// generic - relapp generica adattata per il 770 
//
//  - Applicazioni -
//
//    Anagrafica dipendenti, 
//    Prospetto quadro E1, 
//    Societa' trasformate
//
//  Riempie automaticamente i campi della maschera con id uguali a CODDITTA77 e ANNODIC77
//  con la ditta  e l'anno dichiarazione correnti del 770
//
// Lista modifiche
//
// 10.5.96	Via il flag erede si fa il controllo su CODDIPDEC
//
 
#include <msksheet.h>
#include <relapp.h>
#include <urldefid.h>
#include <tabutil.h>
#include <config.h>
#include <progind.h>
#include "dipend.h"    
#include <nditte.h>
#include "77lib.h"   
#include "pe1.h"  
#include "anadip.h"  
#include "771100.h" 
#include "771200.h"
#include "774200.h"

#define CODDITTA77	181
#define	ANNODIC77	182

HIDDEN const char* QUALIFICA_EREDE = "11";

void socbbis_setta_ditta(TMask& m);
long ADCalcolaItems(const int lffile, const long codditta, const long coddip);

class TGenericRel_application : public TRelation_application
{
  private:                                   
    static bool codditta77_handler  (TMask_field& m, KEY k);
    static bool check_handler       (TMask_field& m, KEY k);
    static bool PE1calcrit_handler     (TMask_field& m, KEY k);
    static bool ADabilita_coddipdec (TMask_field& m, KEY k);
    static bool ADCodDipDec (TMask_field& m, KEY k);
    void ADCancellaQuadri(const long codditta,const long coddip);
//    static bool eredi_handler       (TMask_field& m, KEY k);
    static bool date_handler        (TMask_field& m, KEY k);
    long			_codditta;
    long			_lCodDipDec;
    long			_lCodDip;
    TString16		_sQualificaPrec;  // qualifica prima di andare in edit
    const char*   _maskname;
    int           _num;
    TString16     _quadro;
    TRiporti      _rip;
    TRelation*    _rel;
    TMask*        _msk;
    bool          _alterna_field,_registra;
    int			_anno_dic;
    bool			_MaskConAnnoDic, _MaskConCodditta;
    bool			MaskConAnnoDic() const;
    bool			MaskConCodditta() const { return _MaskConCodditta; }
    void 			LeggiMask();
    bool		Dipendenti() const { return _num == LF_DIPEND; }
  protected:
    virtual bool user_create();
    virtual bool user_destroy();                  
    virtual int  rewrite(const TMask& m);
    virtual int  write  (const TMask& m);  
    virtual bool remove();                     
    virtual void on_config_change();
    virtual TMask* get_mask(int) { return _msk; }
    virtual bool changing_mask(int) { return FALSE;}
    virtual TRelation* get_relation() const { return _rel; }  
    virtual void init_insert_mode(TMask&);
    virtual void init_modify_mode(TMask&);    
    virtual void init_query_mode(TMask&);
    virtual void init_query_insert_mode(TMask&);
    void 			init_mask(TMask&);
    
  public:                                                                     
    bool			_ADCheckFallito;
    TGenericRel_application(const char* name, const int num, const char* quadro);
};

TGenericRel_application& app() { return (TGenericRel_application&)main_app(); }

TGenericRel_application::TGenericRel_application(const char* name, const int num, const char* quadro)
: _maskname(name), _num(num),
  _MaskConCodditta(FALSE), _MaskConAnnoDic(FALSE),
  _msk(NULL), _rel(NULL), _quadro(quadro), _ADCheckFallito(FALSE)
{
}

void TGenericRel_application::LeggiMask()
{
  _MaskConAnnoDic  = _msk->id2pos(ANNODIC77) > 0;
  _MaskConCodditta = _msk->id2pos(CODDITTA77) > 0;
}                  

bool TGenericRel_application::MaskConAnnoDic() const
{
  return  _MaskConAnnoDic;
}

void TGenericRel_application::on_config_change()
{
  if (MaskConAnnoDic())
  {
    TConfig conf(CONFIG_STUDIO);
    _anno_dic = (int)conf.get_long(ANNO_SEL, NULL, -1, TDate(TODAY).year());
  }
}
                                    
