#ifndef __FORM_H
#define __FORM_H

#ifndef __SCANNER_H
#include <scanner.h>
#endif

#ifndef __PRINTER_H
class TPrinter;
class TPrintrow;
#endif

#ifndef __MASK_H
class TMask;
#endif

#ifndef __ISAM_H
class TRectype;
#endif

#ifndef __RELATION_H
class TRelation;
class TRelation_description;
class TCursor;
#endif

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

// @doc EXTERNAL

// @enum pagetype | Posizione della pagina da stampare
enum pagetype {
     odd_page,     // @emem Pagine dispari
     even_page,    // @emem Pagine pari
     first_page,   // @emem Prima pagina
     last_page };  // @emem Ultima pagina

// @doc INTERNAL

// @enum bkg_mode | Tipo di background presente nella stampa
enum bkg_mode {
     none,        // @emem Nessuno sfondo
     testo,       // @emem Sfondo di tipo testo
     graphics } ; // @emem Sfondo grafico

pagetype char2page(char);

class TForm;
class TMask_field;
class TSheet_field;    
class TForm_item;
class TPrint_section;

const int MAXCOLUMNS = 32;

// @doc EXTERNAL

// @class TForm | Classe per la descrizione dei formati di stampa
//
// @base public | TObject
class TForm : public TObject

// @author:(INTERNAL) Guido, Angelo, Villa

