// cglib04.h

#ifndef __CGLIB04_H
#define __CGLIB04_H

#include <applicat.h>
#include <config.h>
#include <prefix.h> 
#include <isam.h> 
#include <stdio.h>
#include <array.h>
#include <assoc.h>
#include <strings.h>
#include <scanner.h>
#include <tabutil.h>  
#include <progind.h>
#include <isam.h>
#include <codeb.h>

#include <mov.h>
#include <rmov.h>
#include <rmoviva.h>        
#include <pconti.h> 
#include <comuni.h>
#include <clifo.h>              
#include <rcausali.h>

#define TEMP_CAUS    "tcaus"
#define TEMP_RCAUS   "trcaus"
#define TEMP_CLIFO   "tclifo"
#define TEMP_PCON    "tpcon"
#define TEMP_MOV     "tmov" 
#define TEMP_RMOV    "trmov" 
#define TEMP_RMOVIVA "trmoviva" 
#define TEMP_OCC     "toccas"
#define TEMP_TAB     "ttab"

#define SIZE          256

static unsigned char _tabella[10] = {0x8a,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52};

HIDDEN      TString80 TEMP;
HIDDEN      TString16 HEADER = "\\header";

const int   CAMPI_RCAUS = 6;

// Tracciato del record di controllo      
HIDDEN int pos[15] = {0,15,25,29,32,38,47,234,235,236,237,238,239,240,241};
                                                                      
/*HIDDEN*/ const char* converti (TString& data_AS400,bool anno_di_quattro);                                                                      
/*HIDDEN*/ const char* riconverti (TString& data_PC,bool anno_di_quattro);                                                                     
/*HIDDEN*/ int date2esc(const TDate& d, int* prevesc = NULL);

int packindex(bool vis, int num, TString& name);
int pack(bool vis, int num, TString& name);
int packfile(bool vis, int num, TString& name);

//const char* converti(TString& data);
int         fremove(const char* path);
bool        look_causale(const char* codcaus);  
bool        format_if_zero(TString&, int);

class TRic_recfield : public TObject
{                 
  char                 _name[12];      // Nome campo
  TRectype*            _rec;           // Puntatore a inizio record
  char*                _p;             // Puntatore a inizio campo
  int                  _len;           // Lunghezza campo
  int                  _dec;           // Numero di decimali
  int                  _type;          // Tipo del campo

  void set(int from, int to);
  
  public:
/*    int operator =(int i) ;
    long operator =(long l) ;
    const TDate& operator =(const TDate& d) ;
    const real& operator =(const real& r) ; */
    
    const char* operator =(const char* s);

/*    operator int() const ;
    operator long() const ;
    operator TDate() const ;
    operator const real() const ; */
    
    operator const char*() const;

//    void setptr(TRecnotype r); // Scrive un campo packed. Sarebbe meglio non usare mai campi packed.
//    TRecnotype ptr() const;    // Legge un campo packed. Sarebbe meglio non usare mai campi packed.

    const char* pos() const { return (const char*) _p;} // Ritorna un puntatore all'inizio del campo nel record. Dovrebbe essere protected!
    int len() const { return (int) _len;} // Ritorna la lunghezza
    int dec() const { return (int) _dec;} // Ritorna il numero di decimali
    TFieldtypes type() const { return (TFieldtypes) _type;} // Ritorna il tipo del campo
    TRectype& record() const { return *_rec;} // Ritorna puntatore a inizio record

    TRic_recfield(TRectype& rec, const char* name, int from = 0, int len = 0);
};


class TMappa_trc : public TAssoc_array
{                                 
  public :
  void leggi_modulo();

  int           from       (const char* key);
  int           to         (const char* key);
  int           logicnum   (const char* key);   
  const char*   field_name (const char* key);    
  int           flag       (const char* key);   
  int           flag_bis   (const char* key);     
  
  TMappa_trc() {};
};

class TTransfer_file
{
  FILE*          _trasfer;  
  TArray         _index;     
  //  TAssoc_array  _fis_index;
  TMappa_trc     _trc;          
  TString        _curfile;
  TString256     _control_rec;   // Buffer per il record di controllo
  TString256     _record;        // Buffer per il record corrente
  TProgind*      _prog;                          
  TIsamtempfile* _toccas;  
  TIsamtempfile* _ttab;
  
  long          _numreg, _numreg_p, _numreg_piva, _npoccas;
  int           _annoes;
  TDate         _datareg;
  TString       _cod_com;

  long          _curpos;
  long          _tot_rec;   // Numero totale di record nel transfer
  int           _nultras;   // Numero ultimo trasferimento
  int           _last_tab,_last_mov;
  long          _ditta;
  
  TString16     _tiporec;
  TString16     _nome_simb;
  TString16     _dataultras;
  TString16     _sigle_file;
  TString       _nrec_file;            
  TString       _ult_file;
  TString       _key;
  TString80     _tmpcaus,_tmprcaus,_tmpclifo,_tmppcon,_tmpmov;
  TString80     _tmprmov,_tmprmoviva;  

private:
  // Inizializza l'indice leggendo il record di controllo
  void          fill_index(TString&,TString&);
  
  // Funzioni utilizzate da fcopytemp()
  void          scrivi_header(const char* dest,const char* wflag);
  void          scrivi_causali(long nrec);
  void          scrivi_clifo(long nrec);
  void          scrivi_pcon(long nrec);
  void          scrivi_PN(long nrec);
  void          scrivi_IVA(long nrec);
  
  void          write_tmp_tabelle(TString& record, bool create);
  int           trasfer_data_tab(TIsamtempfile& file, TRectype& dep);
  void          write_tmp_movPN(TString& record, bool create);
  int           trasfer_data_mov(TIsamtempfile& file, TRectype& dep);
  void          write_tmp_movIVA(TString& record, bool create);
  int           trasfer_data_moviva(TIsamtempfile& file, TRectype& dep, int ln);  
  
