// 771300.cpp  - Gestione quadro I e Prospetto dati generali
//
// 771mod -2 I		 - quadro I
// 771mod -2 W		 - prospetto dati generali
// 771mod -2 1		 - quadro I dichiarante
// 771mod -2 2		 - prospetto dati generali dichiarante
//
// 18.3.96	Aggiunto metodo per registrare flag in QCOMP
//          NB se cambia numero quadri, modificare set_rel_field_quadri
//
#include <relapp.h>
#include <urldefid.h>

#include "771300.h" 
#include "77lib.h" 
#include "774200.h"

HIDDEN const int QUADRI = 29;
// Corrispondenza tra posizione nel record (campo:QCOMP) e id della maschera
HIDDEN int _dlg_comp_array[QUADRI] = {
    F_QCOMPA,
    F_QCOMPA1,
    F_QCOMPA2,
    F_QCOMPA3,
    F_QCOMPB,
    F_QCOMPB1,
    F_QCOMPC, 
    F_QCOMPD, 
    F_QCOMPD1,
    F_QCOMPE, 
    F_QCOMPE1,
    F_QCOMPE2,
    F_QCOMPF, 
    F_QCOMPF1,
    F_QCOMPF2,
    F_QCOMPG, 
    F_QCOMPG1,
    F_QCOMPH, 
    F_QCOMPI, 
    F_QCOMPL,
    F_QCOMPN,
    F_QCOMPP,
    F_QCOMPQ,
    F_QCOMPR,
    F_QCOMPS,
    F_QCOMPT, 
    F_QCOMPAB,
    F_QCOMPDB,
    F_QCOMPU    
  };

// Da id della maschera ritorna la corrispondente posizione in QCOMP
// Ritorna -1 se viene passato un id che non esiste in _dlg_array
HIDDEN int dlg2pos(const int dlg)
{
  for (int i=0; i < QUADRI; i++)
    if (_dlg_comp_array[i] == dlg)
      return i;
  return -1;
}
    
class TQuadroI : public TRelation_application
{
    TRelation	* _rel;
    TMask     * _msk; 
    char      _quadro;
    bool      _registra;
    TRiporti  _rip; 
     
  protected:
    static	bool	PDGcalcolaM6(TMask_field& f, KEY k);
    virtual bool 		user_create();
    virtual bool 		user_destroy();
    virtual TRelation*	get_relation() const { return _rel; }
    virtual TMask*		get_mask(int mode);
    virtual bool		changing_mask(int mode) {return FALSE; }
    virtual int			read(TMask& m);
    virtual void		init_query_mode(TMask&);
    virtual void		init_modify_mode(TMask&);
    virtual int 		write(const TMask& m);
    virtual int 		rewrite(const TMask& m);
  public:                                       
    void set_field_quadri(TMask& m);        
    void set_rel_field_quadri(const TMask& m);        
    void setta_ditta(TMask& m);
    TQuadroI(char q) : _quadro(q) {}
};                     

HIDDEN TQuadroI& app() { return (TQuadroI&) main_app(); }

void TQuadroI::setta_ditta(TMask& m)
{
  TString16 codditta; codditta << get_firm_770();
  if (codditta != "0")        
  {
    m.set(F_CODDITTA, codditta);
    m.field(F_CODDITTA).check();
  }
}  
               
void TQuadroI::init_query_mode(TMask& m)
{
  setta_ditta(m);
  m.send_key(K_AUTO_ENTER,0);
}

void TQuadroI::init_modify_mode(TMask& m)
{
  setta_ditta(m);
  _msk->disable(DLG_DELREC);

  if (_quadro == 'W' || _quadro == '2')
  {
    TConfig conf(CONFIG_STUDIO);
    int anno = (int) conf.get_long(ANNO_SEL);
    m.set(F_ANNODIC, anno);
  }
}
        
// Scrive i flag di q.comp. nella relazione
void TQuadroI::set_rel_field_quadri(const TMask& m)
{   
  int   dlg, pos;

// NB Cambiare qui se cambia numero quadri
  TString qcomp(QUADRI);
  qcomp.spaces(QUADRI);
    
  for (dlg=F_QCOMPA; dlg<=F_QCOMPL; dlg++)    
  {
    pos = dlg2pos(dlg);
    if (pos >= 0)    
      qcomp[pos] = m.get(dlg) == "X" ? 'X' : ' ';
  }           
  _rel->curr().put("QCOMP", qcomp);

// Stessa cosa con flag quadri inviati
  TString qsuppinv (QUADRI);  
  qsuppinv.spaces(QUADRI);
  
  for (pos=0, dlg=F_QSUPPA; dlg<=F_QSUPPU; dlg++, pos++)    
  {
    qsuppinv[pos] = m.get(dlg) == "X" ? 'X' : ' ';
  }
  _rel->curr().put("QSUPPINV", qsuppinv);
}

void TQuadroI::set_field_quadri(TMask& m)
{   
  int   start_dlg   = F_QCOMPA;
  int   dlg;
  TString qcomp (_rel->lfile().get("QCOMP"));
  
  if (qcomp != "")
  {  
    int lenght = qcomp.len();
    for (int i = 0; i < lenght; i++)
    { 
        if (qcomp[i] == 'X')
        {
          dlg = _dlg_comp_array[i];
          m.set(dlg, "X");
        }
    }
  }  

  TString suppinv (_rel->lfile().get("QSUPPINV"));
  
  start_dlg = F_QSUPPA;
  
  if (suppinv != "")
  {  
    int lenght = suppinv.len();
    for (int i = 0; i < lenght; i++)
      if (suppinv[i] == 'X')
      {
        dlg = start_dlg + i;
        m.set(dlg, "X");
      }
  }  
}