bool TGenericRel_application::user_create()
{           
  _alterna_field = FALSE;
  _msk = new TMask(_maskname);
  _rel = new TRelation(_num);

// Determina se la maschera contiene i campi CODDITTA e ANNODIC
  LeggiMask();

  if (MaskConCodditta())    
    _msk->set_handler(CODDITTA77, codditta77_handler);  

  if (_num == LF_PROSPE1)
  {
    _msk->set_handler(PE1F_CODCAUS,  check_handler);
    _msk->set_handler(PE1F_CODCAUS2, check_handler);
    _msk->set_handler(PE1F_IMPONIBILE, PE1calcrit_handler);
  }                                            

  if (Dipendenti())
  { 
    _msk->set_handler(F_DIP_QUALIFICA,  ADabilita_coddipdec);
    _msk->set_handler(ADF_CODDIPDEC,    ADCodDipDec);
    set_search_field(ADF_DIP_CODDIP);
  }  

  if (_num == LF_SOCTRASF)
  {
    char tipo;

    _msk->set_handler(F_SOC_DATAFINPI, date_handler);    
    
    long codditta = get_firm_770();
    
    TLocalisamfile ditta (LF_NDITTE); 
    
    ditta.setkey(1);
    ditta.zero();
    ditta.put(NDT_CODDITTA, codditta);
    if (ditta.read() == NOERR)
      tipo = ditta.get_char(NDT_TIPOA);
      
    if (tipo == 'F')
    {
      _msk->show(-1);
      _msk->hide(-2);
    }                
    else
      if (tipo == 'G')
      {
        _msk->show(-2);
        _msk->hide(-1);
      }
  }
  
  if (_num == LF_BASEBIS)
    _msk->set_handler(F_BSE_DATAFINPI, date_handler);

  for (int i = 0; i < _msk->fields(); i++)
  {
    TMask_field& campo = _msk->fld(i);
    
    if (campo.in_group(8) || campo.in_group(9))
    {
      _alterna_field = TRUE;
      break;
    }
  }                                  
  _registra = FALSE;
  return TRUE;
}

bool TGenericRel_application::user_destroy()
{  
  if (_quadro != "" && _quadro != "0")
    if (_registra)
      _rip.set(_quadro);
  delete _msk;
  delete _rel;
  return TRUE;
}                         

int TGenericRel_application::rewrite(const TMask& m)
{
  m.autosave(_rel);
  const int err = _rel->rewrite();
  _registra = TRUE;
  return err;
}

int TGenericRel_application::write(const TMask& m)
{
  m.autosave(_rel);
  const int err = _rel->write();
  _registra = TRUE;
  return err;
}

// Costruisce un cursore solo per sapere gli items per la progind
long ADCalcolaItems(const int lffile, const long codditta, const long coddip)
{
  long items=0L;
  TRelation* rel = new TRelation(lffile); 
  TString filtro;
  filtro.format("CODDITTA=%ld && CODDIP=%ld", codditta,coddip);
  TCursor*   cur = new TCursor(rel,filtro,1);                  
  (*cur) = 0L;
  items = cur->items();
  delete cur;
  delete rel;
  return items;
}

