#include <config.h>
#include <printer.h>
#include <tabapp.h>
#include <tabutil.h>

#include "batbreg.h" 
#include "batbcam.h" 
#include "batbdel.h"

#define REG_JOURNAL 5

class TGeneric_table_app : public Tab_application
{
  long       _oldditta;
  int        _oldanno;
  bool       _exist_journal;
  bool       _stampa_intest;

protected:  // TRelation_application
  virtual bool user_create() ;                         
  virtual bool protected_record(TRectype& rec) ;
  virtual void init_insert_mode(TMask& m) ;
  virtual void init_modify_mode(TMask& m);
  virtual void init_query_mode (TMask&);
  virtual int rewrite(const TMask& m);

public:
  bool exist_journal() {return _exist_journal;}
  char frequenza_versamenti(long firm, int year) const;
  
  TGeneric_table_app() : _exist_journal(FALSE), _stampa_intest(FALSE) {}
  virtual ~TGeneric_table_app() {}
};

HIDDEN inline TGeneric_table_app& app() { return (TGeneric_table_app&) main_app();}


void TGeneric_table_app::init_insert_mode(TMask& m) 
{
  if (get_tabname() == "REG")
  {
    const long ditta = get_firm();
    const int anno = atoi(m.get(F_ANNO));

    m.set(F_STAMPA_INTESTAZIONE, _stampa_intest ? "X" : "");

    if (ditta != _oldditta || anno != _oldanno)
    {
      _oldditta = ditta;
      _oldanno = anno;

      TTable reg(get_tabname());
      reg.zero();
      reg.put("CODTAB", m.get(F_ANNO));

      TRectype to(reg.curr());
      _exist_journal = FALSE;

      for (reg.read(_isgteq); !_exist_journal && reg.good() && reg.curr() <= to; reg.next())
        _exist_journal = (reg.get_long("I0") == REG_JOURNAL);
    }  
  }  
}

void TGeneric_table_app::init_modify_mode(TMask& m) 
{             
  Tab_application::init_modify_mode(m);
  if (get_tabname() == "REG")
  {                    
    TString16 config;
    config.format("REG%05ld", m.get_long(F_CODDITTA));
    config << m.get(F_CODICE);
    TConfig ini(CONFIG_STAMPE, config);              
    const int what = ini.get_int("Type", NULL, -1, -1);
    m.set(F_CONFIG, what >= 0 ? "X" : "");
    m.enable(F_CONFIG, what >= 0);
  }
}  

void TGeneric_table_app::init_query_mode(TMask& m)
{
  Tab_application::init_query_mode(m);
  if (get_tabname() == "%DEL")
  {
    m.show(F_BANCA1);
    m.show(F_BANCA2);
    m.show(F_CONCESSIONE);
  }
}

bool TGeneric_table_app::protected_record(TRectype& rec) 
{ 
  bool prot = rec.get_bool(FPC);
  if (!prot)
  {
    if (get_tabname() == "%IVD")      // Impedisce la cancellazione di una classe se ha sottoclassi
    {               
      TLocalisamfile& f = get_relation()->lfile();               
      const TRecnotype pos = f.recno();
      const TString16 cod(rec.get("CODTAB"));
      const int err = f.next();
      if (err == NOERR)
      {
        TString16 next(f.get("CODTAB")); next.cut(cod.len());
        prot = cod == next;
      }  
      f.readat(pos);
    }
  }
  return prot;
}

HIDDEN bool tiporeg_handler(TMask_field& f, KEY k)
{
  if ((k == K_TAB || k == K_ENTER) && app().exist_journal() &&
      (atoi(f.get()) == REG_JOURNAL)
      )
    return error_box("Non e' possibile avere due registri giornale nello stesso anno");
  return TRUE;
}

