// quadn_t.cpp
#include <relapp.h>
#include <config.h>

#include "774200.h"
#include "77lib.h"   
#include "quadron.h"
#include "77qn.h"
#include "77qq.h"
#include "77qp.h"

#define CODDITTA77  181
#define ANNODIC77 182

class TQuadriNT_app : public TRelation_application
{
  static bool nprog_handler     (TMask_field& m, KEY k);
  static bool anno_handler      (TMask_field& m, KEY k);
  static bool mese_handler      (TMask_field& f, KEY k);
  static bool codreg_handler    (TMask_field& f, KEY k);
  static bool codtrib_handler   (TMask_field& f, KEY k);
  static bool tipo              (TMask_field& f , KEY k);
  static bool luogo             (TMask_field& f , KEY k);
  TString16   _maskname;
  int           _num;
  int     _pos_quadro;  // posizione nell'array dei quadri. Usato in set_comp
  TString16     _quadro;
  TRiporti      _rip;
  TRelation*    _rel;
  TMask*        _msk;
  bool          _registra;
  int     _anno_dic;
  bool      _MaskConAnnoDic, _MaskConCodditta;
  bool      MaskConAnnoDic() const;
  bool      MaskConCodditta() const { return _MaskConCodditta; }
  void      LeggiMask();
  bool      EsisteUnRec();
  bool      QuadroNoR() const { return _num == LF_QUAN || _num == LF_QUAR; }
  bool      QuadroPoS() const { return _num == LF_QUAP || _num == LF_QUAS; }
  bool      QuadroQoT() const { return _num == LF_QUAQ || _num == LF_QUAT; }
  bool      CheckImporti(const TMask& m); 
  long      Get_newprog();
  long      _codditta; 
  
protected:
  virtual bool user_create();
  virtual bool user_destroy();                  
  virtual int  rewrite(const TMask& m);
  virtual int  write  (const TMask& m);  
  virtual bool remove();                     
  virtual void on_config_change();
  virtual TMask* get_mask(int) { return _msk; }
  virtual bool changing_mask(int) { return FALSE;}
  virtual TRelation* get_relation() const { return _rel; }  
  virtual void init_mask(TMask&);
  virtual void init_query_mode(TMask&);
  virtual void init_insert_mode(TMask&);
  virtual void init_query_insert_mode(TMask&);

  void set_data_cong(const TMask& m);

public:                                                                     
  TQuadriNT_app(char quadro);
  virtual ~TQuadriNT_app() { }
};

TQuadriNT_app::TQuadriNT_app(char quadro)
: _MaskConCodditta(FALSE), _MaskConAnnoDic(FALSE), _msk(NULL), _rel(NULL)
{ 
  _quadro << quadro;

  _maskname << "77q" << quadro; 
  _maskname.lower();
  
  switch (quadro)
  {
    case 'N': _num = LF_QUAN; _pos_quadro = N; break;
    case 'P': _num = LF_QUAP; _pos_quadro = P; break;
    case 'Q': _num = LF_QUAQ; _pos_quadro = Q; break;
    case 'R': _num = LF_QUAR; _pos_quadro = R; break;
    case 'S': _num = LF_QUAS; _pos_quadro = S; break;
    case 'T': _num = LF_QUAT; _pos_quadro = T; break;
    default : fatal_box("Codice quadro errato"); break;  
  }
}

TQuadriNT_app& app() { return (TQuadriNT_app&)main_app(); }

void TQuadriNT_app::LeggiMask()
{
  _MaskConAnnoDic  = _msk->id2pos(ANNODIC77) > 0;
  _MaskConCodditta = _msk->id2pos(CODDITTA77) > 0;
}                  

bool TQuadriNT_app::MaskConAnnoDic() const
{
  return  _MaskConAnnoDic;
}

void TQuadriNT_app::on_config_change()
{
  TConfig conf(CONFIG_STUDIO);
  _anno_dic = (int)conf.get_long(ANNO_SEL, NULL, -1, TDate(TODAY).year());
}
                                    
bool TQuadriNT_app::user_create()
{           
  _msk = new TMask(_maskname);
  _rel = new TRelation(_num);
  _codditta = get_firm_770();  
  _msk->set_handler(QNF_NPROG,  nprog_handler);       
  _msk->field(CODDITTA77).set(_codditta);  
  
  if (QuadroNoR())
  {
    _msk->set_handler(QNF_ANNORIF, anno_handler);    
    _msk->set_handler(QNF_MESERIF, mese_handler);    
  }
    
  if (QuadroQoT())
  {
    _msk->set_handler(QNF_ANNORIF, anno_handler);    
    _msk->set_handler(QNF_MESERIF, mese_handler);    
    _msk->set_handler(QQF_CODREG, codreg_handler);    
  }
    
  if (QuadroPoS())
    _msk->set_handler(QPF_CODTRIB, codtrib_handler);
    
  _registra = FALSE;
  set_search_field(QNF_NPROG);

  return TRUE;
}

bool TQuadriNT_app::EsisteUnRec()
{
  TLocalisamfile qn(_num);
  qn.put(QN_CODDITTA, _codditta);
  int err = qn.read(_isgteq);
  bool yes = err == NOERR && qn.get_long(QN_CODDITTA) == _codditta;
  return yes;
}

bool TQuadriNT_app::user_destroy()
{  
  if (_quadro != "")
    if (_registra)
      _rip.set_compilato(_codditta, _pos_quadro, EsisteUnRec());
  delete _msk;
  delete _rel;
  return TRUE;
}                         

