#ifndef __PRLIB_H
#define __PRLIB_H

#ifndef __RELATION_H
#include <relation.h>
#endif

#ifndef __RECARRAY_H
//#include <recarray.h>
#endif

#ifndef __AGE_H 
#include "../pr/agenti.h"
#endif

class TRata : public TSortable
{
  TDate _datascad;
  real  _imprata, _impprovv, _pagato, _provvpag, _pagmat, _provvmat;
  bool  _saldata;
  int   _nrata,_tipopagpr,_tipopag;
  char  _generata;
  TString16 _codval;
  
public:
  virtual TObject* dup() const { return new TRata(*this); }
  virtual int compare(const TSortable& s) const;
  const int        rata()     const { return _nrata;}
  const int        tipopag()  const { return _tipopag;}
  const TDate      datascad() const { return _datascad; }
  const real       imprata()  const { return _imprata;}
  const real       impprovv() const { return _impprovv;}
  const real       pagato()   const { return _pagato;}
  const real       provvpag() const { return _provvpag;}
  const real       provvmat() const { return _provvmat;}
  const real       pagmat()   const { return _pagmat;}
  const bool       saldata()  const { return _saldata;}
  const char       generata() const { return _generata;}
  const int        tipopagpr()const { return _tipopagpr;}
  const TString &  codval() const   { return _codval; }
  void             set_rata(const int n)            { _nrata = n; }
  void             set_tipopag(const int t)         { _tipopag = t; }
  void             set_datascad(const TDate& d)     { _datascad = d; }
  void             set_imprata(const real&   r)     { _imprata  = r; }
  void             set_impprovv(const real&  r)     { _impprovv = r; }
  void             set_saldata(const bool b = TRUE) { _saldata = b; }
  void             set_codval(const char * codval) { _codval = codval; }
  void             set_generata(const bool g = TRUE) { _generata = g ? 'D' : ' '; }
  void             set(const TRectype& rec);
  void             set(const TRata& r);
  void             set(TToken_string& t);
  const TRata& operator = (const TRata & r) { set(r);return *this;}
  TRata(const TRectype& rec);     
  TRata(const TRata & r) { set(r);}
  TRata() { _generata = ' '; _saldata = FALSE; }
  virtual ~TRata() {}
};

class TRate_doc    : public TObject
{
  // Dati del documento
  int       _anno;
  TString16 _codnum,_codval;
  long      _ndoc,_codcf;
  TDate     _datadoc,_datacambio;
  real      _impdoc,_impprdoc,_impnetdoc,_cambio;
  TArray    _rows;    // Rate del documento. La rata 0 corrisponde alla provvigione all'atto della fatturazione
                      // Array di TRata
public:
  virtual TObject* dup()      const { return new TRate_doc(*this); }
  const int        anno()     const { return _anno; }
  const TString&   codnum()   const { return _codnum; }
  const TString&   codval()   const { return _codval; }
  const long       ndoc()     const { return _ndoc; }
  const long       codcf()    const { return _codcf; }
  const TDate      datadoc()  const { return _datadoc; }
  const TDate      datacam()  const { return _datacambio;}
  const real       impdoc()   const { return _impdoc;}
  const real       impprdoc() const { return _impprdoc;}
  const real       cambio()   const { return _cambio;}
  const real       impnet()   const { return _impnetdoc;}
  const int        items()          { return _rows.items();}
  const bool       exist(const int i);
  TRata&           row(int i, bool create = FALSE);
  TRata&           operator[](int i){ return row(i,FALSE); }
  void add_rata(TRata* r)           {_rows.add(r);}
  void remove_rata(int i = -1)      {_rows.destroy(i);} 
  // Pakka le rate
  void pack_rate()                  {_rows.pack();}
  // Ordina le rate
  void sort_rate()                  {_rows.sort();}
  // Controlla che la somma delle provvigioni delle singole rate sia <= della provvigione del documento
  bool ok_provvigione();
  void        set(const TRectype& rec);
  void        set(const TRate_doc & r);
  void        set(TToken_string& t);
  const TRate_doc & operator =(const TRate_doc& r) { set(r); return *this;}
  TRate_doc(const TRectype& rec);
  TRate_doc(const TRate_doc& r) { set(r);}
  virtual ~TRate_doc() {}
};

class TProvvigioni_agente : public TRectype
{
  TString16       _agente;       // Codice agente 
  //TRecord_array   *_rows;        // Righe provvigionali (LF_PROVV) usato per leggere/scrivere
  TRelation*      _provv_rel;
  TCursor*        _provv_cur;
  TAssoc_array    _rate;         // Array associativo per ANNO+CODNUM+NDOC
                                 // contiene le informazioni del documento con le relative rate.
protected:
  int rate2rows(int action);
public:
  const TString16& agente () const          { return _agente;}
  real  perc_fatt()  const                  { return get_real(AGE_PERCFATT);}
  real  perc_fissa() const                  { return get_real(AGE_PERCPROVV);}
  // Per operare direttamente sulle righe
  //const TRectype& operator [](int index) const 
  //                                         { return _rows->operator[](index);}
  //TRectype& operator[] (int index)         { return _rows->operator[](index);}
  const int items() const                   { return _rate.items();}
  // lettura, scrittura ecc...
  int  read(const char* agente, const int anno = 0, const char* codnum = NULL, const long = 0L);
  int  write()      { return rate2rows(0); }
  int  rewrite()    { return rate2rows(1); }
  int  remove()     { return rate2rows(2); }
  void unlock();
  // Restituisce un elenco di documenti che hanno rate per le provvigioni di questo agente
  int  documenti(TString_array& kl)        { return _rate.get_keys(kl); }
  // Per accedere tramite singole rate...
  TRate_doc&  rate(int anno, const char* codnum, long ndoc, bool create = FALSE) ;
  TRate_doc&  rate(const char* key, bool create = FALSE) ;
  // Rimuove le rate del documento indicato
  void remove_rate(int anno, const char* codnum, long ndoc);
  void remove_rate(const char* key);
  void destroy() { _rate.destroy(); }
  TProvvigioni_agente(const char* agente);
  TProvvigioni_agente() ;
  virtual ~TProvvigioni_agente();  
};

class TAgente : public TRectype
{                              
protected:
  int read(const char* codice);
  virtual TAgente & copy(const TAgente & a) { return (TAgente &) TRectype::operator=((TRectype &)a);}

public:       
  TObject* dup() const { return new TAgente(*this); }
  const TString& codice() const { return get("CODAGE");}  
  const TString& ragsoc() const { return get("RAGSOC"); } 
  const TString& campoprovv() const { return get("CAMPOPROVV"); } 

  TAgente(const char* codice = NULL);
  TAgente(const TAgente & a);
  TAgente(const TRectype& rec);
  virtual ~TAgente() {}
};
#endif