HIDDEN bool printer_handler(TMask_field& f, KEY k)
{        
  if (k == K_SPACE)
  {                  
    TMask& m = f.mask();
    TString16 config;
    config.format("REG%05ld", m.get_long(F_CODDITTA));
    config << m.get(F_CODICE);

    if (config.len() == 11)
    {
      TPrinter& p = printer();
      p.set_printtype(normprinter);           // Force configuration update
      p.read_configuration(config);
      if (p.set())
      {
        m.enable(F_CONFIG);
        m.set(F_CONFIG, "X");
      }  
      p.read_configuration();
    }   
    else 
      return error_box("Nessun registro selezionato"); 
  }
  return TRUE;  
}

char TGeneric_table_app::frequenza_versamenti(long firm, int year) const
{        
  char freq = 'M';
  
  TString16 key; key.format("%05ld%d", firm, year);
  TTable lia("%LIA");
  lia.put("CODTAB", key);
  if (lia.read() != NOERR)
  { 
    TLocalisamfile nditte(LF_NDITTE);
    nditte.put("CODDITTA", firm);
    nditte.read();
    freq = nditte.get_char("FREQVIVA");
  }
  else 
    freq = lia.get_char("S7");
  CHECK(freq == 'M' || freq == 'T', "Frequenza versamenti IVA assurda");
  
  return freq;
}  

HIDDEN bool coddel_handler(TMask_field& f, KEY k)
{
  const TMask& m = f.mask();
  
  if (!m.query_mode() && k == K_TAB)
  {
    const short id = f.dlg();
    long cod;
    if (id == F_BANCA1)
      cod = m.get_long(F_BANCA1);
    if (id == F_CONCESSIONE)
      cod = m.get_long(F_CONCESSIONE);  
    
    if (id == F_BANCA1)
      if (cod != 0)
        f.mask().hide(F_CONCESSIONE);
    
    if (id == F_CONCESSIONE)
      if (cod != 0)
      {
        const long firm = m.get_long(F_DITTA);
        TLocalisamfile nditte(LF_NDITTE);
        nditte.put("CODDITTA", firm);
        if (nditte.read() == NOERR)
        { 
          const char tipoa = nditte.get_char("TIPOA");
          const long codan = nditte.get_long("CODANAGR");
          TLocalisamfile anag(LF_ANAG);
          anag.put("TIPOA", tipoa);
          anag.put("CODANAGR", codan);
          if (anag.read() == NOERR)
          {
            const bool titcf = anag.get_bool("TITCF");
            if (!titcf)
            {
              f.mask().hide(F_CONCESSIONE);
              return error_box("Concessione non ammessa senza conto fiscale");
            }
            f.mask().hide(F_BANCA1);
            f.mask().hide(F_BANCA2);
          }
        }  
      }
  }
  return TRUE;
}

HIDDEN bool intdel_handler(TMask_field& f, KEY k)
{
  const TMask& m = f.mask();
  
  if (!m.query_mode() && k == K_ENTER)
  {                                            
    const long firm = m.get_long(F_DITTA);
    const int anno = m.get_int(F_ANNODEL); 
    const real imp(m.get(F_IMPORTO));
    const real intr(f.get());
    if (!intr.is_zero())
      if (app().frequenza_versamenti(firm, anno) == 'T')
      {
        TConfig cnf(CONFIG_DITTA, "cg");
        bool isintr = cnf.get_bool("InTrTr");
        if (isintr)
          return error_box("Interessi non ammessi: ditta con NO calcolo interessi");
      } 
      else return error_box("Interessi non ammessi: ditta con versamenti mensili");
    
    if (imp < intr)
      return error_box("Incoerenza importo versato e interessi");
    else if (!imp.is_zero() && imp == intr)
      return error_box("Incoerenza importo versato e interessi");
  }
  return TRUE;
}                       