  char          TipoConto (int gruppo, int conto);  
  const char*   numero_civico(TString& field);
  void          leggi_record_controllo();                            
  int           annoes_datacomp(const TString& record, TDate& datacomp);
  void          decimali(TString& campo, int dec); 
  void          negativo(TString& importo);
  int           strip_zero(TString& importo);
  bool          my_isdigit(unsigned char ch);
  int           look(unsigned char carattere);
  int           cerca_annoes(long numreg);                
  const char*   scrivi_occasionali(const TString& record);
  
  public:
  
  void          remove_all(bool file_ditta = TRUE);
  void          canc_file_dir_temp(const char* dir);  
  void          temp_dir(TString& orig,TString& dest,TString& sigle);
  
  const char*   cerca_comune_cap(TString& field);
  const char*   cerca_comune_den(TString& field);                       
  void          datafine_esprec(const int aep, TDate& datacomp);   
                                                                     
  bool          fcopytemp(const char* orig, const char* dest);
  bool          ordina_trasfer(const char* orig);
  long          determina_dimensione(FILE* f);                            
                                                                         
  int           dataes(const TDate&, int*, TDate&);
                                                                       
  const char*   path (long codditta = 0); 
  bool          open (const char* path, bool create=FALSE);
  void          close ();
  bool          exist() const { return _trasfer != NULL; }

  long          get_pos(const char* key);
  
  // Funzioni che agiscono sul record di controllo del file trasfer.

  bool          read_control_rec(); // Legge il record del file header
  bool          read_control_rec_t(); // Legge il record di controllo del file trasfer  
  bool          write_control_rec(const char* str, const int size); // Scrive una stringa di lunghezza size 

  const char*   tiporec   () const { return _tiporec; }   // Ritorna il tipo record
  const char*   nome_simb () const { return _nome_simb; } // Ritorna il nome simbolico del sistema inviante
  long          ditta     () const { return _ditta; }     // Ritorna la ditta inviante
  int           nultras   () const { return _nultras; }   // Ritorna il numero ultimo trasferimento
  const char*   dataultras() const { return (const char*) _dataultras; } // Ritorna la data ultimo trasferimento
  const char*   sigle_file() const { return (const char*) _sigle_file; } // Ritorna una stringa contenente le sigle dei file da ricevere
  const char*   nrec_file () const { return (const char*) _nrec_file; }  // Ritorna una stringa con il numero totale di record corrispondenti ad ogni sigla dei file da ricevere    
  char          flg_agg(char sigla); // Ritorna i flag tipo aggiornamento relativi alle tabelle
  bool          numprot_att(); // Ritorna il flag riattribuzione numero protocollo su fatture attive
  bool          numprot_pas(); // Ritorna il flag riattribuzione numero protocollo su fatture passive
  char          flg_agg_IV(char sigla);  // Ritorna il flag tipo aggiornamento classi piano dei conti
  const char*   ult_file  () const { return (const char*) _ult_file; } // Ritorna l'ultima sigla file elaborato
  const char*   key       () const { return (const char*) _key; } // Ritorna la chiave ultimo record elaborato
  const char*   record    () const { return (const char*) _control_rec; } // Ritorna il record di controllo del trasfer

  // Funzioni per il posizionamento e la gestione dei record del trasfer (escluso il record di controllo)

  // Legge il record del trasfer specificato da numrec
  int           read_rec_trasfer(long numrec, int size=256); 
  const char*   read_rec  () const { return (const char*) _record; } // Ritorna un record del trasfer

  // Scrive una stringa di lunghezza size nel campo specificato da fieldnum
  void          writeat(const char* str,int size,int fieldnum,const char* file); 
  void          writeat(const char* str,int size,int fieldnum,
                        const char* file, const long numrec); 
  
  int           write(long numrec, int size=SIZE);

  // Permette di posizionarsi all'interno del record sul campo specificato 
  // da fieldnum sfruttando la Mappa precaricata  
  int           go2field(int fieldnum, const char* file=NULL,
                         const long nrec=-1L, bool seek=TRUE); 
  void          go2rec  (const long numrec);
  void          readat(long recnum); // Si posiziona all'inizio del record specificato da numrec sfruttando l'array indice

  void          put(const char* val, const char* file, int fieldnum,long recnum=-1L);

  // Funzioni per la gestione dell'array indice
  int           last_tab() const { return _last_tab; } // Ritorna la posizione dell'ultima sigla relativa alle tabelle presente nella schiera delle sigle file
  int           last_mov() const { return _last_mov; } // Ritorna la posizione dell'ultima sigla relativa ai movimenti presente nella schiera delle sigle file
  
  int           num(char sigla);
  const char*   name(int i); // Ritorna la sigla di quel file
  long          nrec(int i); // Ritorna il numero di record di quel file
  int           lenrec(int i); // Ritorna la lunghezza del record del trasfer corrispondente a quel file
  int           lenrec(char sigla); // Ritorna la stessa cosa ma con la sigla invece del numero
  long          start(int i);       // Inizio del file numero i
  long          start(char sigla);  // Inizio del file sigla
  long          end(int i); // Ritorna la posizione in byte corrispondente alla fine di quel file all'interno del trasfer 
  long          rec(int i); 

  long          tot_rec() const { return _tot_rec; }
  
  void          annulla_classi(int g, int c,bool conto);

  // Copia il file trasfer creando tre isam_temp_file per i mov. di prima nota  
  bool          fcopytemp (const char*, const char*, bool);

  TMappa_trc&   mappa() {return _trc; }  

  TTransfer_file(); 
  ~TTransfer_file();
};                  

#endif

