#include <applicat.h>
#include <relation.h>
#include <form.h>
#include <mask.h>
#include <printer.h>
#include <config.h>
#include <urldefid.h>
#include <tabutil.h>

#include <nditte.h>
#include "ve3100.h"

#define KILL(x) { ((TEditable_field &)mask->field(x)).reset_key(1); mask->disable(x); }
#define REVIVE(x) { ((TEditable_field &)mask->field(x)).set_key(1); mask->enable(x); }

class TForm_sconti : public TForm
{
protected:
  virtual word set_header(word p, bool u);
public:
  void compact(const bool what); // Compatta i campi disabilitati del corpo, in modo che non ci siano buchi...
  TForm_sconti(const char* form);
  virtual ~TForm_sconti() {};
};
word TForm_sconti::set_header(word p, bool u)
{
  TPrinter& pr = printer();
  TForm_item& pagina = find_field('H',odd_page,3);
  TString16 pg; pg << (int)pr.getcurrentpage();
  pagina.set(pg);
  return TForm::set_header(p,u);
}

void TForm_sconti::compact(const bool what)
// Scorre i campi del corpo, compattando i campi abilitati
{
  word togli;
  if (what) // sconti di riga
    togli = 4;
  else // sconti incondizionati
    togli = 5;
  TPrint_section& b = section('B',odd_page);
  const word fields = b.fields();
  const word height = b.height();
  const word max = fields - togli;
  int y = 1; // first coordinate of first field
  for (word i = 1; i <= fields; i++)
  {
     TForm_item& f = b.find_field(i);
     if (f.enabled())
       if (i <= max)
         f.y() = y++;
       else
         f.y() = y;
  }
  b.set_height(y+1);
}

TForm_sconti::TForm_sconti(const char* form) 
 : TForm(form)
{}

/*                                                                                                 1         1         1         1
         1         2         3         4         5         6         7         8         9         0         1         2         3
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
D:
CC DESCR                                              SCONTO
.. .................................................. .........................

R:
CC CODART               UM SCONTO
.. .................... .. .........................
Categoria vendite: ..................................................
Articolo:          ..................................................
Unità di misura:   ..................................................

I:
CC SC ZN CPG  SCONTO
.. .. .. .... .........................
Categoria vendite:       ..................................................
Sconto cliente:          ..................................................
Zona:                    ..................................................
Condizione di pagamento: ..................................................
*/

class TStampa_sconti: public TApplication {
  TForm_sconti *_frm; // form di stampa
  TLocalisamfile *_anamag,*_scon; // file per i controlli sulle anagrafiche
  TTable *_cve, *_zon, *_cpg;  // Tabella categorie di vendita
  TString16 _sconti; // tipo di archivio
  bool _catven; // abilitazione della categoria di vendita (gesliscv)
  bool _scokey_catven; // abilitazione della categoria di vendita
  bool _scokey_scclienti; // abilitazione degli sconti clienti
  bool _scokey_zone; // abilitazione delle zone
  bool _scokey_condpag; // abilitazione delle condizioni di pagamento
protected:
  virtual bool create(void);
  virtual bool destroy(void);
  virtual bool menu(MENU_TAG m);  
public:
  TStampa_sconti() {};
  virtual ~TStampa_sconti() {}
};

bool TStampa_sconti::create()
{
  bool gotcha= FALSE; // booleano di avvenuta inizializzazione
  _sconti= "*"; // inizializzazione dell'indicatore del tipo di tabella
  if (argc()>2) _sconti= argv(2); // se c'è, prende il tipo di tabella dalla linea di comando
  else
  {
    TMask choose("VE3100"); // istanzia la maschera di scelta del tipo di tabella
    if (choose.run() == K_ENTER) _sconti= choose.get(F_TIPOSC); // prende il tipo di tabella dalla maschera
  }
  switch (_sconti[0])
  {
    case 'D': // sconti documento
      _frm = new TForm_sconti("scontid");
      gotcha= TRUE;
      break;
    case 'R': // sconti di riga
      _frm = new TForm_sconti("scontir");
      gotcha= TRUE;
      break;
    case 'I': // sconti incondizionati
        _frm = new TForm_sconti("scontii");
        gotcha= TRUE;
      break;
    default: // messaggio di errore se si indica una tabella non valida
      error_box("Indicare la tabella sulla linea di comando (D, R o I) oppure selezionarla dalla maschera di partenza");
      break;
  }
  _anamag = new TLocalisamfile(LF_ANAMAG);
  _scon = new TLocalisamfile(LF_SCONTI);
  _cve = new TTable("CVE");
  _zon = new TTable("%ZON");
  _cpg = new TTable("%CPG");
  dispatch_e_menu(BAR_ITEM(1));
  return (gotcha);
}

bool TStampa_sconti::destroy()
{
  if (_frm) delete _frm;
  if (_anamag) delete _anamag;
  if (_scon) delete _scon;
  if (_cve) delete _cve;
  if (_cpg) delete _cpg;
  if (_zon) delete _zon;
  return TRUE;
}