{
  // @cfriend TForm_editor
  friend class TForm_editor;
  // @cfriend TForm_EC_editor
  friend class TForm_EC_editor;
  // @cfriend TPrint_section
  friend class TPrint_section;
  
  // @access:(INTERNAL) Private Member

  // @cmember:(INTERNAL) Tipo di sfondo da applicare alla stampa (vedi <t bkg_mode>)
  bkg_mode _background_mode;

  // @cmember:(INTERNAL) Nome del profilo di stampa
  TString _name;
  // @cmember:(INTERNAL) Codice del profilo di stampa
  TString _code;
  // @cmember:(INTERNAL) Nome del font da utilizzare
  TString _fontname;
  // @cmember:(INTERNAL) Dimensione del font da utilizzare
  int _fontsize;
  // @cmember:(INTERNAL) Maschera per la sezione
  TString _section_mask;
  //@cmember:(INTERNAL) Offset X valido per tutte le sezioni
  int _x;
  //@cmember:(INTERNAL) Offset Y valido per tutte le sezioni
  int _y;
  // @cmember:(INTERNAL) Carattere utilizzato per il posizionamento dei moduli
  char _char_to_pos;
  // @cmember:(INTERNAL) Coordinata X del posizionamento iniziale
  int _ipx;
  // @cmember:(INTERNAL) Coordinata Y del posizionamento iniziale
  int _ipy;
  // @cmember:(INTERNAL) Coordinata X del posizionamento finale (la riga e' la stessa)
  int _fpx;
  // @cmember:(INTERNAL) Flag per registrare i parametri (font ed offset)
  bool _dirty;
  
  // @cmember:(INTERNAL) Flag di abilitazione del messagio ADD
  bool _msg_add_enabled;
  
  // @cmember:(INTERNAL) Relazione corrente (puo' essere NULL), vedi <c TRelation>
  TRelation* _relation;
  // @cmember:(INTERNAL) Cursore corrente (puo' essere NULL), vedi <c Tcursor>
  TCursor* _cursor;
  // @cmember:(INTERNAL) <c TRelation_description> per la gestione della relazione corrente
  TRelation_description* _rel_desc;

  // @cmember:(INTERNAL) Array di headers
  TArray _head;
  // @cmember:(INTERNAL) Array di bodies
  TArray _body;
  // @cmember:(INTERNAL) Array di footers
  TArray _foot;
  // @cmember:(INTERNAL) Array di sfondi grafici
  TArray _back;

  // @cmember:(INTERNAL) Indica se si sta stampando l'ultima pagina
  bool _lastpage;

  // @cmember:(INTERNAL) Indica se si tratta di un nuovo form
  bool _isnew;
  // @cmember:(INTERNAL) Indica se si tratta di form di base (.frm file)
  bool _isbase;
  // @cmember:(INTERNAL) Indica se effettuare il posizionamento manuale dei moduli
  bool _arrange;
  // @cmember:(INTERNAL) Permessi di Edit
  int _editlevel;
  // @cmember:(INTERNAL) Descrizione del formato
  TString _desc;
  // @cmember:(INTERNAL) Array di caratteri di fincatura
  TString16 _fink;
  
  // @cmember:(INTERNAL) Handler di default della testata di stampa
  static void header_handler(TPrinter& p);
  // @cmember:(INTERNAL) Handler di default del piede di stampa
  static void footer_handler(TPrinter& p);                                         

  // @cmember:(INTERNAL) Ritorna l'array di caratteri di fincatura
  const char* get_fincatura()    
  { return _fink; }
  // @cmember:(INTERNAL) Setta l'array di caratteri di fincatura
  void set_fincatura(const char* s);
                                               
// @access Protected Member
protected:

  // @cmember Cambia il formato di tutte le date nel form
  bool ps_change_date_format(TPrint_section& s, const char* f);
  // @cmember Cambia il formato di tutti i numeri nel form
  bool ps_change_number_format(TPrint_section& s, int w, int dec, const char* p);
  // @cmember Controlla se esiste una sezione di stampa
  TPrint_section* exist(char s, pagetype t, bool create = FALSE);
  // @cmember Inizializza il form
  void init();
  // @cmember Carica il form dal file specificato
  void read(const char* form, const char* code = "", int editlevel = 0, const char* desc = ""); 

  // @cmember Ritorna una sezione di stampa, la crea se non esiste (chiama <mf TForm::exist>)
  TPrint_section& section(char s, pagetype pos);
  // @cmember Ritorna una sezione di stampa, la crea se non esiste (chiama <mf TForm::exist>)
  //        (3 e' una pagina dispari qualsiasi)
  TPrint_section& section(char s, word page = 3);

  // @cmember Stampa la sezione <p s>  
  void print_section(ostream& out, char s) const;
  // @cmember Stampa il sorgente del form su file di testo
  virtual void print_on(ostream& out) const;
  
  // @cmember Legge una use e setta la relazione (ritorna sempre TRUE)
  bool parse_use(TScanner&);
  // @cmember Legge una join e setta la relazione (ritorna sempre TRUE)
  bool parse_join(TScanner&);
  
  // @cmember Legge una <c TRelation_description> e setta la relazione
  bool parse_description(TScanner&);
  // @cmember Scrive una <c TRelation_description> su <p out>
  void print_description(ostream& out) const;
  
  // @cmember Legge dal file le caratteristiche generali del form (identificate da GE)
  bool parse_general(TScanner&);
  // @cmember Scrive le caratteristiche generali del form su <p out>
  void print_general(ostream& out) const;
  // @cmember Usata per leggere voci non-standard nella sezione generale
  virtual void extended_parse_general(TScanner&) 
  {} 

  // @cmember Chiamata per effettuare controlli non standard nell'edit della sezione
  //          <p sec> (prima dell'esecuzione della maschera di edit <p m>)
  virtual void pre_edit_checks(TMask&m, TPrint_section* sec)
  {}
  // @cmember Chiamata per effettuare controlli non standard nell'edit della sezione
  //          <p sec> (dopo l'esecuzione della maschera di edit <p m>)
  virtual bool post_edit_checks(TMask& m, TPrint_section* sec)
  {return FALSE;}
  
  // @cmember Legge un profilo
  bool read_profile();
  // @cmember Scrive un profilo su file (vedi <mf TForm::read_profile>)
  bool write_profile();
  
  // @cmember Resetta gli specials obbligatori per ogni form_item (header, offset e fincatura)
  //  per comodita' di utilizzo dei membri _col_head, _ofs, finkl e finkr di TForm_item.
  void set_compulsory_specials();
  // @cmember Legge gli specials obbligatori prima di scriverli
  void get_compulsory_specials();
  
  // @cmember Ritorna il numero di pagina correntemente in stampa
  word page(const TPrinter& p) const;
  // @cmember Effettua il posizionamento manuale del modulo
  void arrange_form();
  
  // @cmember Ritorna il numero di record presenti nella <c TCursor>
  virtual long records() const;
  // @cmember Effettua l'update della sezione grafica background
  virtual word set_background(word p, bool u);
  // @cmember Effettua l'update della sezione header
  virtual word set_header(word p, bool u);
  // @cmember Effettua l'update della sezione body
  virtual word set_body(word p, bool u);
  // @cmember Effettua l'update della sezione footer
  virtual word set_footer(word p, bool u);

// @access Public Member  
public:               

  // @cmember Genera automaticamente la sezione grafica con colonne fincate
  bool genera_fincatura(pagetype p, int y1, int y2, const int* rows);
 
  // @cmember Genera le righe di intestazione colonna alla riga indicata, vale per COLUMNWISE
  bool genera_intestazioni(pagetype p, short y);

  // @cmember Stampa gli items da <p form> a <p to>
  bool print(long from = 0L, long to = -1L);

  // @cmember Ritorna l'altezza della pagina <p page> la prima di default
  word height(word page = 3);

  // @cmember Ritorna l'array di item del body  
  TArray& body() 
  { return _body; }
  // @cmember Ritorna l'array di item dell'header
  TArray& head() 
  { return _head; }
  // @cmember Ritorna l'array di item del footer
  TArray& foot() 
  { return _foot; }
  // @cmember Ritorna l'array di item dello sfondo
  TArray& back() { return _back; }

  // @cmember Ritorna il nome del profilo di stampa 
  const TString& name() const 
  { return _name; }
  // @cmember Ritorna il codice del profilo di stampa
  const TString& code() const 
  { return _code; }
  
  // @cmember Ritorna il nome della mschera per la sezione
  virtual const char* section_mask()
  { return "ba2100s"; }
  // @cmember Ritorna i permessi di Edit (<md TForm::_editlevel> assume solo i valori 0 e non 0)
  bool edit_level() const 
  { return _editlevel; }
  // @cmember Setta i permessi di edit
  void set_edit_level(int n) 
  { _editlevel = n; }
  // @cmember Setta la descrizione del formato
  void set_description(const char* s) 
  { _desc = s; }
  
  void enable_message_add(bool on) { _msg_add_enabled = on; }
  void disable_message_add() { enable_message_add(FALSE); }
  bool message_add_enabled() const { return _msg_add_enabled; }
  
  // @cmember Ritorna la relazione corrente
  virtual TRelation* relation() const 
  { return _relation; }
  // @cmember Ritorna la <c TCursor> corrente
  virtual TCursor* cursor() const 
  { return _cursor; }
  // @cmember Ritorna la <c TRelation_description> corrente
  TRelation_description& rel_desc() const;
  // @cmember Effettua operazioni personalizzate dall'applicazione sul <c TForm_item>
  virtual bool validate(TForm_item& fld, TToken_string& val);
  
  // @cmember Ritorna il campo <p id>-esimo della sezione <p sec>
  TForm_item& find_field(char sec, pagetype pag, short id) const;
  // @cmember Ritorna l'offset x valido per tutte le sezioni
  int& offset_x()  
  { return _x; }
  // @cmember Ritorna l'offset x valido per tutte le sezioni
  int& offset_y()  
  { return _y; }
  // @cmember Ritorna il nome del font in uso
  TString& fontname() 
  { return _fontname; }
  // @cmember Ritorna la dimensione del font in uso
  int&  fontsize()   
  { return _fontsize; } 
  // @cmember Ritorna il carattere utilizzato per il posizionamento dei moduli
  char& char_to_pos()
  { return _char_to_pos; }
  // @cmember Ritorna la coordinata X del posizionamento iniziale
  int& ipx()
  { return _ipx; }
  // @cmember Ritorna la coordinata Y del posizionamento iniziale
  int&  ipy()
  { return _ipy; }
  // @cmember Ritorna la coordinata X del posizionamento finale
  int&  fpx()
  { return _fpx; }
  // @cmember Ritorna il flag per registrare i parametri
  bool dirty() const 
  { return _dirty; }
  // @cmember Setta il flag per registrare i parametri
  void set_dirty(bool d = TRUE) 
  { _dirty = d; }
  // @cmember Setta se effettuare il posizionamento manuale dei moduli
  void set_arrange(bool arng = TRUE)
  { _arrange = arng ; }
                                            
  // @cmember Cambia il formato di tutte le date nel form (vedi <mf TForm::ps_change_date_format>)
  void change_date_format(const char* f);
  // @cmember Cambia il formato di tutti i numeri nel form (vedi <mf TForm::ps_change_number_format>)
  virtual void change_number_format(int w, int dec, const char* p);
  // @cmember Rilegge la sezione specificata
  bool reread(char sec, pagetype p, bool force=FALSE);
  // @cmember Editor interface (vedi <c TForm_editor>)
  TForm_editor& editor() const;
  
  // @cmember Setta l'inizio di stampa dell'ultima pagina
  void set_last_page(bool lp) 
  { _lastpage = lp; }
  
  // @cmember Setta il modo di sfondo (fincatura)
  void set_mode(bkg_mode b);
  // @cmember Ritorna il modo di sfondo (fincatura)
  bkg_mode mode()
  { return _background_mode;}

  // @cmember Costruttore
  TForm();
  // @cmember Costruttore (se <p code> == NULL si tratta in form di base, diversamente e'
  //        integrato by a file definition)
  TForm(const char* form, const char * code = "", int editlevel = 0, const char* desc = "");
  // @cmember Distruttore
  virtual ~TForm();
};


