// --------------------------------------------------------------
// fv:  cg0 -5 <tab>: gestione maschere contabilita'
// --------------------------------------------------------------

#include <tabapp.h>
#include <saldi.h>
#include <defmask.h>
#include <sheet.h>
#include "../ba/batbesc.h"
#include "cglib.h"

class CGTab_application : public Tab_application
{  
  // ------------- specifiche tabella esercizi ----                                            
  TLocalisamfile* _saldi;
  static bool dataini_handler(TMask_field& f, KEY k);
  static bool checkbut_handler(TMask_field& f, KEY k);
  void check_sheet();
  bool check_esercizio(TString& cod, TDate s1, TDate f1);
  // --------------------------------------------

  protected:     

  virtual bool protected_record(TRectype & rec);

  virtual bool user_create();
  virtual bool user_destroy();

  public:
                                             
  static CGTab_application& app() { return (CGTab_application&)main_app(); }                     
                       
  CGTab_application() : Tab_application() {}
  virtual ~CGTab_application() {}
}; 

bool CGTab_application::protected_record(TRectype &rec)
{                           
  if (get_tabname() == "ESC")
  {                                 
     // cerca saldo con questo esercizio
     TString cod(rec.get("CODTAB")); 
     _saldi->zero();
     _saldi->put(SLD_ANNOES, cod);         
     // se ce n'e' uno non si puo' cancellare
     if (_saldi->read(_isgteq) == NOERR && cod == rec.get("CODTAB"))
       return TRUE;
  }  
  return Tab_application::protected_record(rec);
}

bool CGTab_application::user_create()
{             
  Tab_application::user_create();
  
  if (get_tabname() == "ESC")
  {
    _saldi = new TLocalisamfile(LF_SALDI);
    get_mask()->set_handler(F_DATAINI, dataini_handler);
    get_mask()->set_handler(BUT_CHECK, checkbut_handler);
  }
  return TRUE;
}

bool CGTab_application::user_destroy()
{             
  if (get_tabname() == "ESC")
     delete _saldi; 
  return Tab_application::user_destroy();
}


// - esercizi-specific --------------------------------------------------------

bool CGTab_application::dataini_handler(TMask_field& f, KEY k)
{
  if (k == K_ENTER && f.mask().is_running() && !f.mask().query_mode())   
  {                        
    TString16 cod = f.mask().get(F_ANNO);
    TDate s1 = f.mask().get_date(F_DATAINI);
    TDate f1 = f.mask().get_date(F_DATAFIN);
    
    return app().check_esercizio(cod, s1, f1);
  }
  return TRUE;
}

bool CGTab_application::check_esercizio(TString& cod, TDate s1, TDate f1)
{                                                                                            
  // -----------------------------------------------------------------------------------------
  // chiamata prima di registrare. Controlla:
  // - se non ci sono altri esercizi, ok;
  // - se ce ne sono altri:
  //    1) controllo non sovrapposizione date   
  //    2) se ci sono es. con date inferiori, datainizio -1 deve essere = data fine altro es;
  //    3) se ci sono es. con date superiori, datafine +1 deve essere = data inizio altro
  // ---------------------------------------------------------------------------------------- 
  
  byte err = 0x00;  bool ret = TRUE;
  TLocalisamfile& esc = get_relation()->lfile();
  
  bool basta1 = FALSE, basta2 = FALSE;
  
  for (esc.first(); !esc.eof(); esc.next())
  {
    if (esc.get("CODTAB") == cod) 
      continue;                      
                                                          
    TDate s2 = esc.get_date("D0");
    TDate f2 = esc.get_date("D1");
    TDate s1d = s1; --s1d;
    TDate s2d = s2; --s2d;
             
    // check sovrapposizione
    if (s1 <= f2 && s2 <= f1)         
      err |= 0x01;
    else 
    {
      if (!basta1 && f1 < s2 && f1 != s2d)
        err |= 0x02;
      if (f1 < s2 && f1 == s2d)
      {
        err &= ~0x02;
        basta1 = TRUE;
      }
      if (!basta2 && s1 > f2 && f2 != s1d)
        err |= 0x04;
      if (s1 > f2 && f2 == s1d)
      {
        err &= ~0x04;
        basta2 = TRUE;
      }
    }
  }             
  
  if (err) 
  {         
    ret = FALSE;
    TString errstr(120); 
    errstr << "Date esercizio errate: \n";
    // build error string  
    if (err & 0x01)
      errstr << "\n - l'esercizio si sovrappone ad altro gia' esistente";
    if (err & 0x02)
      errstr << "\n - l'esercizio non e' contiguo ad esercizi successivi";
    if (err & 0x04)
      errstr << "\n - l'esercizio non e' contiguo ad esercizi precedenti"; 

    if (!(err & 0x01))      
    {                         
      errstr << "\nSi desidera registrare ugualmente?";
      ret = yesno_box(errstr);  
    }
    else error_box(errstr); 
  }
  return ret;
}


void CGTab_application::check_sheet()
{
  // crea 'nu bellu shit co'tutte le informazion e un messaggino
  // di error se ce n'e' bisogn         
  TLocalisamfile& esc = get_relation()->lfile();  
  TArray escarr(10);
  for (esc.first(); !esc.eof(); esc.next())
    escarr.add(new TEsercizio(esc.curr()));  

  escarr.sort();

  TArray_sheet as(-1,-1,70,20,"Esercizi contabili",
                  "Codice|Inizio@10|Fine@10|Scarico@10|Chiusura@10|Note@20",
                  0x18);
  
  TDate s1;
  
  for (int i = 0; i < escarr.items(); i++)  
  {
    // sovrapposti non possono essere, perche' non si possono
    // registrare; possono solo esserci discontinuita'
    TEsercizio& e = (TEsercizio&)escarr[i];
    TToken_string* tt = new TToken_string(80);
    tt->add(e.codice());
    tt->add(e.inizio().string());
    tt->add(e.fine().string());
    tt->add(e.scarico().string());
    tt->add(e.chiusura().string());

    if (i > 0 && e.inizio() != ++s1)
      tt->add("*** non contiguo ***");
    else tt->add("");

    s1 = e.fine();
         
    as.add(tt);
  } 
  
  as.run();
}

bool CGTab_application::checkbut_handler(TMask_field& f, KEY k)
{
  if (k == K_SPACE && f.mask().is_running()) 
    app().check_sheet();
  return TRUE;
}

// -------------------------------------------------------------

int cg0600(int argc, char* argv[])
{
  CGTab_application a;

  a.run(argc, argv, "Gestione tabelle contabili");
  return 0;
}