// Controlla che ci siano o l'imposta o i compensi
// NB che siano uguali QNF_IMPOSTA anche nei corrispondenti campi dei
// quadri Q, R e T (107 e 106)
bool TQuadriNT_app::CheckImporti(const TMask& m)
{
  const real impost(m.get(QNF_IMPOSTA));  
  const real compen(m.get(QNF_COMPENSI));  
  return impost != 0.0 || compen  != 0.0;
}

void TQuadriNT_app::set_data_cong(const TMask& m)
{
  const char q = _quadro[0];
  if (q == 'P' || q == 'S')
  {
    const int mese = m.get_int(QPF_MESECON);
    ((TMask&)m).set(QPF_DATACON, TDate(1, mese, q == 'P' ? 1996 : 1997));
  }  
}

int TQuadriNT_app::rewrite(const TMask& m)
{
  set_data_cong(m);
  const int err = TRelation_application::rewrite(m);
  _registra = err == NOERR;
  return err;
}

int TQuadriNT_app::write(const TMask& m)
{                         
  set_data_cong(m);
  const int err = TRelation_application::write(m);
  _registra = err == NOERR;
  return err;
}

bool TQuadriNT_app::remove()
{
  const bool ok = TRelation_application::remove();
  _registra = ok;
  return ok;
}

void TQuadriNT_app::init_mask(TMask& m)
{
  m.set(ANNODIC77, _anno_dic); 
}

void TQuadriNT_app::init_query_mode(TMask& m)
{                   
  init_mask(m);
}

void TQuadriNT_app::init_insert_mode(TMask& m)
{                   
  init_mask(m);   
}

void TQuadriNT_app::init_query_insert_mode(TMask& m)
{
  init_insert_mode(m);
  m.set(QNF_NPROG, Get_newprog());    
  m.send_key(K_TAB,QNF_NPROG);
}


///////////////////////////////////////////////////////////
// 2 modi :
//  RUN,773,-1,771230m,89,"Prospetto del Quadro E1","E1"    [771230i.uml]
// oppure
//  773 -1 menu_st "Stampe dichiarazioni" [prassi.mnu]
// QUADRO N:
// 773,-2,77qn,72,"Quadro N","N"
///////////////////////////////////////////////////////////
int quadriN_T(int argc, char* argv[])
{                
  TApplication::check_parameters(argc, argv);

  char quadro = 'N';
  if (argc > 5) 
    quadro = toupper(*argv[5]);
  else
    quadro = toupper(*argv[2]);
  
  TString16 title;  
  title << "Quadro " << quadro;
  
  TQuadriNT_app a(quadro);
  a.run(argc, argv, title);
  return 0;
}

bool TQuadriNT_app::anno_handler(TMask_field& f, KEY k)
{
  TMask& m = f.mask();
  if (k == K_ENTER && (modifica(m) || inserimento(m)) )
  {
    TString dep(f.get());
    if (dep.empty())
      return f.warning_box("Manca l'anno");
    else
      if (!app().CheckImporti(m))
        return f.warning_box("Manca almeno un importo");
  }
  return TRUE;
}

bool TQuadriNT_app::mese_handler(TMask_field& f, KEY k)
{
  TMask& m = f.mask();
  if (k == K_ENTER && (modifica(m) || inserimento(m)) )
  {
    TString dep(f.get());
    if (dep.empty())
      return f.warning_box("Manca il mese");
  }
  return TRUE;
}

// Per i Quadri Q e T
bool TQuadriNT_app::codreg_handler(TMask_field& f, KEY k)
{
  TMask& m = f.mask();
  if (k == K_ENTER && (modifica(m) || inserimento(m)) )
  {
    TString dep(f.get());
    if (dep.empty())
      return f.warning_box("Manca il codice regione");
  }
  return TRUE;
}

// Per i Quadri P e S. Codice tributo REQUIRED 
bool TQuadriNT_app::codtrib_handler(TMask_field& f, KEY k)
{
  TMask& m = f.mask();
  if (k == K_ENTER && (modifica(m) || inserimento(m)) )
  {
    TString dep(f.get());
    if (dep.empty())
      return f.warning_box("Manca il codice tributo");
  }
  return TRUE;
}

bool TQuadriNT_app::nprog_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB)    
    f.set_dirty();
  return TRUE;                   
}   

// ritorna nuovo progressivo da utilizzare 
long TQuadriNT_app::Get_newprog()
{                      
  long nprog = 0L;              
  TLocalisamfile qnr(_num);
  qnr.zero();
  qnr.put(QN_CODDITTA, _codditta);
  TRectype dep(qnr.curr());
  for (qnr.read(_isgteq); !qnr.eof(); qnr.next())
  {
    if (qnr.curr() > dep) break;
    nprog = qnr.get_long(QN_NPROG);
  }
  return ++nprog; 
}
 
bool TQuadriNT_app::tipo(TMask_field& f , KEY k)
{
/*
  if (k == K_SPACE)
  {
    char tipo  = f.mask().get(F_QLTIPOVERS)[0];
    char luogo = f.mask().get(F_QLLUOVERS)[0];
    
    if (tipo == 'D' && luogo == 'T')
      f.mask().hide(F_QLSERIE);
    else
      f.mask().show(F_QLSERIE);
  }
*/
  return TRUE;
}

bool TQuadriNT_app::luogo(TMask_field& f , KEY k)
{
/*  
  if (k == K_SPACE)
  {
    char tipo  = f.mask().get(F_QLTIPOVERS)[0];
    char luogo = f.mask().get(F_QLLUOVERS)[0];
    
    if (tipo == 'D' && luogo == 'T')
      f.mask().hide(F_QLSERIE);
    else
      f.mask().show(F_QLSERIE);  
  }           
  */
  return TRUE;
}