// @doc INTERNAL

// @class TForm_flags | Classe per la gestione dei flag di una <c TForm>
//
// @base public | TObject
class TForm_flags : public TObject

// @author:(INTERNAL) Guido, Angelo, Villa

{
// @access Public Member
public:
  // @cmember Indica se il campo e' automagico (determina da solo il suo valore 
  //          alla partenza della maschera)
  bool automagic : 1;
  // @cmember Indica se il campo e' abilitato
  bool enabled : 1;
  // @cmember Indica se il campo e' visibile
  bool shown : 1;
  // @cmember Indica se il campo e' stato modificato
  bool dirty : 1;
  // @cmember Indica se il campo possiede un carattere di fincatura sinistro
  bool finkl : 1;
  // @cmember Indica se il campo possiede un carattere di fincatura destro
  bool finkr : 1;
  // @cmember Indica se si tratta di un campo memo
  bool memo : 1;

// @access Protected Member
protected:
  // @cmember Permette di stampare i flags su file di testo
  void print_on(ostream& out) const;

// @access Public Member
public:
  // @cmember Costruttore
  TForm_flags();
  
  // @cmember Setta il flag di visibile
  void set_shown(bool b)   
  { shown = b; }
  // @cmember Setta il flag di fincatura sinistra
  void set_finkl(bool b)   
  { finkl = b; }
  // @cmember Setta il flag di fincatura destra
  void set_finkr(bool b)   
  { finkr = b; }
  // @cmember Setta il flag di campo memo
  void set_memo (bool b)   
  { memo  = b; }
  // @cmember Permette di stampare i flags sulla maschera di editing <p m>
  void print_on(TMask& m);
  // @cmember Legge i flgs dalla maschera <p m>
  void read_from(const TMask& m);
  
  // @cmember Aggiorna i flags con la stringa <p s>
  bool update(const char* s);
};