void TGenericRel_application::ADCancellaQuadri(const long codditta,const long coddip)
{      
  bool bRimossoA,bRimossoA1,bRimossoA2,bRimossoA3,bRimossoB,bRimossoB1;
  bRimossoA=bRimossoA1=bRimossoA2=bRimossoA3=bRimossoB=bRimossoB1=FALSE;  

  long items = ADCalcolaItems(LF_QUAA, codditta, coddip);
  TProgind progA(items,"Cancellazione quadro A", FALSE,TRUE);
// Cancella quadro A
  TLocalisamfile qa(LF_QUAA);    
  qa.zero();
  qa.put("CODDITTA", (long) codditta);
  qa.put("CODDIP",   (long) coddip);
  TRectype dep(qa.curr());
  for (qa.read(_isgteq, _lock); !qa.eof(); qa.next(_lock))
  {                     
    progA.addstatus(1);
    if (qa.curr() > dep)
    {
      qa.reread(_unlock);
      break;
    }
    const long lDit = qa.get_long("CODDITTA");
    const long lDip = qa.get_long("CODDIP");
    if (lDit == codditta && lDip == coddip)
    {
      bRimossoA = TRUE;
      qa.remove();
    }
  }

// Cancella quadro A1
  items = ADCalcolaItems(LF_QUAA1, codditta, coddip);
  TProgind progA1(items,"Cancellazione quadro A-1", FALSE,TRUE);
  TLocalisamfile qa1(LF_QUAA1);
  qa1.zero();
  qa1.put("CODDITTA", (long) codditta);
  qa1.put("CODDIP",   (long) coddip);
  TRectype dep1(qa1.curr());
  for (qa1.read(_isgteq, _lock); !qa1.eof(); qa1.next(_lock))
  {                         
    progA1.addstatus(1);  
    if (qa1.curr() > dep1)
    {
      qa1.reread(_unlock);
      break;
    }
    const long lDit = qa1.get_long("CODDITTA");
    const long lDip = qa1.get_long("CODDIP");
    if (lDit == codditta && lDip == coddip)
    {
      bRimossoA1 = TRUE;
      qa1.remove();     
    } 
  }    
  
// Cancella quadro A2
  items = ADCalcolaItems(LF_QUAA2, codditta, coddip);
  TProgind progA2(items,"Cancellazione quadro A-2", FALSE,TRUE);
  TLocalisamfile qa2(LF_QUAA2);  
  qa2.zero();
  qa2.put("CODDITTA", (long) codditta);
  qa2.put("CODDIP",   (long) coddip);
  TRectype dep2(qa2.curr());
  for (qa2.read(_isgteq, _lock); !qa2.eof(); qa2.next(_lock))
  {
    progA2.addstatus(1);    
    if (qa2.curr() > dep2)
    {
      qa2.reread(_unlock);
      break;
    }                    
    const long lDit = qa2.get_long("CODDITTA");
    const long lDip = qa2.get_long("CODDIP");
    if (lDit == codditta && lDip == coddip)
    {
      bRimossoA2 = TRUE;
      qa2.remove();     
    }
  }    
  
// Cancella quadro A3  
  items = ADCalcolaItems(LF_QUAA3, codditta, coddip);
  TProgind progA3(items,"Cancellazione quadro A-3", FALSE,TRUE);
  TLocalisamfile qa3(LF_QUAA3);  
  qa3.zero();
  qa3.put("CODDITTA", (long) codditta);
  qa3.put("NPROG",    1);
  qa3.put("CODDIP",   (long) coddip);
  TRectype dep3(qa3.curr());
  for (qa3.read(_isgteq, _lock); !qa3.eof(); qa3.next(_lock))
  {     
    progA3.addstatus(1);    
    const long lDit = qa3.get_long("CODDITTA");
    const long lDip = qa3.get_long("CODDIP");
    if (lDit != codditta || lDip != coddip)
    {
      qa3.reread(_unlock);
      continue;
    }                    
    if (lDit == codditta && lDip == coddip)
    {
      bRimossoA3 = TRUE;
      qa3.remove();     
    }
  }    
  
// Cancella quadro B
  items = ADCalcolaItems(LF_QUAB, codditta, coddip);
  TProgind progB(items,"Cancellazione quadro B", FALSE,TRUE);
  TLocalisamfile qb(LF_QUAB);  
  qb.zero();
  qb.put("CODDITTA", (long) codditta);
  qb.put("CODDIP",   (long) coddip);
  TRectype dep4(qb.curr());
  for (qb.read(_isgteq, _lock); !qb.eof(); qb.next(_lock))
  {
    progB.addstatus(1);    
    if (qb.curr() > dep4)
    {
      qb.reread(_unlock);
      break;
    }                    
    const long lDit = qb.get_long("CODDITTA");
    const long lDip = qb.get_long("CODDIP");
    if (lDit == codditta && lDip == coddip)
    {
      bRimossoB = TRUE;
      qb.remove();
    }
  }                    
  
// Cancella quadro B1  
  items = ADCalcolaItems(LF_QUAB1, codditta, coddip);
  TProgind progB1(items,"Cancellazione quadro B-1", FALSE,TRUE);
  TLocalisamfile qb1(LF_QUAB1);  
  qb1.zero();
  qb1.put("CODDITTA", (long) codditta);
  qb1.put("CODDIP",   (long) coddip);
  TRectype dep5(qb1.curr());
  for (qb1.read(_isgteq, _lock); !qb1.eof(); qb1.next(_lock))
  {
    progB1.addstatus(1);    
    if (qb1.curr() > dep5)
    {
      qb1.reread(_unlock);
      break;
    }                   
    const long lDit = qb1.get_long("CODDITTA");
    const long lDip = qb1.get_long("CODDIP");
    if (lDit == codditta && lDip == coddip)
    {
      bRimossoB1 = TRUE;
      qb1.remove();     
    }
  }  
  
  if (bRimossoA)
    _rip.set("A");
  if (bRimossoA1)
    _rip.set("A1");
  if (bRimossoA2)
    _rip.set("A2");
  if (bRimossoA3)
    _rip.set("A3");
  if (bRimossoB)
    _rip.set("B");
  if (bRimossoB1)
    _rip.set("B1");
}

