#ifndef __CG2102_H
#define __CG2102_H

#ifndef __RELAPP_H
#include <relapp.h>
#endif

#ifndef __PAGAMENT_H
#include "pagament.h"
#endif

#ifndef __SALDACON_H
#include "saldacon.h"
#endif

#ifndef __CGLIB_H
#include "cglib.h"
#endif

#ifndef __CG2101_H
#include "cg2101.h"
#endif

#ifndef __CG2103_H
#include "cg2103.h"
#endif

class TPrimanota_application : public TRelation_application
{                    
  TArray _file;               // Tutti i fiels da usare
  TMovimentoPN* _rel;         // Relazione principale

  TPagamento*   _pag;
  
  TCausale* _causale;         // Causale corrente
  TLibro_giornale* _giornale; // Libro giornale corrente
  TipoIVA _iva;               // Tipo di IVA corrente
  bool _ges_val, _ges_sal;    // Gestione valuta e saldaconto
  bool _num_cli, _num_for;    // Riferimento partita allineato a destra
  bool _npart_is_prot;        // Riferimento partita = n. prot. IVA anziche' doc
  
  bool _skip_giornale_check;  // Ignora controllo data stampa libro giornale
  bool _skip_bollato_check;   // Ignora controllo data stampa bollato
  
  bool _savenew;              // Registra e nuovo
  short _firstfocus;          // Primo campo della maschera a prendere il focus
  
  bool _sheet_shown;          // Lo sheet e' gia' stato visualizzato una volta?

  bool  _is_saldaconto;       // saldaconto si/no (vede parametri e causale)
  
  TSaldo_agg _saldi;          // Saldi da aggiornare
  TPartite_array _partite;    // Partite coinvolte

  TMask* _msk[4];             // Maschere di query, cg, iva, occasionali
  long _lastreg;              // Numero ultima registrazione
  int _mode;                  // Modo maschera corrente
  
  TDate _last_dreg;           // Ultima data registrazione inserita
  TDate _last_dcom;           // Ultima data competenza inserita
  
  TBill _conto_ricavo;        // Conto di ricavo del clifo
  
  TToken_string _tmp;         // Stringa temporanea da ritornare
  TString_array _pag_rows;    // Copia dello sheet delle rate
  
  TEsercizi_contabili _esercizi; // Tabella degli esercizi contabili
  
  static bool showpartite_handler(TMask_field& f, KEY k);
  static bool speserimb_handler(TMask_field& f, KEY k);
  static bool altrespese_handler(TMask_field& f, KEY k);
  static bool abbatt_handler(TMask_field& f, KEY k);
  static bool abbpass_handler(TMask_field& f, KEY k);
  static bool ritprof_handler(TMask_field& f, KEY k);
  static bool diffcamb_handler(TMask_field& f, KEY k);
  static bool suspended_handler(TMask_field& f, KEY k);
  static bool num_handler(TMask_field& f, KEY key);
  static bool caus_query_handler(TMask_field& f, KEY key);
  static bool caus_modify_handler(TMask_field& f, KEY key);
  static bool datareg_handler(TMask_field& f, KEY key);
  static bool datacomp_handler(TMask_field& f, KEY key);
  static bool data74ter_handler(TMask_field& f, KEY key);
  static bool doc_handler(TMask_field& f, KEY key);
  static bool numrif_handler(TMask_field& f, KEY key);
  static bool protiva_handler(TMask_field& f, KEY key);
  static bool clifo_handler(TMask_field& f, KEY key);
  static bool totdoc_handler(TMask_field& f, KEY key);
  static bool totdocval_handler(TMask_field& f, KEY key);
  static bool ritfis_handler(TMask_field& f, KEY key);
  static bool ritsoc_handler(TMask_field& f, KEY key);
  static bool main_codiva_handler(TMask_field& f, KEY key);
  static bool corrlire_handler(TMask_field& f, KEY key);
  static bool corrvaluta_handler(TMask_field& f, KEY key);
  static bool occas_code_handler(TMask_field& f, KEY key);
  static bool occas_handler(TMask_field& f, KEY key);
  static bool solaiva_handler(TMask_field& f, KEY key);
  static bool descr_handler(TMask_field& f, KEY k);
  
  static bool sheet_clifo_handler(TMask_field& f, KEY k);
  static bool iva_sottoconto_handler(TMask_field& f, KEY k);
  static bool imponibile_handler(TMask_field& f, KEY key);
  static bool detrazione_handler(TMask_field& f, KEY key);
  static bool codiva_handler(TMask_field& f, KEY key);
  static bool imposta_handler(TMask_field& f, KEY key);
  static bool dareavere_handler(TMask_field& f, KEY k);
  static bool cg_conto_handler(TMask_field& f, KEY key);
  static bool codpag_handler(TMask_field& f, KEY key);
  static bool cambio_handler(TMask_field& f, KEY key);
  static bool reset_handler(TMask_field& f, KEY key);
  static bool nrate_handler(TMask_field& f, KEY key);
  static bool recalc_handler(TMask_field& f, KEY key);
  static bool codcab_handler(TMask_field& f, KEY key);

  static bool iva_notify(TSheet_field& s, int r, KEY key);
  static bool iva_handler(TMask_field& f, KEY key);
  static bool cg_notify(TSheet_field& s, int r, KEY key);
  static bool cg_handler(TMask_field& f, KEY key);
  
