// Stampa base
#include "77stba.h"
const int _RIGHE_N = 6;
const int _RIGHE_R = 2;
const int _RIGHE_P = 4;
const int _RIGHE_Q = 4;
const int _RIGHE_S = 4;
const int _RIGHE_T = 4;
const int _RIGHE_NA = 8;
const int _RIGHE_RA = 4;
const int _RIGHE_PA = 10;
const int _RIGHE_QA = 4;
const int _RIGHE_SA = 6;
const int _RIGHE_TA = 4;

int TBase1::dic_form_len() const
{
  if (curr_page()==PRIMA && _PaginaPosizionamento)
    return BASE_FORMLEN-HEADER_PRIMA_NOPOS;
  else
    return BASE_FORMLEN;
}

int TBase1::prima_riga(PaginaQuadro p) const
{
  if (p==PRIMA && _PaginaPosizionamento)
    return 11;
  else
    return 11+HEADER_PRIMA_NOPOS;
}

TBase1::TBase1(const char* sNomeForm, const char* quadro)  : TDicForm(sNomeForm, quadro) 
{
  r = new TRelation(LF_SOCI);
  r->add(LF_ANAG,    "TIPOA=TIPOASOC|CODANAGR=CODANAGRSO");
  r->add(LF_ANAGFIS, "CODANAGR=CODANAGR",1, LF_ANAG);    
  r->add(LF_COMUNI,  "COM=COMNASC",1,LF_ANAGFIS);
  c = new TCursor(r);       
  _bAllegSoci=FALSE;
}

TBase1::~TBase1()
{
  delete r;
  delete c;
}

