#ifndef __CONFIG_H
#define __CONFIG_H 

#ifndef INCL_XVTH
#include <xvt.h>
#endif

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

// @doc EXTERNAL

class ofstream;

// questo sara' il principale, per ora non c'e'
#define CONFIG_GENERAL  0
// file parametri studio (uno per studio, per ora e' il principale)
#define CONFIG_STUDIO   1
// file parametri ditta (uno per ditta)
#define CONFIG_DITTA    2
// file conversioni archivi
#define CONFIG_FCONV    3
// file parametri utente
#define CONFIG_USER     4
// file parametri stampe
#define CONFIG_STAMPE   5
// file parametri golem
#define CONFIG_GOLEM    6

// @class TConfig | Classe per la gestione dei file di configurazione in formato
//                  Windows
//
// @base public | TObject
class TConfig : public TObject
{

  // @comm Sono definite alcune costanti per l'individuazione immediata di
  //       alcuni file particolari e di frequente uso. Tali file sono:
  //
  // @flag CONFIG_GENERAL | Questo sara' il principale, per ora non c'e'
  // @flag CONFIG_STUDIO | File parametri studio (uno per studio, per ora e'
  //                       il principale)
  // @flag CONFIG_DITTA | File parametri ditta (uno per ditta)
  // @flag CONFIG_FCONV | File conversioni archivi
  // @flag CONFIG_USER | File parametri utente
  // @flag CONFIG_STAMPE | File parametri stampe
  // @flag CONFIG_GOLEM | File parametri golem

  // @access Private Member

  // @cmember Contenuto del paragrafo
  TAssoc_array _data;
  // @cmember Nome del file di configurazione
  TFilename _file;
  // @cmember Indica se il file??? e' presente (TRUE se esiste)
  bool _dirty;
  // @cmember Indica se il paragrafo e' presente (TRUE se esiste)
  bool _ispresent;
  // @cmember Nome del paragrafo attivo
  TString _paragraph;

  // @access Protected Member
protected:
  // @cmember Legge i dati del paragrafo
  bool _read_paragraph();
  // @cmember Scrive i dati del paragrafo
  void _write_paragraph(ofstream&);
  // @cmember Scrive il file di configurazione
  void _write_file();
  // @cmember Inizializza il paragrafo leggendo dal file i dati
  void init(const char *fn, const char* pa);

  // @access Public Memeber
public:

  // @cmember Ritorna il valore della variabile nella sezione corrente o in
  //          quella specificata
  TString& get(const char* var, const char* section = NULL, int index = -1, const char* def = "");

  // @cmember Ritorna il valore della variabile nella sezione corrente o in
  //          quella specificata (se la variabile contiene un long)
  long get_long(const char* var, const char* section = NULL, int index = -1, long def = 0L);

  // @cmember Ritorna il valore della variabile nella sezione corrente o in
  //          quella specificata (se la variabile contiene un long)
  char get_char(const char* var, const char* section = NULL, int index = -1, char def = ' ' );

  // @cmember Ritorna il valore della variabile nella sezione corrente o in
  //          quella specificata (se la variabile contiene un int)
  int get_int(const char* var, const char* section = NULL, int index = -1, int def = 0);
  
  // @cmember Ritorna il valore della variabile nella sezione corrente o in
  //          quella specificata (se la variabile contiene un bool)
  bool get_bool(const char* var, const char* section = NULL, int index = -1, bool def = FALSE);
  
  // @cmember Ritorna il valore del colore settato nella variabile nella
  //          sezione corrente o in quella specificata
  COLOR get_color(const char* var, const char* section = NULL, int index = -1, COLOR def = 0);

  // @cmember Setta la variabile nella sezione corrente o specificata
  bool set(const char* var, const char* value, const char* section = NULL, bool force = TRUE, int index = -1);
  // @cmember Setta la variabile nella sezione corrente o specificata
  bool set(const char* var, long value, const char* section = NULL, bool force = TRUE, int index = -1);
  
  // @cmember Controlla se esite una variabile nel paragrafo attivo
  bool exist(const char* var, int index = -1);         

  // @cmember Controlla se il paragrafo corrente e' nuovo (TRUE se nuovo)
  bool new_paragraph()
  { return !_ispresent; }

  // @cmember Ritorna quanti elementi dell'array nominato sono presenti nella
  //          sezione indicata.
  word items(const char* var, const char* section);

  // @cmember Setta il paragrafo passato come quello attivo
  void set_paragraph(const char* par);

  // @cmember Riempie pl con la lista dei paragrafi
  int list_paragraphs(TString_array& pl);
  
  // @cmember Riempie vl con la lista dei nomi delle variabili 
  //          nella sezione corrente o in quella indicata; se 
  //          add_value e' TRUE ci mette "variabile|valore" 
  //          ACHTUNG: l'array e' in ordine HASH (CAZZ)                         
  int list_variables(TString_array& vl, bool add_value = FALSE, const char* section = NULL);                           
                            
  // @cmember Costruttore (il paragrafo iniziale e' il modulo corrente
  //          salvo diversa indicazione)
  TConfig(int which_config = CONFIG_GENERAL, const char* paragraph = NULL);
  // @cmember Costruttore (il paragrafo iniziale e' il modulo corrente
  //          salvo diversa indicazione)
  TConfig(const char* file, const char* paragraph = NULL);

  // @ cmember Distruttore. Riscrive il file con le modifiche se necessrio,
  virtual ~TConfig();
};

#endif
