#include <applicat.h>
#include <date.h>
#include <lffiles.h>
#include <mask.h>
#include <isam.h>
#include <printapp.h>
#include <tabutil.h>
#include <utility.h>
#include <nditte.h>
#include <anagr.h>
#include <comuni.h>
#include "cg0.h"
#include "cg0400.h"


class CG0400_application : public TPrintapp
{
  
  TTable* _tabpim, * _tabreg;
  TLocalisamfile* _nditte, * _attiv, * _anag, * _com;
  TMask* _msk;
  TDate _data;
  int _i, _sospmsk, _tipoprog, _livelloprog, _tipo_crmsk;
  TString _cap,_cofi,_paiva,_ragsoc,_comunefis,_provfis,_viafis,_codivamsk,_codattmsk;
  bool _vuoilordi;
  real _imponibile, _imposta, _lordo, _imponibile_v, _imposta_v, _lordo_v;
  real _imponibile_vs, _imposta_vs, _lordo_vs, _totimponibile_v, _totimposta_v;
  real _totlordo_v, _totimponibile_vs, _totimposta_vs, _totlordo_vs, _imponibile_acq;
  real _imposta_acq, _lordo_acq, _totimponibile_acq, _totimposta_acq, _totlordo_acq;

public:
  bool user_create();
  bool user_destroy();
  bool set_print(int);

  bool menu(MENU_TAG m) { return TPrintapp::menu(m); }

  virtual void preprocess_header();
  virtual bool preprocess_page(int,int);
  virtual print_action postprocess_page(int,int);
  virtual bool preprocess_print(int,int);

  void fai_ricerca(int);
  void get_dati_ditta();
  int  stampa_intestazione_ditta();

public:
  CG0400_application(){};
};


bool CG0400_application::user_create()
{
  _tabpim = new TTable(TAB_PIM);
  _tabreg = new TTable(TAB_REG);
  _anag   = new TLocalisamfile(LF_ANAG);
  _nditte = new TLocalisamfile(LF_NDITTE);
  _attiv  = new TLocalisamfile(LF_ATTIV);
  _com    = new TLocalisamfile(LF_COMUNI);
  _msk    = new TMask("cg0400a");
  return TRUE;
}

bool CG0400_application::user_destroy()
{
  delete _msk;
  delete _tabpim;
  delete _tabreg;
  delete _anag;
  delete _nditte;
  delete _com;
  delete _attiv;        
  return TRUE;
}

void CG0400_application::fai_ricerca(int i)
{
  TString codtab,codreg,dep,codiva,codatt;
  int mese;
  long anno;

  _imponibile=0;
  _imponibile_v=0;
  _imponibile_vs=0;
  _imposta=0;
  _imposta_v=0;
  _imposta_vs=0;
  _lordo=0;
  _lordo_v=0;
  _lordo_vs=0;
  _imponibile_acq=0;
  _imposta_acq=0;
  _lordo_acq=0;

  _tabpim->first();
  while (!_tabpim->eof())   //Scorre tutti i record della tabella PIM
  { 
    _imponibile = 0;
    _imposta    = 0;
    _lordo      = 0;
    codtab = _tabpim->curr().get("CODTAB");
    mese   = atoi(codtab.mid(12,2));
    if (_livelloprog == 1)           //Se si tratta di una aliquota
    {        
      codiva = codtab.mid(15,3);
      codatt = codtab.mid(4,5);
    }
    else                  //altrimenti se si tratta di una attivita'
    {
      codatt = codtab.mid(4,5);
      codiva = codtab.mid(55,3);
    }
    if (((mese==i)&&(codiva==_codivamsk))||((mese==i)&&(codatt==_codattmsk)))  
    {
      codreg = codtab.mid(9,3);
      anno = atoi(codtab.mid(0,4));
      _tabreg->curr().zero();
      dep = format("%04d", anno);
      dep << format("%3s", (const char*)codreg);
      _tabreg->curr().put("CODTAB", (const char*)dep);
      _tabreg->read();
      if (_tabreg->bad())
        _tabreg->curr().zero();
      int tipo = atoi(_tabreg->curr().get("I0"));
      if ((tipo == 1) && (_tipoprog == 1))     //Se si tratta di una vendita
      { 
        int tipo_importo = (int) _tabreg->curr().get_long("I0");
        bool sosp = _tabreg->curr().get_bool("B0");
        if (tipo_importo == 1)         // 1=importo netto  2=importo lordo
        {  
          _imponibile = _tabpim->curr().get_real("R0");
          
          _imposta = _tabpim->curr().get_real("R1");
        }
        else 
          _lordo = _tabpim->curr().get_real("R2");    
        if (sosp)             //Se e' una vendita in sospensione d'imposta
        { 
          _imponibile_vs += _imponibile;
          _imposta_vs += _imposta;
          _lordo_vs += _lordo;
        }
        else
        {
          _imponibile_v += _imponibile;
          _imposta_v += _imposta;
          _lordo_v += _lordo;
        }
      }
      else if ((tipo == 2) && (_tipoprog == 2))  //Se si tratta di un acquisto
      {
        int tipo_importo = atoi(codtab.mid(15,1));
        int tipo_cr = atoi(codtab.mid(14,1));
        if (_tipo_crmsk == tipo_cr)
        {
          if (tipo_importo == 1)     // 1=importo netto  2=importo lordo
          {
            _imponibile = _tabpim->curr().get_real("R0");
            
            _imposta = _tabpim->curr().get_real("R1");
          }
          else
            _lordo = _tabpim->curr().get_real("R2");    
          
          _imponibile_acq += _imponibile;
          _imposta_acq += _imposta;
          _lordo_acq += _lordo;
        }
      }         
    }
    _tabpim->next();
  }

  _totimponibile_v+=_imponibile_v;
  _totimposta_v+=_imposta_v;
  _totlordo_v+=_lordo_v;
  _totimponibile_vs+=_imponibile_vs;
  _totimposta_vs+=_imposta_vs;
  _totlordo_vs+=_lordo_vs;
  _totimponibile_acq+= _imponibile_acq;
  _totimposta_acq+= _imposta_acq;
  _totlordo_acq+= _lordo_acq;
}