void TBase1::stampa_corpo(TPrinter& pr)
{
  TPrint_section& body = section('B', first_page);
  body.reset();
  body.update();       
  const int body_righe = body.height();
  for (int i = 0; i < body_righe; i++)
  {
    pr.print(body.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

// accetta solo quelli con qualifica=A,B o C
bool bFiltraSoci(const TRelation* rel)
{ 
  TString sQual(3);
  sQual = rel->lfile().get("RICQUAL"); 
  return sQual=="A" || sQual=="B" || sQual=="C";
}

long TBase1::iContaSoci()
{                  
  TString filtro(20);
  filtro.format("CODDITTA=%d",_codditta);
  c->setfilter(filtro);
  c->set_filterfunction(bFiltraSoci);
  (*c)=0L;
  return c->items();
}

const int _INIZIO_SOCI=53;
void TBase1::stampa_soci(TPrinter& pr)
{                                  
  TPrint_section& fut = section('F', first_page);
  fut.reset();
  jump_to_line(pr,_INIZIO_SOCI);
  const long iSoci = iContaSoci();
  if (iSoci > 11)
  {
    _bAllegSoci=TRUE;
    TPrintrow& rg=fut.row(0);    
    rg.put("VEDERE ALLEGATO", 25);
    pr.print(rg);      
    _RigaCorr++;
    if (usa_progind()) progind()->addstatus(1);
  }
  else
  {    
    int i=0;                             
    TString sRagsoc,sSesso,sComuneNa,sProvNa,sDataNa,sCodFis,sCodQua;
    for ((*c)=0L; c->pos() < c->items(); ++(*c))
    {                         
      TString sNome,sCognome;
      TPrintrow& rg=fut.row(i++);
      sCodQua=c->file().get("RICQUAL");       
      sRagsoc=c->file(LF_ANAG).get("RAGSOC");
      sCodFis=c->file(LF_ANAG).get("COFI");       
      sDataNa=c->file(LF_ANAGFIS).get("DATANASC"); 
      sSesso=c->file(LF_ANAGFIS).get("SESSO");
      sComuneNa=c->file(LF_COMUNI).get("DENCOM");      
      sComuneNa.cut(28);
      sProvNa=c->file(LF_COMUNI).get("PROVCOM");      
//      fut.field(0).set(sRagsoc);  
      sRagsoc:=fut.field(0).get();
      if (sRagsoc.len() > 30 && sRagsoc[30] != ' ')
      {
	      sCognome=sRagsoc.left(30);
	      sCognome.trim();
	      sNome=sRagsoc.mid(30,0);
	      sNome.trim();
	      sRagsoc = sCognome;
	      sRagsoc << " " << sNome;
      }
      rg.put(sRagsoc,fut.field(0).x()-1);
      fut.field(1).set(sSesso);          
      rg.put(sSesso,fut.field(1).x()-1);      
      fut.field(2).set(sComuneNa);       
      rg.put(sComuneNa,fut.field(2).x()-1);      
      fut.field(3).set(sProvNa);         
      rg.put(sProvNa,fut.field(3).x()-1);      
      fut.field(4).set(sDataNa);         
      rg.put(sDataNa,fut.field(4).x()-1);      
      fut.field(5).set(sCodFis);         
      rg.put(sCodFis,fut.field(5).x()-1);      
      fut.field(6).set(sCodQua);         
      rg.put(sCodQua,fut.field(6).x()-1);      
      pr.print(rg);      
      _RigaCorr++;
      if (usa_progind()) progind()->addstatus(1);
    }
  }
}

bool TBase1::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;
      
  if (!InitPrint(codditta))
    return FALSE;
  pr.formlen(BASE_FORMLEN);             

  (*cur)=0L;  
  if (_modulaser) 
  {
    ClearFlagModulaser();
    TPrintrow r;
    if (!_GiaMessoStartDoc)
      put_modulaser(r, STARTDOC);     
    put_modulaser(r, STARTDITTA);
    put_modulaser(r, STARTPAGE, 1);
    pr.print(r);
    _RigaCorr++;
  }
  jump_to_line(pr, prima_riga(PRIMA));
  stampa_corpo(pr);       
  stampa_soci(pr);
  next_page(pr);
  close_print();
  return TRUE;
}

void TBase2::stampa_corpo(TPrinter& pr)
{
  TPrint_section& body = section('B', even_page);
  body.reset();
  body.update();       
  const int body_righe = body.height();
  for (int i = 0; i < body_righe; i++)
  {
    pr.print(body.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TBase2::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;
  filtra(codditta);      
  _RigaCorr=0;
  (*cur)=0L;  
  jump_to_line(pr, prima_riga(PRIMA));
  stampa_corpo(pr);       
  next_page(pr);
  close_print();                                      
  return TRUE;
}

long TBase3::filtra(const long codditta)
{
  TString filtr(24); 
  _codditta=codditta;
  filtr.format("(CODDITTA==%ld)&&(QLAP==%d)", codditta, anno_770());
  cursor()->setfilter(filtr, TRUE);   
  const long items = cursor()->items();
  return items;
}

void TBase3::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

int TBase3::stampa_L(TPrinter& pr,const int iChiaveL)
{
  long codit=0L;
  TPrint_section& body = section('B', odd_page);
  body.reset();               
  
  TCursor& cur = *cursor();
// Le chiavi nel file e nel .ini sono saggiamente scambiate  
  if (iChiaveL==2) 
    cur.setkey(1);
  else 
    cur.setkey(2);

//  filtra(_codditta);
  
  bool finito=FALSE;
  int righe=0;
  while (!finito)
  {
    body.update();
	  const int body_righe = body.height();
	  for (int i = 0; i < body_righe; i++)
	  {
	    TPrintrow& rr=body.row(i);
	    pr.print(rr);
	    rr.reset();
	    _RigaCorr++;
	  }
	  if (usa_progind())
	    progind()->addstatus(1);
	  righe++;                           
	  ++cur;
	  codit=cur.file().get_long("CODDITTA");
	  bool buono=codit==_codditta;
// Guarda se e' necessario stampare l'aggiuntivo
	  _bAggiuntivoL = buono && righe>14;
	  finito=righe>14 || codit!=_codditta;
  }
  return righe;
}

void TBase3::stampa_totali_L(TPrinter& pr)
{ 
// La sezione f last contiene solo due totali aggiornati con add nel form
  TPrint_section& hh = section('F', last_page);
//  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TBase3::print(const long codditta, const long NumFis, const long NumNoFis)
{                          
  _bAggiuntivoL=TRUE;
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;
  filtra(codditta);      
  _RigaCorr=0;               
  (*cur)=0L;  
  jump_to_line(pr, prima_riga(PRIMA));
// Stampa i codici concessione e tesoreria
  stampa_testata(pr);         
// Legge dai par.studio l'ordinamento da usare per L
  TConfig conf(CONFIG_STUDIO);
  const int iChiaveL = (int)conf.get_long("FlStQl", "77"); 
  const int righe_stampate=stampa_L(pr,iChiaveL);                 
// Se la stampa prosegue i totali vanno sull'aggiuntivo NON qui
  if (!_bAggiuntivoL)                            
  {
    jump_to_line(pr,_RIGA_TOTALI_L);
    stampa_totali_L(pr);
  }
  next_page(pr);
  close_print();  
  return TRUE;
}

const char* TRigaN::sMeseRif() const
{           
  __dep16="";
  __dep16 << _MeseRif;
  return __dep16;
}

const char* TRigaN::sAnnoRif() const
{           
  __dep16="";
  __dep16 << _AnnoRif;
  return __dep16;
}

// Ordina le righe N per periodo di riferimento
int TRigaN::compare(const TSortable& s) const
{
  const TRigaN& rec = (const TRigaN&)s;
  const int da = _AnnoRif - rec._AnnoRif;
  const int dm = _MeseRif - rec._MeseRif;
  if (da==0)
    return dm;
  else
    return da;                                           
}

TRigaN::TRigaN(const TLocalisamfile& qn)
{                   
  _pos = qn.recno();
  
  const TRectype& rec = qn.curr();
  
  _MeseRif = rec.get_int("MESERIF"); 
  _AnnoRif = rec.get_int("ANNORIF");  
// Nel quadro R si chiama diversamente @!#@!!!  
  if (qn.num() == LF_QUAN)
    _ImpRimb = rec.get_real("IMPOSTA");
  else                               
    _ImpRimb = rec.get_real("IMPRIMB");  
  _CompAss = rec.get_real("COMPENSI");
}

int TRigheNR::fill(const long codditta,TLocalisamfile& qnr)
{
  long ditta=0L;  
  _data.destroy();
// Si posiziona sul primo della ditta corrente
  qnr.zero();
  qnr.put("CODDITTA",codditta);
  qnr.read()==NOERR;
  ditta=qnr.get_long("CODDITTA");
  if (ditta!=codditta) return 0;

// Legge tutti quelli della ditta corrente
  for (; !qnr.eof(); qnr.next())
  {                          
    ditta=qnr.get_long("CODDITTA");
    if (ditta!=codditta) break;
    
    TRigaN* n = new TRigaN(qnr);
    if (n->pos() >= 0)
      _data.add(n);
    else
      delete n;  
  } 
  _data.sort();
  const int i = _data.items();
  return i;
}

const char* TRigaQT::sMesePag() const
{           
  __dep16="";
  __dep16 << _MesePag;
  return __dep16;
}

const char* TRigaQT::sAnnoPag() const
{           
  __dep16="";
  __dep16 << _AnnoPag;
  return __dep16;
}

// Ordina le righe N per periodo di riferimento
int TRigaQT::compare(const TSortable& s) const
{
  const TRigaQT& rec = (const TRigaQT&)s;
  const int da = _AnnoPag - rec._AnnoPag;
  const int dm = _MesePag - rec._MesePag;
  if (da==0)
    return dm;
  else
    return da;                                           
}

TRigaQT::TRigaQT(const TLocalisamfile& qt)
{                   
  const TRectype& rec = qt.curr();
  
  _MesePag = rec.get_int("MESEPAG"); 
  _AnnoPag = rec.get_int("ANNOPAG");  
  _ContVers = rec.get_real("CONTVERS");
  _ContRimb = rec.get_real("CONTRIMB");
  _Interessi=rec.get_real("INTERESSI");
  _sCodReg=rec.get("CODREG");
}

int TRigheQT::fill(const long codditta,TLocalisamfile& qt)
{
  long ditta=0L;
// Si posiziona sul primo della ditta corrente
  _data.destroy();
  qt.zero();
  qt.put("CODDITTA",codditta);
  qt.read()==NOERR;
  ditta=qt.get_long("CODDITTA");
  if (ditta!=codditta) return 0;

// Legge tutti quelli della ditta corrente
  for (; !qt.eof(); qt.next())
  {                          
    ditta=qt.get_long("CODDITTA");
    if (ditta!=codditta) break;
    
    TRigaQT* n = new TRigaQT(qt);
    if (n->pos() >= 0)
      _data.add(n);
    else
      delete n;  
  } 
  _data.sort();
  const int i = _data.items();
  return i;
}

// Ordina le righe N per periodo di riferimento
int TRigaPS::compare(const TSortable& s) const
{
  const TRigaPS& rec = (const TRigaPS&)s;
  TDate dtDataS = rec.dDataVers();
  const int month=_dDv.month();
  const int year=_dDv.year();
  const int da = year  - dtDataS.year();
  const int dm = month - dtDataS.month();
  if (da==0)
    return dm;
  else
    return da;                                           
  
  return _dDv<rec.dDataVers();
}

TRigaPS::TRigaPS(const TLocalisamfile& qt)
{                   
  const TRectype& rec = qt.curr();
  
  _dDv     = rec.get_date("DATAVERS"); 
  _rImp    = rec.get_real("IMPOSTA");  
  _rIntDip = rec.get_real("INTERDIP");
  _rIntDat = rec.get_real("INTERDAT");           
	_sTipoV  = rec.get("TIPOVERS");
	_sCodTrib= rec.get("CODTRIB");
	_sSerie  = rec.get("SERIE");
	_sNumero = rec.get("NUMERO");  
}

int TRighePS::fill(const long codditta,TLocalisamfile& ps)
{
  long ditta=0L;
// Si posiziona sul primo della ditta corrente
  _data.destroy();
  ps.zero();
  ps.put("CODDITTA",codditta);
  ps.read()==NOERR;
  ditta=ps.get_long("CODDITTA");
  if (ditta!=codditta) return 0;

// Legge tutti quelli della ditta corrente
  for (; !ps.eof(); ps.next())
  {                          
    ditta=ps.get_long("CODDITTA");
    if (ditta!=codditta) break;
    
    TRigaPS* n = new TRigaPS(ps);
    if (n->pos() >= 0)
      _data.add(n);
    else
      delete n;  
  } 
  _data.sort();
  const int i = _data.items();
  return i;
}

int TBase4::calcola_firma()
{
  TPrint_section& totali = section('F', first_page);
  TForm_item& signature = totali.find_field(_IdFirma);
  const int y = signature.y();
  TString spazi(50); spazi.fill(' ');  
  TString cognome = signature.get();
  if (cognome.len() > 30 && cognome[29] == ' ')
  {
    TString nome = cognome.mid(30, -1);
    cognome.cut(30); cognome.trim();
    cognome << ' ' << nome;
    signature.set(cognome);
    
    totali.row(y-1).put(spazi, signature.x()-1);
    totali.row(y-1).put(cognome, signature.x()-1);
  }   
  return y;
}

void TBase4::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}                                  

void TBase4::fill_riga_QT(TPrint_section& sec,const int num)
{              
  TString sVal;
  int start=1,end=6;
  for (int i = start; i <= end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < _righeQT.items())
    {
      const TRigaQT& rN = _righeQT[num];	    
	    if (i==start)
  	    sVal=rN.sMesePag();
  	  else if (i==start+1)
  	    sVal=rN.sAnnoPag();
  	  else if (i==start+2)  
  	    sVal=rN.ContVers(fi.picture());
  	  else if (i==start+3)
  	    sVal=rN.ContRimb(fi.picture());
  	  else if (i==start+4)
  	    sVal=rN.Interessi(fi.picture());
  	  else if (i==start+5)
  	    sVal=rN.CodReg();
	  }  
	  else 
	    sVal="";
	  fi.set(sVal); 
	  TPrintrow& row=sec.row(0);
	  row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::stampa_Q(TPrinter& pr)
{
  TPrint_section& body = section('F', even_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAQ);
  _righeQT.fill(_codditta,qp);    
  if (_righeQT.items()==0) return;  
  _bAggQ = _righeQT.items() > _RIGHE_Q;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_QT(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_Q-1;
  }
// Salta due righe alla fine  
  stampa_righe_vuote(pr,2);
}

void TBase4::stampa_T(TPrinter& pr)
{
  TPrint_section& body = section('F', odd_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAT);
  _righeQT.fill(_codditta,qp);
  if (_righeQT.items()==0) return;
  _bAggT = _righeQT.items() > _RIGHE_T;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_QT(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_T-1;
  }
}

void TBase4::fill_riga_PS(TPrint_section& sec,const int num)
{              
  TString sVal,sDep;
  int start=1,end=8;
  for (int i = start; i <= end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < _righePS.items())
    {
      const TRigaPS& rN = _righePS[num];	    
	    if (i==start)
  	    sVal=rN.sImposta(fi.picture());
  	  else if (i==start+1)
  	    sVal=rN.sIntDip(fi.picture());
  	  else if (i==start+2)  
  	    sVal=rN.sIntDat(fi.picture());
  	  else if (i==start+3)
  	    sVal=rN.sTipoVers();
  	  else if (i==start+4)
  	    sVal=rN.sCodTrib();
  	  else if (i==start+5)  
      {
  	    sDep=rN.sDataVers();
  	    sVal.picture(fi.picture(),sDep);
  	  }
  	  else if (i==start+6)
  	    sVal=rN.sSerie();
  	  else if (i==start+7)
  	    sVal=rN.sNumero();
	  }  
	  else 
	    sVal="";
	  fi.set(sVal); 
	  TPrintrow& row=sec.row(0);
	  row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::stampa_P(TPrinter& pr)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAP);
  _righePS.fill(_codditta,qp);    
  if (_righePS.items()==0) return;  
  const int items=_righePS.items();
  _bAggP = items > _RIGHE_P;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_PS(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_P-1;
  }
// Salta due righe alla fine  
  stampa_righe_vuote(pr,2);
}

void TBase4::stampa_S(TPrinter& pr)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
  TLocalisamfile qp(LF_QUAS);
  _righePS.fill(_codditta,qp);      
  if (_righePS.items()==0) return;    
  _bAggS = _righePS.items() > _RIGHE_S;

  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_PS(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_S-1;
  }
// Salta due righe alla fine  
  stampa_righe_vuote(pr,2);
}

void TBase4::stampa_R(TPrinter& pr)
{
  TPrint_section& body = section('B', even_page);
  body.reset();                                     
  TLocalisamfile qr(LF_QUAR);
  _righeNR.fill(_codditta,qr);      
  if (_righeNR.items()==0) return;    
  const int items=_righeNR.items();
// se iRigheNR > 2 => bisogna stampare anche l'allegato
  _bAggR = items > _RIGHE_R;
  fill_riga_NR(body,0,0);                   
  fill_riga_NR(body,1,1); 
  TPrintrow& rr=body.row(0);
  pr.print(rr);
	rr.reset();
	_RigaCorr++;
  if (usa_progind())
    progind()->addstatus(1);
// Salta due righe alla fine  
  stampa_righe_vuote(pr,2);
}

void TBase4::fill_riga_NR(TPrint_section& sec,const int num, const int side)
{              
  TString sVal;
  int start,end;
  if (side==0)
  {
    start=1;
    end=5;
  }
  else
  {
    start=5;
    end=9;
  }
  for (int i = start; i < end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < _righeNR.items())
    {
      const TRigaN& rN = _righeNR[num];	    
	    if (i==start)
  	    sVal=rN.sMeseRif();
  	  else if (i==start+1)
  	    sVal=rN.sAnnoRif();
  	  else if (i==start+2)  
  	    sVal=rN.ImpRimb(fi.picture());
  	  else if (i==start+3)
  	    sVal=rN.CompAss(fi.picture());
	  }  
	  else 
	    sVal="";
	  fi.set(sVal); 
	  TPrintrow& row=sec.row(0);
	  row.put(sVal,fi.x()-1);
  }       
} 

void TBase4::stampa_righe_vuote(TPrinter& pr,const int righe)
{
	TPrintrow rr;
  for (int i=0; i<righe; i++)
  {
	  pr.print(rr);
	  rr.reset();
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
  }
}

void TBase4::stampa_N(TPrinter& pr)
{ 
  TPrint_section& body = section('B', odd_page);
  body.reset();                                     
  TLocalisamfile qn(LF_QUAN);
  _righeNR.fill(_codditta,qn);        
  if (_righeNR.items()==0) return;      
// se iRigheN > 6 => bisogna stampare anche l'allegato
  _bAggN = _righeNR.items() > _RIGHE_N;

  int num=0;                
  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_NR(body,num,0);                   
    num+=3;
    fill_riga_NR(body,num,1); 
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    num-=2;
    FinitaSezione=riga>2;               
  }
// Salta due righe alla fine  
  stampa_righe_vuote(pr,2);
}

void TBase4::stampa_fine(TPrinter& pr)
{
  TPrint_section& sec = section('F', first_page);
  const int hhr = sec.height();
  sec.reset();                  
  sec.update();                 
  const int lasty = calcola_firma();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(sec.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TBase4::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  _bAggN=_bAggP=_bAggR=_bAggQ=_bAggS=_bAggT=FALSE;
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;
  filtra(codditta);      
  _RigaCorr=0;
  (*cur)=0L;                              
  jump_to_line(pr, prima_riga(PRIMA));
// Stampa da M1 a M6  
  stampa_testata(pr);
  stampa_N(pr);          
  stampa_P(pr); 
  stampa_Q(pr);
  stampa_R(pr);
  stampa_S(pr);
  stampa_T(pr);        
  stampa_fine(pr);
  next_page(pr);
  close_print();
  return TRUE;
}

bool TStampaBase::user_create()
{
  _fBase1 = new TBase1("77base1", "Base");
  _fBase2 = new TBase2("77base2", "Base");   
  _fBase3 = new TBase3("77base3", "Base");     
  _fBase4 = new TBase4("77base4", "Base");      
// Adesso bisogna chiamare set_cursor per impostare il cursore dentro
// al form. Sarebbe meglio fare in modo che il form usi sempre il cursore
// letto dal .frm, senza bisogno di passarglielo dall'applicazione
  _fBase1->set_cursor(_fBase1->TForm::cursor());         
  _fBase2->set_cursor(_fBase2->TForm::cursor());    
  _fBase3->set_cursor(_fBase3->TForm::cursor());    
  _fBase4->set_cursor(_fBase4->TForm::cursor());    
  return TRUE;
}

bool TStampaBase::user_destroy()
{
  delete _fBase1; 
  delete _fBase2;  
  delete _fBase3;  
  delete _fBase4;      
  return TRUE;
}          

bool TStampaBase::print_quadro(const int OffsetDitta, const bool modulaser)
{
  int start=0, last=0;                

// Setta formlen prima di printer.open per avere la lunghezza giusta nel caso di 
// stampa a video
  printer().formlen(BASE_FORMLEN);               
  bool ok = printer().open();

  _fBase1->set_modulaser(modulaser);
  _fBase2->set_modulaser(modulaser);      
  _fBase3->set_modulaser(modulaser);      
  _fBase4->set_modulaser(modulaser);      
      
// Dice se deve eseguire il posizionamento del foglio.
// Se stampa piu' ditte va eseguito solo sulla prima
// Occhio a non spostarlo nel ciclo.
  _fBase1->set_posiziona(TRUE);
    
  if (OffsetDitta >= 0)
  {
    start = OffsetDitta;
    last = OffsetDitta;  
  }
  else
    last = ditte().items() - 1;
    
  for (int i = start; i <= last; i++)
  {
    TString CoFiDic(20);
    TToken_string riga(ditte()[i]);
    const long codditta = atol(riga.get(0));
    const TipoDitta  tipo = (TipoDitta)riga.get_int(1);
    const long fis      = riga.get_long(2);
    const long nofis    = riga.get_long(3);
    const bool LastFis  = (bool)riga.get_int(4);
    const bool LastNoFis = (bool)riga.get_int(5);

// I gruppi dich-estinti hanno totali comuni  
// Si presume che nell'array vengano messi nell'ordine dich-estinti
    if (tipo == normale || tipo == dichiarante)
      _fBase1->azzera_totali();

    if (tipo == estinto)
      CoFiDic = riga.get(6);
      
// Dice al form che tipo di ditta si stampa
    _fBase1->set_tipo_ditta(tipo);

// Numera i fogli a partire da 1 per ogni ditta normale e da 1 e di seguito negli estinti
// per i sogg. dichiaranti
    if (tipo == normale || tipo == dichiarante)
      _fBase1->set_num_foglio(1);
      
// Se la ditta e' estinta dice al form il cod.fis. del dichiarante
    if (tipo == estinto)
      _fBase1->set_cofi_dic(CoFiDic);

// Dice al form che e' l'ultima ditta
    if (i == last)
      _fBase1->set_last_ditta(TRUE);

    _fBase1->print(codditta, fis, nofis); 
    _fBase2->print(codditta, fis, nofis);    
    _fBase3->print(codditta, fis, nofis);    
    _fBase4->print(codditta, fis, nofis);            
  }                       
  printer().close();
  return ok;
}

int TQuadroL::prima_riga(PaginaQuadro p) const
{
  if (p==PRIMA)
  {
    if (_PaginaPosizionamento)
      return 4;
    else
      return 4+HEADER_PRIMA_NOPOS;
  }
  else
    return 4;
}


long TQuadroL::filtra(const long codditta)
{
  TString filtr(24); 
  _codditta=codditta;
  filtr.format("(CODDITTA==%ld)&&(QLAP==%d)", codditta,anno_770());
  cursor()->setfilter(filtr, TRUE);   
  const long items = cursor()->items();
  return items;
}

void TQuadroL::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();

  TForm_item& nf=hh.find_field(18);
  TString fstr(10); fstr << _num_foglio;
  nf.set(fstr);      
  _num_foglio++;
  
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

bool TQuadroL::stampa_L(TPrinter& pr,const long lStartRec,const int iRecL)
{
  long codit=0L;
  bool eof=FALSE;
  TPrint_section& body = section('B', odd_page);
  body.reset();               
  TCursor& cur = *cursor();
  if (lStartRec > cur.items())
    return TRUE;
  else
    cur=lStartRec;
  bool finito=FALSE;
  int righe=0;

  while (!finito)
  {
    body.update();
	  const int body_righe = body.height();
	  for (int i = 0; i < body_righe; i++)
	  {
	    TPrintrow& rr=body.row(i);
	    pr.print(rr);
	    rr.reset();
	    _RigaCorr++;
	  }
	  if (usa_progind())
	    progind()->addstatus(1);
	  righe++;                           
	  ++cur;  
	  eof=cur.pos()==cur.items()-1;
	  finito = (righe==iRecL-1) || eof;
  }
  return eof;
}

void TQuadroL::stampa_totali_L(TPrinter& pr)
{ 
// La sezione f last contiene solo due totali aggiornati con add nel form
  TPrint_section& hh = section('F', last_page);
//  hh.reset();
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

const int _START_AGG_L=17;
const int _REC_PRIMA_AGG_L=12;
const int _REC_SECONDA_AGG_L=14;
const int _RIGA_TOTALI_AGG_L=60;

bool TQuadroL::print(const long codditta, const long NumFis, const long NumNoFis)
{                          
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  if (!InitPrint(codditta))
    return FALSE;

// Non stampare se non ci sono record
  if (cur->items() < _START_AGG_L-1)                
    return FALSE;
    
// Legge dai par.studio l'ordinamento da usare per L
  TConfig conf(CONFIG_STUDIO);
  const int iChiaveL = (int)conf.get_long("FlStQl", "77"); 
  if (iChiaveL==2) 
    cur->setkey(1);
  else 
    cur->setkey(2);

  int lOffsetL=_START_AGG_L;
  bool finito=FALSE;
  while (!finito)
  {  
	  jump_to_line(pr, prima_riga(PRIMA));
	  stampa_testata(pr);         
	  finito=stampa_L(pr,lOffsetL,_REC_PRIMA_AGG_L);
    next_page(pr);
	  if (!finito)         
	  {
	    lOffsetL+=_REC_PRIMA_AGG_L;
	    jump_to_line(pr, prima_riga(SECONDA));
	    finito=stampa_L(pr,lOffsetL,_REC_SECONDA_AGG_L);
	  }
	  if (finito)
	  {
	    jump_to_line(pr,_RIGA_TOTALI_AGG_L);
	    stampa_totali_L(pr);
	  }
    next_page(pr);
  }
  close_print();  
  return TRUE;
}

bool TStampaQuadroAggL::user_create()
{   
  _form = new TQuadroL("77QL", quadro());
  _form->set_cursor(_form->TForm::cursor());
// init anche di _cur nell'applicazione  
  _cur = _form->cursor();
  return TRUE;  
}

bool TStampaQuadroAggL::user_destroy()
{
  delete _form;
  return TRUE;
}

void TQuadroN::stampa_fine(TPrinter& pr)
{
  TPrint_section& sec = section('F', first_page);
  const int hhr = sec.height();
  sec.reset();                  
  sec.update();                   
  const int lasty = calcola_firma();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(sec.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

void TQuadroN::stampa_testata(TPrinter& pr)
{
  TPrint_section& hh = section('H', first_page);
  hh.reset();
  
  TForm_item& nf=hh.find_field(12);
  TString fstr(10); fstr << _num_foglio;
  nf.set(fstr);      
  _num_foglio++;
  
  hh.update();       
  const int hhr = hh.height();
  for (int i = 0; i < hhr; i++)
  {
    pr.print(hh.row(i));
    _RigaCorr++;
  }
  if (usa_progind())
    progind()->addstatus(1);
}

int TQuadroN::prima_riga(PaginaQuadro p) const
{
  if (_PaginaPosizionamento)
    return 4;
  else
    return 4+HEADER_PRIMA_NOPOS;
}

/*void TBase4::fill_riga_QT(TPrint_section& sec,const int num)
{              
  TString sVal;
  int start=1,end=6;
  for (int i = start; i <= end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < _righeQT.items())
    {
      const TRigaQT& rN = _righeQT[num];	    
	    if (i==start)
  	    sVal=rN.sMesePag();
  	  else if (i==start+1)
  	    sVal=rN.sAnnoPag();
  	  else if (i==start+2)  
  	    sVal=rN.ContVers(fi.picture());
  	  else if (i==start+3)
  	    sVal=rN.ContRimb(fi.picture());
  	  else if (i==start+4)
  	    sVal=rN.Interessi(fi.picture());
  	  else if (i==start+5)
  	    sVal=rN.CodReg();
	  }  
	  else 
	    sVal="";
	  fi.set(sVal); 
	  TPrintrow& row=sec.row(0);
	  row.put(sVal,fi.x()-1);
  }       
} */

/*
void TBase4::fill_riga_PS(TPrint_section& sec,const int num)
{              
  TString sVal;
  int start=1,end=8;
  for (int i = start; i <= end; i++)
  {
    TForm_item& fi = sec.find_field(i);
    if (num < _righePS.items())
    {
      const TRigaPS& rN = _righePS[num];	    
	    if (i==start)
  	    sVal=rN.sImposta(fi.picture());
  	  else if (i==start+1)
  	    sVal=rN.sIntDip(fi.picture());
  	  else if (i==start+2)  
  	    sVal=rN.sIntDat(fi.picture());
  	  else if (i==start+3)
  	    sVal=rN.sTipoVers();
  	  else if (i==start+4)
  	    sVal=rN.sCodTrib();
  	  else if (i==start+5)
  	    sVal=rN.sDataVers();
  	  else if (i==start+6)
  	    sVal=rN.sSerie();
  	  else if (i==start+7)
  	    sVal=rN.sNumero();
	  }  
	  else 
	    sVal="";
	  fi.set(sVal); 
	  TPrintrow& row=sec.row(0);
	  row.put(sVal,fi.x()-1);
  }       
} */                              

void TQuadroN::stampa_N(TPrinter& pr)
{ 
  TPrint_section& body = section('B', odd_page);
  body.reset();                                     
//  TLocalisamfile qn(LF_QUAN);
//  _righeNR.fill(_codditta,qn);
// Nell'aggiuntivo parto dal record n.7
  int num=6;                
  int riga=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_NR(body,num,0);                   
    num+=3;
    fill_riga_NR(body,num,1); 
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    num-=2;
    FinitaSezione=riga>4;               
  }
}

void TQuadroN::stampa_P(TPrinter& pr)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
//  TLocalisamfile qp(LF_QUAP);
//  _righePS.fill(_codditta,qp);
  const int items=_righePS.items();
// Parte da rec.n.5
  int riga=4;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_PS(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_PA-1;
  }
}

void TQuadroN::stampa_Q(TPrinter& pr)
{
  TPrint_section& body = section('F', even_page);
  body.reset();                                     
//  TLocalisamfile qp(LF_QUAQ);
//  _righeQT.fill(_codditta,qp);
// parte da rec.n.5
  int riga=4;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_QT(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_QA-1;
  }
// Salta due righe alla fine  
  stampa_righe_vuote(pr,2);
}

void TQuadroN::stampa_R(TPrinter& pr)
{
  TPrint_section& body = section('B', even_page);
  body.reset();                                     
//  TLocalisamfile qr(LF_QUAR);
//  _righeNR.fill(_codditta,qr);
  const int items=_righeNR.items();
  int RecNum=2;       
  int RigheStampate=0;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
	  fill_riga_NR(body,RecNum,0);                   
	  RecNum+=3;
	  fill_riga_NR(body,RecNum,1);
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
		rr.reset();
		RigheStampate++;
		_RigaCorr++;
	  if (usa_progind())
	    progind()->addstatus(1); 
	  RecNum-=2;    
    FinitaSezione=RigheStampate>_RIGHE_RA-1;	    
  }
}

void TQuadroN::stampa_S(TPrinter& pr)
{
  TPrint_section& body = section('H', even_page);
  body.reset();                                     
//  TLocalisamfile qp(LF_QUAS);
//  _righePS.fill(_codditta,qp);

  int riga=4;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_PS(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_SA-1;
  }
}

void TQuadroN::stampa_T(TPrinter& pr)
{
  TPrint_section& body = section('F', odd_page);
  body.reset();                                     
//  TLocalisamfile qp(LF_QUAT);
//  _righeQT.fill(_codditta,qp);
  int riga=4;
  bool FinitaSezione=FALSE;
  while (!FinitaSezione)
  {
// Stampa la parte sinistra (primi 4 campi)  
    fill_riga_QT(body,riga);                   
	  TPrintrow& rr=body.row(0);
	  pr.print(rr);
	  rr.reset();
	  riga++;
	  _RigaCorr++;
    if (usa_progind())
      progind()->addstatus(1);
    FinitaSezione=riga>_RIGHE_TA-1;
  }
}

/*
void TBase4::fill_riga_NR(TPrint_section& sec,const int num, const int side)
{              
  TString sVal;
  int start,end;
  if (side==0)
  {
    start=0;
    end=4;
  }
  else
  {
    start=4;
    end=8;
  }
  for (int i = start; i < end; i++)
  {
    TForm_item& fi = sec.field(i);
    if (num < _righeNR.items())
    {
      const TRigaN& rN = _righeNR[num];	    
	    if (i==start)
  	    sVal=rN.sMeseRif();
  	  else if (i==start+1)
  	    sVal=rN.sAnnoRif();
  	  else if (i==start+2)  
  	    sVal=rN.ImpRimb(fi.picture());
  	  else if (i==start+3)
  	    sVal=rN.CompAss(fi.picture());
	  }  
	  else 
	    sVal="";
	  fi.set(sVal); 
	  TPrintrow& row=sec.row(0);
	  row.put(sVal,fi.x()-1);
  }       
} */

bool TQuadroN::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor* cur = cursor();
  TPrinter& pr = printer();
  _codditta=codditta;
  if (!InitPrint(codditta))
    return FALSE;

  TLocalisamfile qn(LF_QUAN);
  _righeNR.fill(_codditta,qn);
  bool stampoN=_righeNR.items() > 6;
  TLocalisamfile qp(LF_QUAP);
  _righePS.fill(_codditta,qp);      
  bool stampoP=_righePS.items() > 4;  
  TLocalisamfile qq(LF_QUAQ);
  _righeQT.fill(_codditta,qq);        
  bool stampoQ=_righeQT.items() > 4;    
  TLocalisamfile qr(LF_QUAR);
  _righeNR.fill(_codditta,qr);
  bool stampoR=_righeNR.items() > 2;    
  TLocalisamfile qs(LF_QUAS);
  _righePS.fill(_codditta,qs);     
  bool stampoS=_righePS.items() > 4;    
  TLocalisamfile qt(LF_QUAT);
  _righeQT.fill(_codditta,qt);
  bool stampoT=_righeQT.items() > 4;  

// Se non c'e' niente da stampare esce
  if (!stampoN && !stampoP && !stampoQ && !stampoR && !stampoS
      && !stampoT) 
    return FALSE;
  
  pr.formlen(TDicForm::dic_form_len());
  _RigaCorr=0;
  (*cur)=0L;
  bool done=FALSE;
  while (!done)
  {
	  jump_to_line(pr, prima_riga(PRIMA));             
	  int skip=HEADER_PRIMA_NOPOS;
	  stampa_testata(pr);
    jump_to_line(pr, _PaginaPosizionamento ? 20-skip : 20);
	  stampa_N(pr); 
    jump_to_line(pr, _PaginaPosizionamento ? 26-skip : 26);	           
	  stampa_P(pr); 
    jump_to_line(pr, _PaginaPosizionamento ? 38-skip : 38);	  
	  stampa_Q(pr);
    jump_to_line(pr, _PaginaPosizionamento ? 44-skip : 44);	  
	  stampa_R(pr);
    jump_to_line(pr, _PaginaPosizionamento ? 48-skip : 48);	  
	  stampa_S(pr);
    jump_to_line(pr, _PaginaPosizionamento ? 56-skip : 56);	  
	  stampa_T(pr);        
    jump_to_line(pr, _PaginaPosizionamento ? 63-skip : 63);	  
	  stampa_fine(pr);
	  _PaginaPosizionamento=FALSE;
	  next_page(pr);           
    pr.formlen(TDicForm::dic_form_len());	  
	  ++(*cur);
	  done = cur->pos() >= cur->items()-1;
  }
  close_print();
  return TRUE;
}

bool TStampaQuadroAggN::user_create()
{   
  _form = new TQuadroN("77QN", quadro());
  _form->set_cursor(_form->TForm::cursor());
  _cur = _form->cursor();
  return TRUE;  
}

bool TStampaQuadroAggN::user_destroy()
{
  delete _form;
  return TRUE;
}

