///////////////////////////////////////////////////////////
// Quadro 770/A
///////////////////////////////////////////////////////////

#include "77stqab.h" 

TDipendente::TDipendente(const TCursor& cur)
{                   
  _pos = ((TCursor&)cur).pos();
  
  const TRectype& rec = cur.curr();
  const TRectype& dip = cur.curr(LF_DIPEND);

  _codice_ditta      = rec.get_long("CODDITTA");
  _ragsoc            = dip.get("COGNOME"); _ragsoc << ' ' << dip.get("NOME");
  _codice_deceduto   = dip.get_long("CODDIPDEC");
  _codice_dipendente = rec.get_long("CODDIP");
  
  if (rec.num() == LF_QUAA)
  {
    _fine_rapporto        = rec.get("DATAFR");
    _lavoro_precedente    = rec.get("CFDLPREC").not_empty();
    _causa                = toupper(rec.get_char("CAUSA"));
    _rettifica_conguaglio = toupper(rec.get_char("RETCON"));
    _numero_progressivo   = rec.get_int("NPROG");
  }  
  else
  {
    _fine_rapporto        = rec.get("DATAFIN");
    _lavoro_precedente    = FALSE;
    _causa                = ' ';
    _rettifica_conguaglio = ' ';
    _numero_progressivo   = rec.get_int("NPROG");
  } 
  
  if (_rettifica_conguaglio == 'B' || !_fine_rapporto.ok())
    _fine_rapporto = eotime;
}

int TDipendente::compare(const TSortable& s) const
{
  const TDipendente& rec = (const TDipendente&)s;
  
  if (_codice_ditta != rec._codice_ditta)
    return _codice_ditta > rec._codice_ditta ? +1 : -1;

  const int diff = _ragsoc.compare(rec._ragsoc, -1, TRUE);
  if (diff != 0)
    return diff;
    
  if (_codice_dipendente != rec._codice_dipendente)  
    return _codice_dipendente > rec._codice_dipendente ? +1 : -1;
    
  if (_fine_rapporto != rec._fine_rapporto)                      
    return _fine_rapporto > rec._fine_rapporto ? +1 : -1;
    
  if (_lavoro_precedente != rec._lavoro_precedente)  
    return _lavoro_precedente ? +1 : -1;
    
  if (_causa != rec._causa)  
    return _causa > rec._causa ? +1 : -1;
    
  if (_rettifica_conguaglio != rec._rettifica_conguaglio)  
    return _rettifica_conguaglio > rec._rettifica_conguaglio ? +1 : -1;
                                                                       
  return _numero_progressivo - rec._numero_progressivo;                                                                     
}

int TDipendenti::find(long cod) const
{
  for (int i = _data.last(); i >= 0; i--)
    if (dip(i).codice() == cod)
      break;
  return i;    
}

int TDipendenti::fill(TCursor& cur)
{
  for (cur = 0; cur.ok(); ++cur)
  {
    TDipendente* n = new TDipendente(cur);
    if (n->pos() >= 0)
      _data.add(n);
    else
      delete n;  
  } 
  const int i = _data.items();
  if (i > 0)
  {
    _data.sort();
    for (int d = i-1; d >= 0; d--)
    {
      const long coddec = dip(d).codice_deceduto();
      if (coddec > 0)                     // E' un erede!
      {
        int posdec = find(coddec);
        if (posdec >= 0 && posdec != d-1) // Il deceduto esiste
        {
          TDipendente* dipen = (TDipendente*)_data.remove(d, TRUE);
          if (d < posdec)                 // Se l'erede precede il defunto ...
            posdec--;                     // ... il defunto avanza di un posto!
          dipen->reset_deceduto();        // Non e' piu' un erede
          _data.insert(dipen, posdec+1);  // Attaccalo dietro al deceduto
        }  
      }
    }
  }  
  return i;
}

void TQuadroA::azzera_totali() 
{ 
  TPrint_section& totali = section('F', last_page);
  totali.reset();                                   // Azzera le righe
  
  for (int i = totali.fields()-1; i >= 0; i--)
    totali.field(i).set("");                        // Azzera i campi
}