  static bool pag_notify(TSheet_field& s, int r, KEY key);
  static bool pag_sheet_handler(TMask_field& f, KEY key);

  void reset_sheet_row(TSheet_field& s, int n);
  int crea_somma_spese(TImporto& imp);

protected:                              // TApplication
  virtual void on_firm_change();
  virtual void on_config_change();
  virtual void print();

protected:                              // TRelation_application
  virtual bool user_create();
  virtual bool user_destroy();
  virtual bool changing_mask(int mode);
  virtual TMask* get_mask(int mode);
  virtual TRelation* get_relation() const { return _rel; }
  virtual void init_query_mode(TMask& m);
  virtual void init_insert_mode(TMask& m);
  virtual void init_modify_mode(TMask& m);
  virtual bool save_and_new() const;
  virtual const char* get_next_key();
  virtual int read(TMask& m);
  virtual int write(const TMask& m);
  virtual int rewrite(const TMask& m);
  virtual bool remove();
  virtual void write_enable(bool) {}

protected:
  void check_saldi();
  void genera_incasso(const char* causimm);
  
  TMask* load_mask(int n);
  TMask& occas_mask() { return *load_mask(3); }
  void open_files(int logicnum, ...);
  void close_files() { _file.destroy(); }
  
  void mask2rel(const TMask& m);

  TipoIVA iva() const { return _iva; }
  char clifo() const { return iva() == iva_vendite ? 'C' : 'F'; }
  bool gestione_valuta() const { return _ges_val; }
  bool gestione_saldaconto() const { return _ges_sal; }
  bool npart_is_prot()        { return _npart_is_prot; }

  bool is_saldaconto() const  { return _is_saldaconto; }
  bool is_fattura() const { return gestione_saldaconto() && causale().tipomov() == 1; }
  bool is_nota_credito() const { return gestione_saldaconto() && causale().tipomov() == 2; }
  bool is_pagamento() const { return gestione_saldaconto() && causale().tipomov() >= 3; }

  void fill_sheet(TMask& m) const;
  void init_mask(TMask& m);
  
  static TipoIVA reg2IVA(const char* registro, int anno);
  static int type2pos(char tipo);
  static const real& cod2IVA(const TMask& m);
  static real scorpora(real& imponibile, const real& percentuale);
  static bool detraibile(TToken_string& row);
  static int bill2pos(const TBill& conto, char tipo);

  TipoIVA cau2IVA(const char* causale, int anno);
  bool IVA2bill(const TCodiceIVA& iva, TBill& bill);
  int bill2contr(const TBill& c, char sezione) const;
  int bill_used(const TBill& conto) const;
  TBill& ivas_bill(TBill& tc);
  
  bool read_caus(const char* cod, int year);                                                  
  TLibro_giornale& giornale() { return *_giornale; }

  bool test_swap(bool ritsoc);
  TImporto real2imp(const real& r, char tipo);
  real totale_documento();
  
  void ivas_pack();
  void cgs_pack();
  bool ci_sono_importi() const;
  real calcola_saldo() const;
  real calcola_imp() const;

  void add_cgs_tot(TMask& m);
  int set_cgs_row(int n, const TImporto& importo, TBill& conto, const char* desc, char tipo);
  void set_cgs_imp(int n, const TImporto& importo);
  bool add_cgs_imp(int n, const TImporto& importo);
  bool sub_cgs_imp(int n, const TImporto& importo);
  void disable_cgs_cells(int n, char tipo);      

  void add_cgs_rit(bool fisc);        
  void generazione_righe_cg(int r);
  
  void reset_cgs_row(int n)  { reset_sheet_row(cgs(), n); }
  void reset_ivas_row(int n) { reset_sheet_row(ivas(), n); }
  
  TPagamento& pagamento() const;

  void set_pagamento(const char* c, const char* d);
  void reset_pagamento(TMask& m);
  void set_scadenze(TMask& m);
  bool read_scadenze(TMask& m);
  void write_scadenze(const TMask& m);
  void remove_scadenze(const TMask& m, const char* rif);
  void renumber_partita(TMask& m, const char* oldp, const char* newp);
  void recalc_scadenze(const TDate& d);
  
  bool edit_partite(const TMask& m, int riga);

  bool notify_cgline_deletion(TPartita& partita, long nreg, int numrig);
  bool notify_cgline_deletion(int numrig);
  
  bool is_percipient(long forn, char& tipper, long& codper) const;
  long calcola_m770(int tipo_coll, real& spese, real& compenso, real& iva, real& ritfis);
  bool link_m770();                                 

public:               
  static char row_type(const TToken_string& s);

  TCausale& causale() const { return *_causale; }
  TPartite_array& partite() { return _partite; }   // Partite editate
  bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp);
  bool notify_edit_pagamento(TPartita& partita, TRectype& new_pag, 
                             const TValuta& valuta, int deleting = 0);

  TSheet_field& cgs() const;
  TSheet_field& ivas() const;
  TSheet_field& pags() const;
  TString_array& pag_rows() { return _pag_rows; }
  TImporto get_cgs_imp(int n);

  TPrimanota_application();
};

inline TPrimanota_application& app() 
{ return (TPrimanota_application&)main_app(); }          

#endif