HIDDEN bool impdel_handler(TMask_field& f, KEY k)
{
  const TMask& m = f.mask();
  
  if (!m.query_mode() && k == K_ENTER)
  {                                            
    const int tipo_del = m.get_int(F_TIPODEL); 
    if (tipo_del == 1 || tipo_del == 7)
    { 
      const double lim[3] = { 500.0, 50500.0, 200000.0};
      const int mese_del = m.get_int(F_MESEDEL);
      int t;
      if (tipo_del == 1)
      {
        if (mese_del == 12) t = 0;
        else t = 1;
      }
      else t = 2;
      const real imp(m.get(F_IMPORTO));
      if (imp < lim[t]) 
        return yesno_box("Importo inferiore a Lit. %s. Registrare ugualmente?", real(lim[t]).string("."));
    }
  }
  return TRUE;
}                       

HIDDEN bool mese_handler(TMask_field& f, KEY k)
{
  if (!f.mask().query_mode() && k == K_SPACE)
  {
    TMask& m = f.mask();
    const int vers = m.get_int(F_TIPODEL);
    if (vers == 1)
    {
      const int mese = m.get_int(F_MESEDEL);
      const long firm = m.get_long(F_DITTA);
      const int anno = m.get_int(F_ANNODEL);             
      if (app().frequenza_versamenti(firm, anno) == 'T')
      {
        TLocalisamfile nditte(LF_NDITTE);
        nditte.zero();
        nditte.put("CODDITTA",firm);
        if (nditte.read() == NOERR)
        {
          TString16 attprev = nditte.get("CODATTPREV");
          TLocalisamfile attiv(LF_ATTIV);
          attiv.zero();
          attiv.put("CODDITTA",firm); 
          attiv.put("CODATT",attprev);
          if (attiv.read() != NOERR) attiv.zero();
          bool benzinaio = attiv.get_bool("ART74_4");
          bool gest4 = FALSE;
          if (benzinaio) 
          {
            TConfig cnf(CONFIG_DITTA, "cg");
            gest4 = cnf.get_bool("GesT74");
          } 
          if (benzinaio && gest4)
          {
            if (mese != 3 && mese != 6 && mese != 9 && mese != 12 && mese != 13)       
            {
              TMask* mask = &m;
              mask->reset();
              return error_box("Ditta trimestrale: indicare trimestre");
            } 
          }
          else if (mese != 3 && mese != 6 && mese != 9 && mese != 13)   
          {
            TMask* mask = &m;
            mask->reset();
            return error_box("Ditta trimestrale: indicare trimestre");              
          }
        }
      }
    }   
  } 
  return TRUE;
}

bool TGeneric_table_app::user_create()
{
  Tab_application::user_create();
  const TString& name = get_tabname();
  TMask& mask = *get_mask();
  
  if (name == "REG") 
  {
    mask.set_handler(F_TIPO, tiporeg_handler);
    mask.set_handler(F_PRINTER, printer_handler);
    
    TConfig st(CONFIG_STUDIO, "cg");
    _stampa_intest = st.get_bool("StiReg");
  }
  if (name == "%DEL") 
  {
    mask.set_handler(F_MESEDEL, mese_handler);    
    mask.set_handler(F_IMPORTO, impdel_handler);
    mask.set_handler(F_INTERESSI, intdel_handler);    
    mask.set_handler(F_BANCA1, coddel_handler);    
    mask.set_handler(F_CONCESSIONE, coddel_handler);
  }
  if (name == "CAM")
    set_search_field(FLD_TABCAM_D0);
  
  return TRUE;
}

int TGeneric_table_app::rewrite(const TMask& m)
{
  if (get_tabname() == "REG" && !m.get_bool(F_CONFIG))
  {
    TString16 config;
    config.format("REG%05ld", m.get_long(F_CODDITTA));
    config << m.get(F_CODICE);
    TConfig ini(CONFIG_STAMPE, config);
    const int what = ini.get_int("Type", NULL, -1, -1);
    if (what >= 0)
      ini.set("Type", -1);
  }
  
  return Tab_application::rewrite(m);
}

int ba3100(int argc, char* argv[])
{
  TGeneric_table_app a ;
  a.run(argc, argv, "Tabella");
  return 0;
}
