#ifndef __ASSOC_H
#include <assoc.h>
#endif

#include "sconti.h"
#include "tclifor.h"
#include "velib01.h"
#include "..\cg\pagament.h"

struct dec_parm {
  int pri_lit,
      pri_val, 
      qta_lit, 
      qta_val,  // si lo so non ha senso, ma lo faccio lo stesso
      imp_lit, 
      imp_val;
      // add other groups here
};

class TCodice_numerazione : public TRectype
{
  int _status;
protected:
  int read(const char * cod);
public:
  TObject* dup() const { return new TCodice_numerazione(codice()); }

public:
  const TString& codice() const { return get("CODTAB"); }
  const TString& prefisso() const { return get("S6"); }
  const TString& postfisso() const { return get("S7"); }
  const bool manual_num() const { return get_bool("B0"); }
  const bool auto_num() const { return get_bool("B1"); }
  const TString& tipo_doc1() { return get("S2").mid(0,4);}
  const TString& tipo_doc2() { return get("S2").mid(4,4);}
  const TString& tipo_doc3() { return get("S2").mid(8,4);}
  const TString& tipo_doc4() { return get("S2").mid(12,4);}
  const TString& tipo_doc5() { return get("S2").mid(16,4);}
  
  const char * complete_num (long num);
  int status() { return _status; }
  TCodice_numerazione(const char* codnum = NULL);
  TCodice_numerazione(const TRectype& rec);
  virtual ~TCodice_numerazione();
};

//////////////////////////////////////////////////////////////////////////////////////////////
// classe TDocumentoEsteso: oggetto che ha come finalita' il calcolo dei riepiloghi IVA
//////////////////////////////////////////////////////////////////////////////////////////////

class TRiepilogo_Iva : public TObject
{
  real _imp;
  real _iva;
  real _ali;
  byte _tipo;
  TString16 _cod;
  TString   _des;
  
protected:
  
public:
  real& imp()    { return _imp;} // Imponibile
  real& iva()    { return _iva;} // Iva
  real& ali()    { return _ali;} // Aliquota
  TString& cod() { return _cod;} // Descrizione
  TString& des() { return _des;} // Descrizione
  byte&    tipo(){ return _tipo;}// Tipo (Vedi opzioni per la selzione di filtro nella validate())
  void     zero(){ _imp = 0.0; _iva = 0.0; _ali = 0.0; _tipo = 0; _cod = ""; _des = ""; }
  virtual TObject* dup() const { return new TRiepilogo_Iva(*this); }
  TRiepilogo_Iva& operator = (TRiepilogo_Iva& a);
  TRiepilogo_Iva() {_imp = 0.0; _iva = 0.0; _ali = 0.0; _tipo = 0;}  
  ~TRiepilogo_Iva() {};
};

class TDocumentoEsteso : public TDocumento
{ 
  // Parametri del documento
  dec_parm        _parm;          // Parametri per gli arrotondamenti
  TTable        * _iva;           // Tabella codici IVA
  
  // Totali del documento ricalcolati non appena la tabellina di riepilogo IVA e' completa
  real _importi_netti, _imposte;

  // membri per il calcolo del riepilogo IVA
  bool            _sum_selected;  // TRUE se ha selezionato una riga del riepilogo, funge da semaforo per leggere la prossima
  int             _sum_filter;    // Filtro corrente della riga TRiepilogo_Iva in corso di stampa (-1 se non ha ancora calcolato la tabella)
  TString_array   _order_array;   // Array di TToken_string contenenti i codici IVA soddisfacenti ad ogni tipo di filtro
  TAssoc_array    _summary_table; // Array dove vengono memorizzate le imposte per aliquota
  TArray          _summary_array; // Array dove vengono memorizzate le imposte/imponibili per riga
  TRiepilogo_Iva  _sum_current;   // Riga corrente del riepilogo

  // membri per il calcolo del riepilogo scadenze
  TString_array   _scadenze_array;// Array che contiene le scadenze ("<data>|<importo>")
  int             _scadenze_current;  // indice per identificare l'elementi corrente sull'array (-1 se non ha ancora calcolato)

public:

  
  // Funzioni per il riepilogo IVA
  const bool summary_compiled() { return _sum_filter > -1; }
  void compile_summary(); // Aggiorna la tabella riepilogativa    
  void summary_filter(byte selector);  // filtra la tabellina secondo il filtro corrente se non e' gia' stato fatto
  void summary_reset(bool force=FALSE); // riposiziona l'array dei codici IVA (_order_array). Se il parametro e' TRUE forza il ricalcolo della tabella 
  void summary_set_next(); // seleziona il prossimo elemento del filtro
  const TRiepilogo_Iva& sum_current() { return _sum_current; } // ritorna la riga corrente del filtro corrente
  const char * summary_get(const TString& w); // ritorna l'informazione richiesta estratta dall'elemento corrente
  int  summary_items() { return _summary_table.items();} // ritorna il numero di righe in totale della tabellina
  const TAssoc_array& summary() { return _summary_table; }
  const TArray& summary_array() { return _summary_array;}
  

  // Funzioni per il ricalcolo delle scadenze
  void scadenze_reset(); // riposiziona sulla prima scadenza
  void scadenze_recalc(); // resetta e ricalcola le scadenze
  void scadenze_set_next(); // seleziona il prossimo elemento dell'array delle scadenze
  const char * scadenze_get(const TString& w); // reperisce l'informazione richiesta dall'elemento corrente
  int  scadenze_items() { return _scadenze_array.items(); }  // restituisce il numero di scadenze
  TString_array& scadenze() { return _scadenze_array; }

  // Funzioni di totalizzazione
  real& tot_importi_netti();
  real& tot_imposte();
  real tot_spese();
  real tot_documento();
  // restituisce tot_imponibili, tot_esenti, tot_nonsoggetti a seconda del selettore:  
  // 1 = regime normale
  // 2 = da ventilare (non usato)
  // 4 = esenti
  // 8 = non imponibili
  // 16 = non soggetti
  // pertanto i non imponibili avranno selettore 1 e gli esenti selettore 4.
  // per avere esenti + non soggetti il selettore sara' 20 e cosi' via.
  real tot_imponibili(byte selector);
  
  // Reperisce l'informazione <what> dal campo G1 della testata
  const char* get_head_info(const TString& what);
  
  // Funzioni per settare i parametri
  void set_decimals(dec_parm & parm) { _parm = parm ; }
  void set_condv(TCliFor * cli); // Cambia le condizioni di vendita
  TDocumentoEsteso (const TRectype & rec, dec_parm & parm, TCliFor * cli = NULL) ;
  TDocumentoEsteso (const TRectype & rec, TCliFor * cli = NULL) ;
  TDocumentoEsteso () ;
  ~TDocumentoEsteso();
};