void TQuadroA::preprocess_corpo(const TRectype& rec)
{
  if (rec.num() == LF_QUAA)
  {
    const bool lav_prec = rec.get("CFDLPREC").not_empty();
    const char rett_con = toupper(rec.get_char("RETCON"));

    const bool add = !lav_prec && rett_con != 'B';
    enable_message_add(add);
    
    // Nasconde i dati anagrafici quando rett_con = B
    TPrint_section& body = section('B', odd_page);
    for (int i = 2; i <= 12; i++)
    {
      TForm_item& f = body.find_field(i);
      f.enable(rett_con != 'B');
    }
        
    // Stampa solo le date di fine rapporto del 95
    TForm_item& datafr = body.find_field(16);
    const TDate dfr = rec.get("DATAFR");
    datafr.enable(dfr.year() == 1995);
  }
}

void TQuadroA::stampa_corpo(TPrinter& pr)
{
  TPrint_section& body = section('B', odd_page);
  const int body_righe = body.height();  
  body.reset();
  body.update();       

  for (int i = 0; i < body_righe; i++)
  {
    pr.print(body.row(i));
    _RigaCorr++;
  }

  if (usa_progind())
    progind()->addstatus(1);
}


int TQuadroA::calcola_firma()
{
  TPrint_section& totali = section('F', last_page);
  TForm_item& signature = totali.find_field(2);
  const int y = signature.y()-1;
  
  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).reset();
  totali.row(y).put(cognome, signature.x()-1);
  
  return y;
}

void TQuadroA::stampa_totali(TPrinter& pr) 
{ 
  TPrint_section& totali = section('F', last_page);
  totali.update();

  const int lasty = calcola_firma();
  
  for (int i = 0; i <= lasty; i++)
  {
    pr.print(totali.row(i));
    _RigaCorr++;
  }
}

void TQuadroA::stampa_firma(TPrinter& pr) 
{ 
  TPrint_section& totali = section('F', last_page);
  totali.update();
  
  const int lasty = calcola_firma();
  
  TPrintrow empty;
  
  for (int i = 0; i <= lasty; i++)
  { 
    if (i < lasty)
      pr.print(empty);
    else  
      pr.print(totali.row(i));
    _RigaCorr++;
  }
}

void TQuadroA::next_page(TPrinter& pr)
{                       
  fill_page(pr, -1);   // formfeed "adattato"  
  inc_curr_page();
}

int TQuadroA::elementi_pagina(PaginaQuadro p) const
{ 
  const int n[4] = { 1, 3, 3, 2 };
  return n[p - PRIMA];
}

int TQuadroA::prima_riga(PaginaQuadro p) const
{
//  return p == PRIMA ? 45 : 5;  
  return p == PRIMA ? 45 : 6; 
}

int TQuadroA::riga_totali(PaginaQuadro p) const
{                                 
  const int h = ((TQuadroA*)this)->section('B', odd_page).height();
  return prima_riga(p) + elementi_pagina(p) * h;
} 

bool TQuadroA::init(long codditta)
{                            
  azzera_totali();
  return InitPrint(codditta);
}