TMask* TQuadroI::get_mask(int mode)
{
  return _msk;
}
                                              
int TQuadroI::read(TMask& m)
{
  m.autoload(*_rel);
// Si posiziona sul record del dichiarante, e se non esiste lo crea
  if (_quadro == '1' || _quadro == '2') 
  {
    TString16 dep; dep << COD_QUA_I_DIC;
    m.set(F_TIPOQUA1, dep); 
    if (_quadro == '1')
      m.set(F_TIPOQUA2, dep);   
    _rel->curr().put("TIPOQUA", COD_QUA_I_DIC);
    const int err = _rel->read();
    if (err != NOERR)
      enter_dichiar_770(get_firm_770(), anno_770(), TRUE);

    m.autoload(*_rel);
  }

// Setta i flag di quadro compilato nel prospetto dai generali  
  if (_quadro == 'W' || _quadro == '2')
    set_field_quadri(m);
  
  return NOERR;
}

bool TQuadroI::PDGcalcolaM6(TMask_field& f, KEY k)
{
  if (k == K_TAB)
  {
    TMask& m = f.mask();
    real m3 = m.get_real(F_M3);
    real m4 = m.get_real(F_M4);
    real m5 = m.get_real(F_M5);    
    real m6 = m3 - m4 - m5;
    if (m6 < ZERO)
      m6 = ZERO;
    TString m6s(m6.string());
    m.set(F_M6, m6s);
  }
  return TRUE;
}

bool TQuadroI::user_create()
{ 
  _registra = FALSE;
  
  switch (_quadro)
  {
    case '1':
      _rel = new TRelation (LF_BASE);
      _rel->add(LF_BASEBIS,"TIPOQUA=\"D\"&&CODDITTA=CODDITTA",1);
      _msk = new TMask("771300a");  
      _msk->disable(DLG_NEWREC);
      _msk->disable(DLG_DELREC);
      _msk->disable(DLG_FINDREC);
      break;    
    case 'I':    
      _rel = new TRelation (LF_BASE);
      _rel->add(LF_BASEBIS,"CODDITTA=CODDITTA",1);
      _msk = new TMask("771300a");   
      _msk->disable(DLG_NEWREC);
      _msk->disable(DLG_DELREC);
      _msk->disable(DLG_FINDREC);
      break;    
    case 'W':                               
      _rel = new TRelation (LF_BASEBIS);          
      _rel->add(LF_BASE,"CODDITTA=CODDITTA",1);
      _msk = new TMask("771400a"); 
      _msk->disable(DLG_NEWREC);
      _msk->disable(DLG_DELREC);
      _msk->disable(DLG_FINDREC);   
      _msk->set_handler(F_M3, PDGcalcolaM6);
      _msk->set_handler(F_M4, PDGcalcolaM6);
      _msk->set_handler(F_M5, PDGcalcolaM6);
      // set numero quadri L aggiuntivi
      _msk->set(F_QLAGG,num_quadri_L_agg(get_firm_770()));
      // set numero quadri N,P,Q,R,S,T aggiuntivi
      _msk->set(F_QNAGG,num_quadri_N_agg(get_firm_770()));
      break;
    case '2':                     
      _rel = new TRelation (LF_BASEBIS);                         
      _rel->add(LF_BASE,"TIPOQUA=\"D\"&&CODDITTA=CODDITTA",1);
      _msk = new TMask("771400b");
      _msk->disable(DLG_NEWREC);
      _msk->disable(DLG_DELREC);
      _msk->disable(DLG_FINDREC);   
      // set numero quadri L aggiuntivi
      _msk->set(F_QLAGG,num_quadri_L_agg(get_firm_770()));
      // set numero quadri N,P,Q,R,S,T aggiuntivi
      _msk->set(F_QNAGG,num_quadri_N_agg(get_firm_770()));
      break;
    default:
      break;
  }
  return TRUE;
}

bool TQuadroI::user_destroy()
{                 
	if (_quadro  == 'I' && _registra)
		_rip.set("I");
		
  delete _msk;
  delete _rel;            
  return TRUE;
}

int TQuadroI::write(const TMask& m)
{
  _registra = TRUE;
  TRelation *r = get_relation();
  m.autosave(*r);
// Setta i flag di quadro compilato nel prospetto dai generali nella relazione
  if (_quadro == 'W' || _quadro == '2')
    set_rel_field_quadri(m);
  r->write();    
  return r->status();
}


int TQuadroI::rewrite(const TMask& m)
{
  _registra = TRUE;
  TRelation *r = get_relation();
  m.autosave(*r);
// Setta i flag di quadro compilato nel prospetto dai generali  nella relazione
  if (_quadro == 'W' || _quadro == '2')
    set_rel_field_quadri(m);
  r->rewrite();
  return r->status();
}

int m71300(int argc, char* argv[])
{
  if (argc < 3) 
    return -1;

  char* title = NULL;
  char quadro = toupper(*argv[2]);
  TQuadroI a (quadro);  
  
  switch (quadro)
  {
    case 'I':    
    case '1':    
      title = "Quadro I";
      break;
    case 'W':
    case '2':
      title = "Prospetto dati generali";
      break;
    default:
      break;
  }

  a.run(argc, argv, title);
  return 0;
}