bool CG0400_application::set_print(int)
{
  KEY tasto;
  tasto = _msk->run();
  if (tasto == K_ENTER)
  { 
    _sospmsk     = atoi(_msk->get(F_TIPOTAB));
    _vuoilordi   = (bool)(_msk->get(F_VUOILORDI) == "X");
    _tipoprog    = atoi(_msk->get(F_TIPO));
    _livelloprog = atoi(_msk->get(F_LIVELLO));
    if (_livelloprog == 1)           //Se si tratta di una aliquota
    {         
      _codivamsk = _msk->get(F_CODIVA);
      _tipo_crmsk = atoi(_msk->get(F_TIPOTABE));
    }
    else                  //altrimenti se si tratta di una attivita'
    {
      _codattmsk = _msk->get(F_ATTIVITA);
      _tipo_crmsk = atoi(_msk->get(F_TIPOTABEL));
    }
    return TRUE;
  }
  return FALSE;
}


bool CG0400_application::preprocess_print(int file,int counter)
{
  set_real_picture("###.###.###.###");
  set_print_zero();
  _totimponibile_v   = 0;
  _totimposta_v      = 0;
  _totlordo_v        = 0;
  _totimponibile_vs  = 0;
  _totimposta_vs     = 0;
  _totlordo_vs       = 0;
  _totimponibile_acq = 0;
  _totimposta_acq    = 0;
  _totlordo_acq      = 0;

  return TRUE;
}

bool CG0400_application::preprocess_page(int file, int counter)
{
  const char* mese;
  reset_print();

  if (counter)
    _i++;
  else
    _i = 1;
  
  fai_ricerca(_i);
  mese = itom(_i);
  set_row(1,"%s", mese);
  if (_tipoprog == 1)
  {
    if (_sospmsk == 1)
    {
      set_row(1,"@16g%r", &_imponibile_v);
      set_row(1,"@32g%r", &_imposta_v);
      if (_vuoilordi)
        set_row(1,"@48g%r", &_lordo_v);
    }
    else if (_sospmsk == 2)
    {
      set_row(1,"@16g%r", &_imponibile_vs);
      set_row(1,"@32g%r", &_imposta_vs);
      if (_vuoilordi)
        set_row(1,"@48g%r",&_lordo_vs);
    }
  }
  else if (_tipoprog == 2)
  {
    set_row(1,"@16g%r", &_imponibile_acq);
    set_row(1,"@32g%r", &_imposta_acq);
    if (_vuoilordi)
      set_row(1,"@48g%r", &_lordo_acq);
  }

  if (_i == 12)
  {
    TString dep = "";
    set_row(2,(const char*) dep);   
    set_row(3,"@10gTotale");
    if (_tipoprog == 1)
    {
      if (_sospmsk == 1)            
      {
        set_row(3,"@16g%r", &_totimponibile_v);
        set_row(3,"@32g%r", &_totimposta_v);
        if (_vuoilordi)
          set_row(3,"@48g%r", &_totlordo_v);
      }
      else if (_sospmsk == 2)
      {
        set_row(3,"@16g%r", &_totimponibile_vs);
        set_row(3,"@32g%r", &_totimposta_vs);
        if (_vuoilordi)
          set_row(3,"@48g%r", &_totlordo_vs);
      }
    }
    else if (_tipoprog == 2)
    {
      set_row(3,"@16g%r", &_totimponibile_acq);
      set_row(3,"@32g%r", &_totimposta_acq);
      if (_vuoilordi)
        set_row(3,"@48g%r", &_totlordo_acq);
    }
  }
  return TRUE;
}