bool TQuadroA::print(const long codditta, const long NumFis, const long NumNoFis)
{  
  TCursor& cur = *cursor();
  TPrinter& pr = printer();
    
  if (!init(codditta))
    return FALSE;
    
//  pr.formlen(QA_FORMLEN);             
  
  int elementi = 0;    // Numero di elementi stampati in questa pagina
  bool stampato_ultimo = FALSE;
  bool stampati_totali = FALSE;
  long persone = 0;
  int pos = 0;
  TDipendenti indice;
  if (quadro() == "A" || quadro() == "B")
  {                 
    persone = indice.fill(cur);
    if (persone > 0)
    {                     
      if (usa_progind()) 
        progind()->addstatus(cur.items()-persone);  // Segna come elaborati tutti gli ignorati
      
      cur = indice[0].pos();
    }  
    else
      return FALSE;  
  }         
  else
  {   
    persone = cur.items();
    cur = 0;
  }  
  while (!stampati_totali)
  {   
    bool stampero_ultimo = (stampato_ultimo == FALSE);
    if (stampero_ultimo)
    {
      if (indice.items() > 0)                          // Usa indice alternativo
        stampero_ultimo = (pos == persone-1);
      else                                             // Usa indice del cursore
        stampero_ultimo = (cur.pos() == persone-1);
    }                        

    if (!stampato_ultimo) 
      preprocess_corpo(cur.curr());
    
    switch(_PaginaCorrente)
    {                     
    case PRIMA: 
      pr.formlen(dic_form_len());

      if (_modulaser) 
        ClearFlagModulaser();
      
      if (elementi == 0)
      {
        stampa_testata(pr);
        if (PaginaPosizionamento())
          jump_to_line(pr, prima_riga(PRIMA));
        else                                   
          jump_to_line(pr, prima_riga(PRIMA)+HEADER_PRIMA_NOPOS);        
      }
      
      if (!stampato_ultimo)
      {
        stampa_corpo(pr);       
        stampato_ultimo = stampero_ultimo;
      }
      
      elementi++;
      if (elementi >= elementi_pagina(PRIMA))
      {
        next_page(pr);
        _PaginaPosizionamento=FALSE;
        elementi = 0;
      }  
      break;             
    case SECONDA:
    case TERZA:              
      if (!stampato_ultimo)
      {
        if (elementi == 0)
          jump_to_line(pr, prima_riga(_PaginaCorrente));      
        stampa_corpo(pr);       
        stampato_ultimo = stampero_ultimo;
      }
      elementi++;
      if (elementi >= elementi_pagina(_PaginaCorrente))
      {
        pr.formlen(dic_form_len());    
        next_page(pr);
        elementi = 0;
      }  
      break;
    case QUARTA:
      if (!stampato_ultimo)
      {
        if (elementi == 0)
          jump_to_line(pr, prima_riga(QUARTA));      
        stampa_corpo(pr);       
        stampato_ultimo = stampero_ultimo;
      }
      
      elementi++;
 
      if (elementi >= elementi_pagina(QUARTA))
      {                 
        jump_to_line(pr, riga_totali(QUARTA));
        if (stampato_ultimo)
        {
          stampa_totali(pr);         // Stampa totali e firma
          stampati_totali = TRUE;
        }  
        else
          stampa_firma(pr);          // Stampa solo la firma senza i totali

        // Usato per stampare la VK_ENDDOC in fill_page()
        _EndPrintDitta = TRUE;    
        pr.formlen(dic_form_len());              
        next_page(pr);
        elementi = 0;
      }
      break;
    default:
      CHECK(0, "Invalid Quadro A page");
      break;
    }
    
    if (!stampato_ultimo)
    {
      if (indice.items() > 0)
        cur = indice[++pos].pos();
      else
        ++cur;
    }
  }
  
  close_print();

  return TRUE;
}

bool TStampaQuadroA::user_create()
{
  _form = new TQuadroA("77QA", quadro());

  TString sortkey(80);
  sortkey.format("CODDITTA|%d->COGNOME|%d->NOME|CODDIP", LF_DIPEND, LF_DIPEND);
  _cur = new TSorted_cursor(_form->TForm::relation(), sortkey);
  
  return TRUE;
}

bool TStampaQuadroA::user_destroy()
{         
  if (_cur)
    delete _cur;       
  
  if (_form)
    delete _form;

  return TRUE;
}          

/////////////////////////////////////////////////////////////////////////////////
// Quadro A1
/////////////////////////////////////////////////////////////////////////////////

int TQuadroA1::elementi_pagina(PaginaQuadro p) const
{
  const int n[4] = { 3, 6, 6, 5 };
  return n[p-PRIMA];
}

int TQuadroA1::prima_riga(PaginaQuadro p) const
{                                
  return p == PRIMA ? 32 : 5; 
//  return p == PRIMA ? 32 : 4; 
}