// @doc EXTERNAL

// @class TPrint_section | Classe per la gestione della stampa di una sezione di <c TForm>
//
// @base public | TArray
class TPrint_section : public TArray

// @author:(INTERNAL) Guido, Angelo, Villa

// @access:(INTERNAL) Private Member
{
  // @cmember:(INTERNAL) Maschera di edit della sezione corrente
  static TMask* _msk;    

  // @cmember:(INTERNAL) Altezza della sezione
  word _height;
  // @cmember:(INTERNAL) Offset prima colonna
  word _ofspc;
  // @cmember:(INTERNAL) Offset verticale intestazione colonna
  word _ofsvr;
  // @cmember:(INTERNAL) Numero di colonne se COLUMNWISE
  word _nfld;
  // @cmember:(INTERNAL) Flag di modifica parametri
  bool _dirty;
  // @cmember:(INTERNAL) Specifica la sezione COLUMNWISE
  bool _columnwise;
  // @cmember:(INTERNAL) Indica se si tratta di una sezione temporanea (da non salvare)
  bool _temp;

  // @cmember:(INTERNAL) <c TForm> a cui appartiene la sezione
  TForm* _form;
  // @cmember:(INTERNAL) Tipo della sezione da stampare (<p H>=header, <p B>=body
  //          <p F>=footer, <p G>=background)
  char _sec_type;
  // @cmember:(INTERNAL) Posizione della pagina da stampare (vedi <t pagetype>)
  pagetype _page_type;
  // @cmember:(INTERNAL) Indica se si tratta di una sottosezione
  bool _subsection;
  
  // @cmember:(INTERNAL) Lista dei campi da stampare
  TArray _item;
  // @cmember:(INTERNAL) Numero di ripetizione eseguite
  int _repeat_count;
  
  // @cmember:(INTERNAL) Offset delle colonne se COLUMNWISE
  int _tab[MAXCOLUMNS];
  
  // @cmember:(INTERNAL) Fa una copia della print_section
  const TPrint_section& copy(const TPrint_section& ps);
  
// @access Protected Member
protected:
  // @cmember Stampa la sezione su file di testo
  virtual void print_on(ostream& out) const;
  // @cmember Crea un nuovo <c TForm_item> di formato <p key> ritornandone un puntatore
  virtual TForm_item* parse_item(const TString& key);
  // @cmember Crea un nuovo <c TForm_item> ritornandone un puntatore (chiama <mf TForm_item::parse_item>)
  TForm_item* parse_item(TScanner& scanner);

  // @cmember Procedura che effettua il ricalcolo delle coordinate di <c TForm_item> nel caso il font sia cambiato
  static bool repos_fields(const char* name, int size);
  // @cmember Handler del bottone per editare in modo dettagliato un <c TForm_item>
  static bool detail_field_handler(TMask_field&, KEY);
  // @cmember Handler del bottone per editare gli specials di un <c TForm_item>
  static bool special_field_handler(TMask_field&, KEY);
  // @cmember Handler dello sheet presente nella maschera di edit della sezione
  static bool detail_field_notify (TSheet_field&, int, KEY);

// @access Public Member
public:
  // @cmember Ritorna la <c TPrintrow> della riga <p num>
  TPrintrow& row(int num);
  // @cmember Ritorna il <c TForm> a cui appartiene la sezione
  TForm& form() const
  { return *_form; }
  
  // @cmember Ritorna la lista dei campi da stampare
  TArray& field_array() 
  { return _item; }
  // @cmember Ritorna l'<p n>-esimo campo da stampare
  TForm_item& field(int n) const 
  { return (TForm_item&)_item[n]; }
  // @cmember Cerca e ritorna l'<p id>-esimo campo da stampare
  TForm_item& find_field(short id) const;
  // @cmember Rimuove uno o tutti i campi da stampare (chiama <mf TArray::destroy>)
  void destroy_field(int n, bool c = TRUE) 
  { _item.destroy(n, c); }
  // @cmember Rimuove tutti i campi da stampare (chiama <mf TArray::destroy>)
  void destroy_fields() 
  { _item.destroy(); }
  // @cmember Viene sostiuito il campo di posizione <p n> col campo <p f> (chiama <mf TArray::add>)
  void change_field(int n, TForm_item* f);
  // @cmember Viene inserito il campo di posizione <p n> col campo <p f> (chiama <mf TArray::insert>)
  void insert_field(int n, TForm_item* f);                 
  // @cmember Viene aggiunto i coda alla'array il campo <p f> (chiama <mf TArray::add>)
  void add_field(TForm_item* f);

  // @cmember Ritorna se si tratta di una sezione temporanea
  virtual bool& temp() 
  { return _temp; };
  // @cmember Ritorna se si tratta di una sezione temporanea
  virtual bool temp() const 
  { return _temp; };
  
  // @cmember Ritorna il numero di campi da stampare
  word fields() const 
  { return _item.items(); }
  // @cmember Ritorna il numero di campi stampabili (0 se non e' COLUMNWISE)
  word columns()      
  { tab(0); return _nfld; }
  // @cmember Ritorna l'altezza della sezione
  word height() const 
  { return _height; }
  // @cmember Ritorna l'offset della prima colonna
  word ofspc()  const 
  { return _ofspc; }
  // @cmember Ritorna l'offset verticale intestazione colonna
  word ofsvr()  const
  { return _ofsvr; }
  // @cmember Modifica i parametri di offset <p x> e <p y> del foglio
  void offset(int& x, int& y);
  // @cmember Setta il numero di ripetizioni eseguite
  void set_repeat_count(int x) 
  { _repeat_count = x; }

  // @cmember Setta l'altezza della sezione
  void set_height(word h)
  { _height = h; }
  
  // @cmember Controlla che si tratti di una sezione vaida (altezza e numero di campi diversi da 0)
  virtual bool ok() const 
  { return height() > 0 || fields() > 0; }

  // @cmember Azzera tutte le righe della sezione di stampa  
  void reset();
  // @cmember Aggiorna tutti i campi e li stampa
  virtual bool update();
  // @cmember Legge i campi dal file di testo (vedi <c TScanner>)
  bool parse(TScanner& scanner);

  // @cmember Legge dal record <p rec> altezza e offset prima colonna della sezione
  bool read_from(const TRectype& rec);
  // @cmember Settano il record <p rec> con i valori attuali della sezione
  void print_on(TRectype& rec);

  // @cmember Esegue l'edit della sezione di stampa
  bool edit(const char* title);
  // @cmember Ritorna il tipo della sezione da stampare (vedi <md TPrint_section::_sec_type>)
  char section_type() const 
  { return _sec_type; }
  // @cmember Ritorna il tipo di pagina da stampare (vedi <t pagetype>)
  pagetype page_type() const 
  { return _page_type; }

  // @cmember Ritorna TRUE se sono stati modificati i parametri
  bool dirty() const 
  { return _dirty; }
  // @cmember Setta il flag di modifica parametri
  void set_dirty(bool d = TRUE) 
  { _dirty = d; }
  // @cmember Ritorna TRUE se si tratta di una campo COLUMNWISE
  bool columnwise() const 
  { return _columnwise; }
  // @cmember Ritorna l'offset della colonna <p col> se COLUMNWISE
  int tab(int col);
  // @cmember Annulla (setta a -1) l'offset delle colonne se COLUMNWISE
  void reset_tabs();                                            
  
  // @cmember Operatore di assegnamento
  const TPrint_section& operator=(const TPrint_section& ps) 
  { return copy(ps); }
  // @cmember Costruttore
  TPrint_section(TForm* parent, char st, pagetype pt, bool subsection = FALSE);
  // @cmember Costruttore
  TPrint_section(const TPrint_section& ps) 
  { copy(ps); }
  // @cmember Distruttore
  virtual ~TPrint_section();
};