bool TGenericRel_application::remove()
{
  _registra = TRUE;                 

  if (Dipendenti())
  {
    const long codditta      = _codditta;
    const long coddip        = _lCodDip;

// Se era un erede resetta il riferimento al deceduto..  
    if (_sQualificaPrec != "" && _sQualificaPrec == QUALIFICA_EREDE)
    {
      if (_lCodDipDec > 0L)
        if (!riscrivi_erede(codditta, _lCodDipDec, coddip,0L))
          return warning_box("Fallita cancellazione erede");
    }                              

// Se era un deceduto cancella cod.dip.dec. sugli eredi    
    if (is_deceduto(codditta,coddip))
    {
      TLocalisamfile dip (LF_DIPEND);
      TProgind ProgDip(dip.items(),"Cancellazione codice deceduto	..", FALSE,TRUE);
      for (dip.first(); !dip.eof(); dip.next(_lock))
      {
        ProgDip.addstatus(1);
        const long lDipDec = dip.get_long(DIP_CODDIPDEC);
        if (lDipDec == coddip)
        {
          dip.put(DIP_CODDIPDEC, 0L);
          dip.rewrite();
        }               
        else
          dip.reread(_unlock);
      }
    }
    
// Cancella tutti i quadri che facevano riferimento a questo dip.
    ADCancellaQuadri(codditta,coddip);        
  }
  return TRelation_application::remove();
}

void socbbis_setta_ditta(TMask& m)
{
  TString16 codditta; codditta << get_firm_770();
  if (codditta != "0")        
  {
    m.set(CODDITTA77, codditta);
    m.field(CODDITTA77).check();
  }
}  

void TGenericRel_application::init_mask(TMask& m)
{
  if (MaskConAnnoDic())
    _msk->set(ANNODIC77, _anno_dic); 
}

void TGenericRel_application::init_modify_mode(TMask& m)
{
  init_mask(m);
  if (Dipendenti())
  {                              
    _lCodDip        = m.get_long(ADF_DIP_CODDIP);
    _lCodDipDec     = m.get_long(ADF_CODDIPDEC);
    _sQualificaPrec = m.get(F_DIP_QUALIFICA);
  }
}

void TGenericRel_application::init_insert_mode(TMask& m)
{
  init_mask(m);
}

void TGenericRel_application::init_query_mode(TMask& m)
{                   
  if (Dipendenti())
  {
    _lCodDipDec     = 0L;
    _sQualificaPrec = "";
  }
  
  if (_num == LF_SOCTRASF || _num == LF_BASEBIS) 
  {
    socbbis_setta_ditta(m);
    m.send_key(K_AUTO_ENTER,0);
  }

  if (_num == LF_PROSPE1)
  {    
    m.send_key(K_SHIFT+K_CTRL+'h', -9);  // Nasconde ricerca su prospe1
    m.send_key(K_SHIFT+K_CTRL+'s', -8);  // Show ricerca su ca7
  }
}

void TGenericRel_application::init_query_insert_mode(TMask& m)
{
  if (Dipendenti())
    _ADCheckFallito = FALSE;

  if (_num == LF_PROSPE1)
  {    
    m.send_key(K_SHIFT+K_CTRL+'h', -8);  // Nasconde ricerca su ca7
    m.send_key(K_SHIFT+K_CTRL+'s', -9);  // Show ricerca su prospe1
  }
}

bool TGenericRel_application::codditta77_handler(TMask_field& f, KEY k)
{
  app()._codditta = get_firm_770();
  TString16 codditta; codditta << app()._codditta;         
  TMask& m = f.mask();
  if (codditta != "0")        
  {
    m.set(CODDITTA77, codditta);
    m.field(CODDITTA77).check();
  }
  return TRUE;
}