long TQuadroA1::filtra(const long codditta)
{
  TString filtr(32); 
  filtr.format("(CODDITTA=%ld)&&(ANNORIF=1995)", codditta);

  cursor()->setfilter(filtr, TRUE);   
  const long items = cursor()->items();

  return items;
}      

void TQuadroA1::preprocess_corpo(const TRectype& rec)
{
  if (rec.num() == LF_QUAA1)
  {
    // Stampa solo le date di ricezione del 95
    const TDate dr = rec.get("DATARIC26");
    TForm_item& dataric = find_field('B', odd_page, 26);  
    dataric.enable(dr.year() == 1995);
  }
}  

bool TStampaQuadroA1::user_create()
{
  _form = new TQuadroA1("77QA1", quadro());
                                                                
  TString sortkey(80);
  sortkey.format("CODDITTA|%d->COGNOME|%d->NOME|CODDIP|MESERIF|NPROG", LF_DIPEND, LF_DIPEND);
  _cur = new TSorted_cursor(_form->TForm::relation(), sortkey);
  
  return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////
// Quadro A2
/////////////////////////////////////////////////////////////////////////////////

int TQuadroA2::elementi_pagina(PaginaQuadro p) const
{
  const int n[4] = { 3, 6, 6, 5 };
  return n[p-PRIMA];
}

int TQuadroA2::prima_riga(PaginaQuadro p) const
{
//  return p == PRIMA ? 32 : 4;  
  return p == PRIMA ? 32 : 5;   
}

void TQuadroA2::preprocess_corpo(const TRectype& rec)
{                     
  if (rec.num() == LF_QUAA2)
  {
    const char ret_con = toupper(rec.get_char("RETCON"));
    const bool add = ret_con != 'B';
    enable_message_add(add);
    
    // Nasconde i dati anagrafici quando rett_con = B
    TPrint_section& body = section('B', odd_page);
    for (int i = 2; i <= 7; i++)
    {
      TForm_item& f = body.find_field(i);
      f.enable(add);
    }
  }  
}

bool TStampaQuadroA2::user_create()
{
  _form = new TQuadroA2("77QA2", quadro());
                                                                
  TString sortkey(80);
  sortkey.format("CODDITTA|%d->COGNOME|%d->NOME|CODDIP|RETCON|NPROG", LF_DIPEND, LF_DIPEND);
  _cur = new TSorted_cursor(_form->TForm::relation(), sortkey);
  
  return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////
// Quadro A3
/////////////////////////////////////////////////////////////////////////////////

int TQuadroA3::elementi_pagina(PaginaQuadro p) const
{
  const int n[4] = { 6, 10, 10, 9 };
  return n[p-PRIMA];
}

int TQuadroA3::prima_riga(PaginaQuadro p) const
{
//  return p == PRIMA ? 32 : 4;  
  return p == PRIMA ? 32 : 5;   
}

bool TStampaQuadroA3::user_create()
{
  _form = new TQuadroA3("77QA3", quadro());
                                                                
  TString sortkey(80);
  sortkey.format("CODDITTA|NPROG|%d->COGNOME|%d->NOME|CODDIP", LF_DIPEND, LF_DIPEND);
  _cur = new TSorted_cursor(_form->TForm::relation(), sortkey);
  
  return TRUE;
}

/////////////////////////////////////////////////////////////////
//         QUADRO B
/////////////////////////////////////////////////////////////////

int TQuadroB::elementi_pagina(PaginaQuadro p) const
{
  const int n[4] = { 3, 5, 5, 3 };
  return n[p-PRIMA];
}

int TQuadroB::prima_riga(PaginaQuadro p) const
{
//  return p == PRIMA ? 32 : 6;  
  return p == PRIMA ? 32 : 7;   
}

bool TStampaQuadroB::user_create()
{
  _form = new TQuadroB("77QB", quadro());
                                                                
  TString sortkey(80);
  sortkey.format("CODDITTA|%d->COGNOME|%d->NOME|CODDIP|DATAINI|NPROG", LF_DIPEND, LF_DIPEND);
  _cur = new TSorted_cursor(_form->TForm::relation(), sortkey);
  
  return TRUE;
}

//////////////////////////////////////////////////////////////
//                QUADRO H
//////////////////////////////////////////////////////////////

long TQuadroH::filtra(const long codditta)
{
  TString filtr(32); 
  filtr.format("(CODDITTA=%ld)&&(H1ANNO=1995)", codditta);

  cursor()->setfilter(filtr, TRUE);   
  const long items = cursor()->items();

  return items;
}      


void TQuadroH::inc_curr_page()
{                      
  if (_PaginaCorrente == PRIMA)
    _PaginaCorrente = SECONDA;
  else
    _PaginaCorrente = PRIMA;
}

int TQuadroH::elementi_pagina(PaginaQuadro p) const
{
  return p == PRIMA ? 21 : 27;
}

int TQuadroH::prima_riga(PaginaQuadro p) const
{
//  return p == PRIMA ? 24 : 9;  
  return p == PRIMA ? 23 : 9;   
}

bool TQuadroH::print(const long codditta, const long NumFis, const long NumNoFis)
{ 
  TCursor& cur = *cursor();
  TPrinter& pr = printer();
    
  if (!InitPrint(codditta))
    return FALSE;
    
//  pr.formlen(QH_FORMLEN);             
  
  int elementi = 0;    // Numero di elementi stampati in questa pagina
  bool stampato_ultimo = FALSE;
  bool stampati_totali = FALSE;
  
  cur = 0;
    
  while (!stampati_totali)
  {   
    bool stampero_ultimo = stampato_ultimo == FALSE;
    if (stampero_ultimo)
        stampero_ultimo &= cur.pos() == cur.items()-1;
    
    switch(_PaginaCorrente)
    {                     
    case PRIMA: 
      pr.formlen(dic_form_len());
      
      if (_modulaser) 
        ClearFlagModulaser();
      
      if (elementi == 0)
      {
        stampa_testata(pr);
        if (PaginaPosizionamento())
          jump_to_line(pr, prima_riga(PRIMA));
        else                                   
          jump_to_line(pr, prima_riga(PRIMA)+HEADER_PRIMA_NOPOS);        
      }
      
      if (!stampato_ultimo)
      {
        stampa_corpo(pr);       
        stampato_ultimo = stampero_ultimo;
      }

      _EndPrintDitta=stampato_ultimo;
            
      elementi++;
      if (elementi >= elementi_pagina(PRIMA))
      {
        next_page(pr);
        _PaginaPosizionamento=FALSE;
        elementi = 0;
      }  
      break;             
    case SECONDA:                
      pr.formlen(dic_form_len());    
      if (!stampato_ultimo)
      {
        if (elementi == 0)
          jump_to_line(pr, prima_riga(SECONDA));      
  
        stampa_corpo(pr);       
        stampato_ultimo = stampero_ultimo;
      }
      _EndPrintDitta=stampato_ultimo;
            
      elementi++;
 
      if (elementi >= elementi_pagina(SECONDA))
      {                 
        if (stampato_ultimo)
        {
          jump_to_line(pr, riga_totali(SECONDA));
          stampa_totali(pr);
          stampati_totali = TRUE;
        }  
        else
          stampa_firma(pr);

        next_page(pr);
        elementi = 0;
      }
      break;
    default:
      CHECK(0, "Invalid Quadro H page");
      break;
    }
    
    if (!stampato_ultimo)
        ++cur;
  }
  
  close_print();

  return TRUE;
}

bool TStampaQuadroH::user_create()
{
  _form = new TQuadroH("77QH", quadro());
                                                                
  TString sortkey(80);
//  sortkey.format("CODDITTA|H1ANNO|H1ENTE"); 
  sortkey.format("CODDITTA|H1ENTE");    // Considera solo in 1995
  _cur = new TSorted_cursor(_form->TForm::relation(), sortkey);
  
  return TRUE;
}