TRectype& look_com (const char * cod, TLocalisamfile *comuni)
{
  comuni->zero();
  comuni->put(COM_COM, cod);
  comuni->read();
  if (comuni->bad())
    comuni->zero();

  return comuni->curr();
}

void CG0400_application::get_dati_ditta()
{
  TLocalisamfile nditte(LF_NDITTE); 
  TLocalisamfile anag(LF_ANAG); 
  TString        codanagr;
  TString        tipoa;

  nditte.zero();
  nditte.put(NDT_CODDITTA, get_firm());   
  nditte.read();

  if (nditte.bad()) nditte.zero();

  codanagr = nditte.get(NDT_CODANAGR);
  tipoa    = nditte.get(NDT_TIPOA);
  _ragsoc  = nditte.get(NDT_RAGSOC);

  anag.setkey(1);
  anag.zero();
  anag.put (ANA_TIPOA, tipoa);
  anag.put (ANA_CODANAGR, codanagr);
  anag.read();
  if (anag.bad()) anag.zero();
  
  _cofi      = anag.get(ANA_COFI);
  _paiva     = anag.get(ANA_PAIV);
  //_ragsoc    = anag.get(ANA_RAGSOC);
  _comunefis = anag.get(ANA_COMRF);

  if (_comunefis.empty()) 
    _comunefis = anag.get(ANA_COMRES);

  TRectype dep = look_com (_comunefis, _com);

  _comunefis   = dep.get(COM_DENCOM);
  _provfis     = dep.get(COM_PROVCOM);
  _cap         = dep.get(COM_CAPCOM);
  if (_comunefis.empty()) 
  {
    _viafis    = anag.get(ANA_INDRF);
    _viafis.rtrim();
    _viafis << " " << anag.get (ANA_CIVRF); 
  }
  else
  {
    _viafis    = anag.get(ANA_INDRES);
    _viafis.rtrim();
    _viafis << " " << anag.get (ANA_CIVRES); 
  }
}

int CG0400_application::stampa_intestazione_ditta()
{
  int r = 3;
  TString codice_ditta;
  TString riga(132);

  get_dati_ditta();
  codice_ditta << get_firm(); 

  set_header (r, "Ditta %s %s Via %s %s %s %s", (const char*)codice_ditta,
              (const char*)_ragsoc, (const char*)_viafis,
              (const char*)_cap, (const char*)_comunefis,
              (const char*)_provfis);
  r++;
  printer().setdate(_data);
  riga = "Data @<  Pag. @#";
  riga.right_just(127);
  riga.overwrite (format ("Partita iva %s Codice fiscale %s", (const char*)_paiva, (const char*)_cofi));
  set_header (r, "%s", (const char*) riga);
  r++;

  return r; 
}

void CG0400_application::preprocess_header()
{
  int r = 1;

  reset_header();
  if (_livelloprog == 1)
    set_header(1, "@30gProgressivi IVA per Aliquota");
  else set_header(1, "@30gProgressivi IVA per Attivita'");

  r = stampa_intestazione_ditta();

  if (_tipoprog == 1)
    set_header(r, "Vendite");
  else set_header(r, "Acquisti");
  if (_livelloprog == 1)
    set_header(r++, "@10gIVA %s",(const char*) _codivamsk);
  else set_header(r++, "@10gCod.attivita' %s",(const char*)_codattmsk);
  r++;        
  if (_vuoilordi)
    set_header(r, "@21gImponibile@40gImposta@50gImporto lordo");
  else set_header(r, "@21gImponibile@40gImposta");
}

print_action CG0400_application::postprocess_page(int file, int counter)
{
  if (_i < 12) return REPEAT_PAGE;
  else return NEXT_PAGE; 
}

int cg0400(int argc,char* argv[])
{
  CG0400_application a;
  a.run(argc, argv, "Riepilogo progressivi IVA");
  return 0;
}