// Handler dell'imponibile   
// Ricalcola ritenuta se:
// 1. cambia imponibile
// 2. la ritenuta e' ZERO
bool TGenericRel_application::PE1calcrit_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB)
  {
    TMask& m = f.mask();
// Leggi i dati..
    const double perc = atof(m.get(PE1F_HPERC));
    const real impo(f.get());
    const real rope_prec(m.get(PE1F_RITENUTA));

// Ricalcola sempre se e' cambiato  
    const bool forza = f.focusdirty();
    
    if (rope_prec != ZERO && !forza)
      return FALSE;
      
    const real rite_calc = (impo * perc) / 100;
    m.set(PE1F_RITENUTA, rite_calc.string());    
  }
  return TRUE;
}

bool TGenericRel_application::check_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB && f.to_check(k) && f.mask().is_running())
  { 
    TTable ca7 ("%CA7");
    
    TString codice = f.get();
    
    ca7.zero();
    ca7.put("CODTAB", codice);
    if (ca7.read() == NOERR)
    {
      int     artbil = ca7.get_int("I3");
      bool    imp    = ca7.get_bool("B0");
      TString codqua = ca7.get     ("S1");
      
      if (artbil == 1015 || codqua != "E1" || imp)
        return f.warning_box("Codice causale non valido per Quadro E1");
    }
    else
      return f.warning_box("Valore non presente in tabella causali");
  }                                        

  return TRUE;  
}                       

// A.Dip. se qualifica=11 (erede) abilita cod.dip.dec.
bool TGenericRel_application::ADabilita_coddipdec(TMask_field& f, KEY k)
{               
  if (k == K_TAB)
  {
    TMask& m = f.mask();
    TString qual(f.get());
    if (qual == QUALIFICA_EREDE)
      m.enable(ADF_CODDIPDEC);
    else                
    {
// Se prima era un erede e ora non lo e' piu' aggiorna il deceduto (brr..)      
      if (app()._sQualificaPrec != "" && 
          app()._sQualificaPrec == QUALIFICA_EREDE)
      {
        const long codditta = app()._codditta;
        const long coddip = m.get_long(ADF_DIP_CODDIP);
        const long lDecedutoPrec = m.get_long(ADF_CODDIPDEC);
        if (lDecedutoPrec > 0L)
          if (!riscrivi_erede(codditta, lDecedutoPrec,coddip,0L))
            return warning_box("Fallita cancellazione erede");
      }
      m.reset(ADF_CODDIPDEC);
      m.disable(ADF_CODDIPDEC);                                       
    }
  }
  return TRUE;
}

const char* FALLITO_EREDE_MSG = "Impossibile inserire un nuovo erede. Il numero massimo di eredi e' 10";

bool TGenericRel_application::ADCodDipDec(TMask_field& f, KEY k)
{
  if (k == K_ENTER)
  {
    TMask& m = f.mask();
    TString sCodDec(f.get());
    long lDecedutoCorrente = 0L;
    const long codditta = app()._codditta;
    const long coddip = m.get_long(ADF_DIP_CODDIP);
        
    if (sCodDec.not_empty())
    {
      lDecedutoCorrente = atol((const char*)sCodDec);
      if (!esiste_dipendente(codditta,lDecedutoCorrente))
        return warning_box("Dipendente inesistente");
    }        
    const long lDecedutoOriginario = app()._lCodDipDec;
    const bool bCambiatoDeceduto = //(lDecedutoCorrente != 0L) && 
                                   (lDecedutoOriginario != 0L) &&
                                   (lDecedutoCorrente != lDecedutoOriginario);
    if (bCambiatoDeceduto)
    {
// Cancella l'erede nel rec.del dec. precedente    
      if (!riscrivi_erede(codditta, lDecedutoOriginario,coddip,0L))
        return warning_box("Impossibile cancellare il codice erede nella scheda del dipendente deceduto");
// Scrive l'erede nel rec.del dec. attuale
      if (lDecedutoCorrente != 0L)
        if (!scrivi_erede(codditta, lDecedutoCorrente, coddip))
          return warning_box(FALLITO_EREDE_MSG);
    }
    else
      if (lDecedutoCorrente != 0L)
      {
        if (!scrivi_erede(codditta, lDecedutoCorrente, coddip))
          return warning_box(FALLITO_EREDE_MSG);
        app()._lCodDipDec = lDecedutoCorrente;
      }
  }
  return TRUE;
}