// @doc EXTERNAL

// @class TForm_item | Classe per la definizione per ogni campo del <c TForm>
//
// @base public | TObject
class TForm_item : public TObject

// @author:(INTERNAL) Guido, Angelo, Villa


{
  // @cfriend TPrint_section
  friend class TPrint_section;
  
  // @access:(INTERNAL) Private Member

  // @cmember:(INTERNAL) Flag del campo (vedi <c TForm_flags>)
  TForm_flags _flag;
  // @cmember:(INTERNAL) Gruppi a cui appartiene il campo
  TBit_array _group;
  // @cmember:(INTERNAL) Special attribuiti al campo (vedi <c TAssoc_array>)
  TAssoc_array _special;
  // @cmember:(INTERNAL) Indica se si tratta di un campo temporaneo (da non salvare)
  bool _temp;

// @access Protected Member
protected:       
  // @cmember:(INTERNAL) Sezione da stampare (vedi <c TPrint_section>)
  TPrint_section* _section;
  // @cmember Identificatore del campo
  short _id;
  // @cmember Coordinata X (in caratteri) del campo
  short _x;
  // @cmember Coordinata Y (in caratteri) del campo
  short _y;
  // @cmember Larghezza del campo (in caratteri)
  short _width;
  // @cmember Altezza del campo (in caratteri)
  short _height;
  // @cmember Altezza effettiva del campo
  short _effective_height;
  // @cmember Offset del campo rispetto l'inizio della colonna (usato per campi 
  //        appartenenti a sezioni COLUMNWISE)
  short _ofs;
  // @cmember Prompt del campo
  TString _prompt;
  // @cmember Descrizione del campo
  TString _desc;
  // @cmember Intestazione della colonna (usato per campi appartenenti a sezioni COLUMNWISE)
  TString _col_head;
  // @cmember Array di message che manda il campo
  TString_array _message;

  // @cmember Stampa sullo stream <p out> le caratteristiche del campo
  virtual void print_on(ostream& out) const;
  // @cmember Stampa sullo stream <p out> il corpo del campo
  virtual void print_body(ostream& out) const;

  // @cmember Legge dal file di testo identificatore, altezza e larghezza del campo
  virtual bool parse_head(TScanner&);
  // @cmember Legge dal file di testo il tipo di campo (prima riga)
  virtual bool parse_item(TScanner&);

  // @cmember Ritorna il messaggio <p m>-esimo del campo
  TToken_string& message(int m = 0);
  // @cmember Manda il messaggio al campo <p dest>
  void send_message(const TString& cmd, TForm_item& dest) const;
  // @cmember Esegue il messaggio <p m>
  bool do_message(int m = 0);
  
  // @cmember Stampa una stringa alla posizione indicata
  void string_at(int x, int y, const char* s);

  // @cmember Cerca nella definizione della variabile <p s> e ne ritorna
  //          l'<p n>-esimo elemento (0=tipo, 1=valore, 2=descrizione)
  const char* get_special_item(const char* s, int n) const;
  
  // @cmember Copia tutti i membri dell'oggetto base in fi. Viene chiamata dalla <mf TForm_item::dup>
  void  copy_to_form_item(TForm_item* fi) const;
  
// @access Public Member
public:
  // @cmember Duplica un TForm_item. Chiama la <mf TForm_item::copy_to_form_item>
  virtual TObject* dup() const;
  // @cmember Ritorna il numero identificatore del campo
  short id() const 
  { return _id; }
  // @cmember Ritorna il reference del numero identificatore del campo 
  virtual short& id()
  { return _id; };
  // @cmember Ritorna la larghezza del campo (in caratteri)
  virtual int width() const 
  { return _width; } 
  // @cmember Ritorna il reference della larghezza del campo (in caratteri)
  virtual short& width()
  { return _width; }
  // @cmember Ritorna l'altezza del campo (in caratteri)
  virtual int height() const 
  { return _height; }
  // @cmember Ritorna il reference dell'altezza del campo (in caratteri)
  virtual short& height()
  { return _height; }
  // @cmember Ritorna l'offset del campo rispetto l'inizio della colonna
  virtual short& ofs()
  { return _ofs; }
  // @cmember Ritorna l'altezza effettiva del campo
  virtual int effective_height() const
  { return _effective_height; }
  // @cmember Scrive la stringa <p s> alla posizione del TForm_item. Funzione che 
  //          per default non fa nulla. Ridefinita solo per TForm_number e TForm_string.
  virtual void put_paragraph(const char* s) 
  {};

  // @cmember Ritorna se si tratta di una campo temporaneo (reference)
  virtual bool& temp() 
  { return _temp; };
  // @cmember Ritorna se si tratta di una campo temporaneo
  virtual bool  temp() const 
  { return _temp; };
  // @cmember Ritorna se il campo e' memo
  bool has_memo() const 
  { return _flag.memo; }
  
// virtual short& x() { return _x; };

  // @cmember Setta la ccordinata X (in caratteri) del campo
  virtual void set_x(short x) 
  {_x=x;}
  // @cmember Ritorna la coordinata X del campo
  virtual short x();
  // @cmember Ritorna il reference della coordinata Y del campo
  virtual short& y() 
  { return _y; }
  // @cmember Ritorna la coordinata Y del campo
  virtual short y() const 
  { return _y; }
  // @cmember Ritorna la coordinata X del campo se e' COLUMNWISE (altrimenti <f CHECK>)
  virtual short get_column() 
  { CHECK(_section->columnwise(),"La sezione non e' COLUMNWISE"); return _x; }
  // @cmember Setta la coordinata X del campo se e' COLUMNWISE (altrimenti <f CHECK>)
  virtual void  set_column(short c) 
  {  CHECK(_section->columnwise(),"La sezione non e' COLUMNWISE"); _x = c;}
  // @cmember Ritorna il numero di campi da stampare
  virtual const int fields() 
  { return 0;}
  
  // @cmember Ritorna se si tratta di un campo visibile
  bool shown() const 
  { return _flag.shown; }
  // @cmember Ritorna se si tratta di un campo nascosto
  bool hidden() const 
  { return !_flag.shown; }
  // @cmember Ritorna se si tratta di un campo abilitato
  bool enabled() const 
  { return _flag.enabled; }
  // @cmember Ritorna se si tratta di un campo disabilitato
  bool disabled() const 
  { return !_flag.enabled; }
  // @cmember Ritorna se si tratta di un campo automagic (vedi <md TForm_flags::automagic>)
  bool automagic() const 
  { return _flag.automagic; }
  // @cmember Ritorna se il campo possiede un carattere si fincatura sinistra
  bool finkl() const 
  { return _flag.finkl; }
  // @cmember Ritorna se il campo possiede un carattere si fincatura destra
  bool finkr() const 
  { return _flag.finkr; }
  // @cmember Ritorna se si tratta di campo memo
  bool memo() const 
  { return _flag.memo; }

  // @cmember Legge da file di testo le caratteristiche del campo
  virtual bool parse(TScanner&);
  // @cmember Aggiorna il contenuto del campo e lo mette nella riga di stampa
  virtual bool update();

  // @cmember Compila la maschera coi dati del campo
  virtual void print_on(TMask& m);
  // @cmember Registra sul record i dati del campo
  virtual void print_on(TRectype& rform);
  // @cmember Compila la <c TToken_string> <p t> coi dati editabili del campo
  virtual void print_on_sheet_row(TToken_string& t) const;

  // @cmember Legge le caratteristiche di un campo da una <c TMask>
  virtual void read_from(const TMask& m);
  // @cmember Legge le caratteristiche di un campo da un <c TRectype>
  virtual bool read_from(const TRectype& rform);
  // @cmember Legge le caratteristiche di un campo da una <c TToken_string>
  virtual void read_from(TToken_string& s);

  // @cmember Edita il campo usando la maschera <p m>
  virtual bool edit(TMask& m); 

  // @cmember Ritorna il prompt del campo
  virtual const char* get() const 
  { return _prompt; }
  // @cmember Setta il prompt del campo
  virtual bool set(const char* s) 
  { _prompt = s; return TRUE; }

  // @cmember Ritorna un esempio del formato corrente
  virtual const char* example() const 
  { return ""; }

  // @cmember Ritorna se si tratta di un campo appartenente ad una sezione
  //        COLUMNWISE (<f CKECK> se non e' COLUNMNWISE)
  const TString& col_head() const
  {CHECK(_section->columnwise(),"La sezione non e' COLUMNWISE"); return _col_head;}
  // @cmember Setta se si tratta di un campo appartenente ad una sezione
  //        COLUMNWISE (<f CKECK> se non e' COLUNMNWISE)
  void set_col_head(const char* s)
  {CHECK(_section->columnwise(),"La sezione non e' COLUMNWISE"); _col_head = s;}

  // @cmember Ritorna il prompt del campo
  const TString& prompt() const 
  { return _prompt; }
  // @cmember Setta il prompt del campo
  void set_prompt(const char* s) 
  { _prompt = s; }
  
  // @cmember Ritorna il memo associato al campo. (<f CHECK> per un generico item)
  virtual TToken_string& memo_info();
  // @cmember Ritorna la picture del campo. (<f CHECK> per un generico item)
  virtual const TString& picture() const;
  // @cmember Setta la picture del campo. (<f CHECK> per un generico item)
  virtual void set_picture(const char*);

  // @cmember Ritorna la <c TPrint_section> del campo
  TPrint_section& section() const 
  { return *_section; }
  // @cmember Ritorna la <c TForm> della sezione del campo
  TForm& form() const 
  { return _section->form(); }
  // @cmember Cerca il campo identificato da <p id> !!!
  TForm_item& find_field(const TString& id) const;
  
  // @cmember Setta il flag di fincatura sinistra
  void set_finkl(bool d = TRUE) 
  { _flag.finkl = d; }
  // @cmember Setta il flag di fincatura destra
  void set_finkr(bool d = TRUE) 
  { _flag.finkr = d; }
  // @cmember Setta il flag di campo modificato
  void set_dirty(bool d = TRUE) 
  { _flag.dirty = d; }
  // @cmember Ritorna il flag di campo modificato
  bool dirty() const 
  { return _flag.dirty; }
  
  // @cmember Ritorna se il campo appartiene al gruppo <p g>
  bool in_group(byte g) const 
  { return g == 0 || _group[g]; }
  // @cmember Ritorna la descrizione del campo
  const TString& key() const 
  { return _desc; }
  // @cmember Riempie la <c TToken_string> <p row> coi dati del campo
  virtual void print_on(TToken_string& row) const;

  // @cmember Setta il flag di campo visibile
  virtual void show(bool on = TRUE) 
  { _flag.shown = on; }  
  // @cmember Nasconde il campo
  void hide() 
  { show(FALSE); }
  // @cmember Abilita/Disabilita il campo
  virtual void enable(bool on = TRUE);
  // @cmember Disabilita il campo (chiama <mf TForm_item::enable>)
  void disable() 
  { enable(FALSE); }
                                                     
  // @cmember Ritorna il numero di specials del campo
  int special_items() const 
  { return _special.items(); }
  // @cmember Ritorna gli specials del campo
  TAssoc_array& specials() const 
  { return (TAssoc_array&)_special; }
  
  // @cmember Riempie il TString_array <p r> passato per reference con i nomi delle variabili
  int get_special_names(TString_array& r);
  // @cmember Ritorna il valore dello special corrispondente al nome <p s>
  //          (chiama <mf TForm_item::get_special_item>)
  const char* get_special_value(const char* s) const 
  { return get_special_item(s, 1); }
  void TForm_item::set_special_value(const char* s, const char* val);
  // @cmember Ritorna il tipo dello special corrispondente al nome <p s>
  //          (chiama <mf TForm_item::get_special_item>)  
  const char* get_special_type (const char* s) const 
  { return get_special_item(s, 0); }
  // @cmember Ritorna la descrizione dello special corrispondente al nome <p s>
  //          (chiama <mf TForm_item::get_special_item>)  
  const char* get_special_desc (const char* s) const 
  { return get_special_item(s, 2); }
  
  // @cmember Costruttore
  TForm_item(TPrint_section* section);
  // @cmember Distruttore
  virtual ~TForm_item()
  {}
};


#endif