bool TStampa_sconti::menu(MENU_TAG)
{
  bool gotcha= FALSE;
  TConfig prassid(CONFIG_DITTA, "ve");
  TMask *mask;
  switch (_sconti[0])
  {
    case 'D': // sconti documento
      mask= new TMask("ve3100d");
      gotcha= TRUE;
      break;
    case 'R': // sconti di riga
      mask= new TMask("ve3100r");
      _catven = prassid.get_bool("GESSCORIGACV");
      if (!_catven)
      {
        KILL(F_R_CODCAT_DA);
        KILL(F_R_CODCAT_A);
        _frm->find_field('B',odd_page,1).disable();
      }
      else
      {
        REVIVE(F_R_CODCAT_DA);
        REVIVE(F_R_CODCAT_A);
        _frm->find_field('B',odd_page,1).enable();
      }
      _frm->compact(TRUE);
      gotcha= TRUE;
      break;
    case 'I': // sconti incondizionati
      mask= new TMask("ve3100i");
      short k_id[2][4]= { F_I_CATVEN_DA, F_I_CATVEN_A, F_I_SCCLIENTI_DA, F_I_SCCLIENTI_A, F_I_ZONE_DA, F_I_ZONE_A, F_I_CONDPAG_DA, F_I_CONDPAG_A }; // vettore dei campi da controllare
      for (int i=0; i<4; i++)
      {
        bool enab= prassid.get_bool("SCOKEY", NULL, i+1);
        switch (i)
        {
          case 0: _scokey_catven= enab; break;
          case 1: _scokey_scclienti= enab; break;
          case 2: _scokey_zone= enab; break;
          case 3: _scokey_condpag= enab; break;
          default: break;
        }
        if (enab)
        { // se nel file di config. il campo è abilitato...
          REVIVE(k_id[0][i]); // ...i campi vengono abilitati anche sulla maschera
          REVIVE(k_id[1][i]);
          _frm->find_field('B',odd_page,i+1).enable();
          gotcha= TRUE;
        }
        else
        {
          KILL(k_id[0][i]); // se nel file di config. i campi non sono abilitati vengono disabilitati anche sulla maschera
          KILL(k_id[1][i]);
          _frm->find_field('B',odd_page,i+1).disable();
        }
      }
      if (!gotcha) error_box("Non ci sono campi chiave abilitati nella configurazione della ditta");
      else
        _frm->compact(FALSE);
      break;
  }
  CHECK(_frm,"Form pointer is NULL");
  // Setta ora e per sempre alcuni campi della testata
  TForm_item& ditta = _frm->find_field('H',odd_page,1);// Nome ditta
  TForm_item& data  = _frm->find_field('H',odd_page,2);// Data stampa
  TDate td(TODAY);
  TLocalisamfile ditte(LF_NDITTE);
  ditte.put(NDT_CODDITTA,get_firm());
  if (ditte.read()==NOERR) ditta.set(ditte.get(NDT_RAGSOC)); 
  data.set(td.string());
  while (gotcha && (mask->run()== K_ENTER))
  { // lancia la maschera, se viene confermata vengono trovati gli estremi del cursore
    TRectype da(_frm->relation()->lfile().curr()); // prepara il record di inizio regione
    da.zero();
    da.put("TIPO", _sconti);
    TRectype a(da); // prepara il record di fine regione
    
    if (_sconti=="R")
    {
      TString cod_art_to = mask->get(F_R_CODCAT_A);
      TString cod_art_from = mask->get(F_R_CODCAT_DA);
      if (!_catven)
      {
        _anamag->last();
        cod_art_to = _anamag->get("CODART");
      }
      da.put("CODART", cod_art_from);
      a.put("CODART", cod_art_to);
    }
    else 
      if (_sconti=="I")
      {
        TString cod_cat_from = mask->get(F_I_CATVEN_DA);
        TString cod_cat_to = mask->get(F_I_CATVEN_A);
        TString codart,sc_cl,zon,cpg;
        da.put("CODCAT",cod_cat_from);
        if (cod_cat_to.empty())
        {
          _cve->last();
          cod_cat_to = _cve->get("CODTAB");
        }
        a.put("CODCAT",cod_cat_to);
        if (_scokey_scclienti || _scokey_zone || _scokey_condpag)
        {
          if (_scokey_scclienti)
            sc_cl = mask->get(F_I_SCCLIENTI_DA);
          if (_scokey_zone)
            sc_cl = mask->get(F_I_ZONE_DA);
          if (_scokey_condpag)
            sc_cl = mask->get(F_I_CONDPAG_DA);
          codart.format("%2s%2s%4s", (const char*)sc_cl, (const char*)zon,(const char*)cpg);
          da.put("CODART", codart); 
          if (_scokey_scclienti && mask->get(F_I_SCCLIENTI_A).empty())
          {
            _scon->put("TIPO","E");                    
            if (_scon->read(_isgteq)==NOERR)
            {
             if (_scon->prev() == NOERR && _scon->get("TIPO") == "D")
               sc_cl = _scon->get("CODCAT"); //ultimo sconto documento
            }
          }
          if (_scokey_zone && mask->get(F_I_ZONE_A).empty())
          {
            _zon->last();
            zon = _zon->get("CODTAB");
          } else zon = mask->get(F_I_ZONE_A);
          if (_scokey_condpag && mask->get(F_I_CONDPAG_A).empty())
          {
            _cpg->last();
            cpg = _cpg->get("CODTAB");
          } else cpg = mask->get(F_I_CONDPAG_A);
          codart.format("%2s%2s%4s", (const char*)sc_cl, (const char*)zon,(const char*)cpg);
          a.put("CODART", codart);
        }
      }
      else
        if (_sconti=="D")
        {
          da.put("CODCAT", mask->get(F_D_CODCAT_DA));
          a.put("CODCAT", mask->get(F_D_CODCAT_A));
        }
    _frm->cursor()->setregion(da,a);
    _frm->print();
  }
  return FALSE;
}

int ve3100(int argc, char **argv)
{
  TStampa_sconti a;
  
  a.run(argc, argv, "Stampa sconti");
  return 0;
}