/*
bool TGenericRel_application::eredi_handler(TMask_field& f, KEY k)
{               
  if (k == K_TAB || k == K_SPACE) 
  {               
    TString depdec(f.get());
    bool erede  = depdec.not_empty();
    
    if (erede)
    {
      f.mask().disable(F_DIP_CODEREDE0);
      f.mask().disable(F_DIP_CODEREDE1);
      f.mask().disable(F_DIP_CODEREDE2);
      f.mask().disable(F_DIP_CODEREDE3);
      f.mask().disable(F_DIP_CODEREDE4);
      f.mask().disable(F_DIP_CODEREDE5);
      f.mask().disable(F_DIP_CODEREDE6);      
      f.mask().disable(F_DIP_CODEREDE7);
      f.mask().disable(F_DIP_CODEREDE8);
      f.mask().disable(F_DIP_CODEREDE9);                                                
    }
    else
    {
      f.mask().enable(F_DIP_CODEREDE0);
      f.mask().enable(F_DIP_CODEREDE1);
      f.mask().enable(F_DIP_CODEREDE2);              
      f.mask().enable(F_DIP_CODEREDE3);
      f.mask().enable(F_DIP_CODEREDE4);
      f.mask().enable(F_DIP_CODEREDE5);
      f.mask().enable(F_DIP_CODEREDE6);
      f.mask().enable(F_DIP_CODEREDE7);
      f.mask().enable(F_DIP_CODEREDE8);
      f.mask().enable(F_DIP_CODEREDE9);                                          
    }
  }
  return TRUE;  
} 
*/

bool TGenericRel_application::date_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB)
  {                     
    TDate datainpi;
    
    TMask& m = f.mask();
    
    TFilename name = m.source_file();
    
    if (name == "771200i.msk")
      datainpi = m.get_date(F_BSE_DATAINPI);  
    if (name == "771100h.msk")          
      datainpi = m.get_date(F_SOC_DATAINPI);  
    
    TDate datafinpi (f.get());

    if (datafinpi < datainpi)
      return f.error_box("La data finale non puo' essere inferiore alla data iniziale");
  }
  return TRUE;
}

class TGeneric_application : public TApplication
{
  TFilename _maskname;
  
protected:
  bool create() { dispatch_e_menu(BAR_ITEM(1)); return TRUE; }
  bool destroy() { return TRUE; }
  bool menu(MENU_TAG);

//  static bool codditta77_handler(TMask_field& m, KEY k);
  
public:
  TGeneric_application(const char* name) : _maskname(name) {}
};


bool TGeneric_application::menu(MENU_TAG)
{ 
  KEY k;
  if (_maskname.empty())
  {
    TMask m("Inserire il nome della maschera", 1, 42, 4);
    m.add_string(101, 0, "", 1, 1, 40);
    m.efield(101).check_type(CHECK_REQUIRED);
    m.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
    m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
    k = m.run();
    if (k == K_ENTER)
      _maskname = m.get(101);
    else
      return FALSE;  
  } 

  TMask m(_maskname);
  
//  if (m.id2pos(F_CODDITTA) > 0)
//    m.set_handler(F_CODDITTA, codditta77_handler);
      
  k = m.run();
  if (k == K_QUIT) stop_run();

  return k != K_QUIT;
}

///////////////////////////////////////////////////////////
// 2 modi :
//  RUN,773,-1,771230m,89,"Prospetto del Quadro E1","E1"    [771230i.uml]
// oppure
//  773 -1 menu_st "Stampe dichiarazioni" [prassi.mnu]
///////////////////////////////////////////////////////////
int generic(int argc, char* argv[])
{
//  TApplication::check_parameters(argc, argv);
  TFilename mask;
  int num = 0;
  if (argc > 1) 
    mask = argv[2];

  if (argc < 6)
  {
    const char* title  = argv[3];              
    TGeneric_application a(mask);
    a.run(argc, argv, title);
  }
  else
  {
    num    = atoi(argv[3]);
    const char* title  = argv[4];             
    const char* quadro = argv[5];
    TGenericRel_application a(mask, num, quadro);
    a.run(argc, argv, title ? title : "Test Relation Application");
  }
  return 0;
}

