#ifndef __MASKFLD_H
#define __MASKFLD_H

#ifndef __DATE_H
#include <date.h>
#endif

#ifndef __REAL_H
#include <real.h>
#endif

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

class TControl;      // __CONTROL_H 
class TText_control;
class TPushbutton_control;

class TRelation;     // __RELATION_H
class TCursor;
class TFieldref;

class TArray_sheet;  // __SHEET_H

class TMask_field;   // Convenience


// @doc EXTERNAL

// @enum Tipo di check da eseguire su un controllo
enum CheckType {
  CHECK_NONE,       // @emem Nessun controllo
  CHECK_NORMAL,     // @emem Controllo normale (non e' un campo obbligatorio)
  CHECK_REQUIRED,   // @emem Controlla se il campo non e' vuoto e fa un check normale
  CHECK_SEARCH      // @emem Controlla se il campo c'e' ma non da' nessuna segnalazione se e' errato
};  

// @doc EXTERNAL

// @enum Momento di richiesta del check
enum CheckTime {
  RUNNING_CHECK,  // @emem Check chiamato mentra la maschera sta andando
  STARTING_CHECK, // @emem Check chiamato al caricamento della maschera
  FINAL_CHECK };  // @emem Check chiamato quando la maschera si sta fermando
  
// @type CONTROL_HANDLER | Prototipo funzione per gestire i tasti speciali all'interno di un controllo
typedef bool (*CONTROL_HANDLER)(TMask_field& field, KEY key);

// @doc EXTERNAL

// @class TMask_field | Classe per la definizione delle operazioni sui campi di
//                      una maschera
//
// @base public | TObject
class TMask_field : public TObject
// @author:(INTERNAL)Guido
{
  // @cfriend TMask
  friend class TMask;  
  // @cfriend TSheet
  friend class TSheet;  
  
// @access:(INTERNAL) Private Member

  // @cmember:(INTERNAL) Maschera all'interno del quale e' contenuto il campo
  TMask* _mask;

  // @cmember:(INTERNAL) Gruppi cui appartiene il campo
  TBit_array* _groups;

  // @access Protected Member
protected:
  // @cmember Controllo vero e proprio
  TControl* _ctl;
  
  // @cmember <t TControl_data> 
  // @comm Struttura usata solo durante la creazione di un controllo 
  struct TControl_data
  {           
    short _dlg;            // Identifier
    short _x, _y;          // Position
    short _width;          // Width
    short _height;         // Height 
    word _size;            // Buffer size
    short _decimals;       // Precision
    TString _prompt;       // Prompt
    TString _flags;        // Flags
    short _bmp_up;         // Bitmap up
    short _bmp_dn;         // Bitmap down
    TToken_string _park;   // Work string
    void reset();
  };
  static TControl_data _ctl_data;

  // @cmember <t TField_Flags> | _flags | | Flag indicante lo stato del campo
  struct TField_Flags
  {
    bool automagic      : 1; 
    bool button         : 1;
    bool dirty          : 2;    // Modified during run ?
    bool enabled        : 1;    // Is editable
    bool enable_default : 1;
    bool firm           : 1;    // Is the current firm ?
    bool focusdirty     : 1;    // Modified during focus ?
    bool ghost          : 1;
    bool password       : 1;
    bool persistent     : 1;
    bool rightjust      : 1;
    bool roman          : 1;    // Is a Roman number ?
    bool shown          : 1;    // Is visible
    bool show_default   : 1;
    byte trim           : 2;    // Trim the string 
    bool uppercase      : 1;
    bool exchange       : 1;    // Value exchange
    bool zerofilled     : 1;
    bool pipeallowed    : 1;
    
    TField_Flags();
    char update(const char*);
  } _flags;

  // @cmember Costruisce il campo da file 
  void construct(TScanner& scanner, WINDOW parent);
  // @cmember Costruisce il campo con i suoi parametri
  void construct(short id, const char* prompt, int x, int y, int len, WINDOW parent, const char* flags = "", int width = 0);

  // @cmember Legge la testata del controllo dal file .msk <p scanner>
  virtual void parse_head(TScanner& scanner);
  // @cmember Legge una riga di definizione del controllo dal file .msk <p scanner>
  virtual bool parse_item(TScanner& scanner);

  // @cmember Crea il controllo (chiama <mf TMask_field::wincreate>)
  virtual void create(WINDOW parent) pure;

  // @cmember Setta il focus sul campo
  virtual void highlight() const;

  // @cmember Manda al campo <p to> un tasto (chiama <mf TMask::send_key>)
  void send_key(KEY k, short to);
  
  // @access Public Member
public: // TObject
  virtual bool is_kind_of(word cid) const;
    
public:
  // @cmember Converte una stringa in un identificatore di controllo
  short atodlg(const char* s) const;

  // @cmember Ritorna la finestra padre
  virtual WINDOW parent() const;
  
  RCT& get_rect(RCT& r) const;
  void set_rect(const RCT& r);
                
  // @cmember Ritorna l'identificatore del controllo
  virtual short dlg() const;

  // @cmember Controlla se si tratta di un controllo corretto
  virtual bool ok() const;
  
  // @cmember Ritorna TRUE se il campo e' stato modificato
  bool dirty() const
  { return _flags.dirty; }
  // @cmember Ritorna TRUE se il campo e' stato modificato dall'ultima volta che ha ricevuto il focus
  bool focusdirty() const 
  { return _flags.focusdirty; }
  // @cmember Setta lo stato di focusdirty del campo 
  void set_focusdirty(bool d = TRUE) 
  { _flags.focusdirty = d; }
  // @cmember Setta lo stato di dirty del campo 
  void set_dirty(bool d = TRUE);
  
  // @cmember Abilita il trim degli spazi
  void set_trim(bool t) 
  { _flags.trim = t ? 3 : 0; }
  
  // @cmember Setta la giustificazione a destra del campo
  void set_justify(bool r) 
  { _flags.rightjust = r; }
  
  // @cmember Verifica la giustificazione a destra del campo
  bool right_justified() const
  { return _flags.rightjust; }
  
  // @cmember Ritorna TRUE se il campo e' in maiuscolo
  bool uppercase() const
  { return _flags.uppercase; }

  // @cmember Ritorna TRUE se il campo e' zerofilled
  bool zerofilled() const
  { return _flags.zerofilled; }

  // @cmember Verifica se l'inserimento del carattere pipe e' stato abilitato
  bool pipe_allowed() const
  { return _flags.pipeallowed; }

  // @cmember Consente l'inserimento del carattere pipe
  void allow_pipe(bool r = TRUE) 
  { _flags.pipeallowed = r; }

  // @cmember Ritorna il nome della classe
  virtual const char* class_name() const;
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;
  
  // @cmember Ritorna TRUE se il campo e' un numero romano    
  bool roman() const 
  { return _flags.roman; }
  // @cmember Ritorna TRUE se il campo e' automagic
  bool automagic() const 
  { return _flags.automagic; }
  // @cmember Ritorna TRUE se ha un bottone di campo
  bool has_button() const 
  { return _flags.button; }
  // @cmember Ritorna TRUE se si tratta di campo fantasma
  bool ghost() const 
  { return _flags.ghost; }
  // @cmember Ritorna TRUE se si tratta di campo in valuta
  bool exchangeable() const 
  { return _flags.exchange; }

  // @cmember Controlla se il campo appartiene ad una chiave di ricerca
  virtual bool in_key(byte) const
  { return FALSE; }
  // @cmember Controlla se il campo ha un check
  virtual bool has_check() const 
  { return FALSE;}
  // @cmember Controlla se il campo ha una richiesta
  virtual bool has_query_button() const 
  { return FALSE;}
  // @cmember Ritorna il campo corrispondente su record
  virtual const TFieldref* field() const
  { return NULL; }
  
  // @cmember Ritorna il tipo di checktype del campo
  virtual void check_type(CheckType);

  // @cmember Ritorna lo stato di checktype del campo
  virtual CheckType check_type() const 
  { return CHECK_NONE; }
  // @cmember Ritorna TRUE se il checktype del campo e' <p CHECK_REQUIRED>
  bool required() const 
  { return check_type() == CHECK_REQUIRED; }
  
  // @cmember Controlla la validita' del campo
  virtual bool check(CheckTime = RUNNING_CHECK) 
  { return TRUE;}
  
  // @cmember Azzera il contenuto del campo
  virtual void reset();

  // @cmember Abilita/disabilita il campo (lo rende scrivibile)
  virtual void enable(bool on = TRUE);
  
  // @cmember Abilita/disabilita il campo (chiama <mf TMask_field::enable>)
  void disable()
  { enable(FALSE); }
  // @cmember Controlla se un campo e' abilitato
  virtual bool enabled() const 
  { return _flags.enabled; }
  // @cmember Rimette lo stato di dis/abilitazione del campo a seconda di come era settato sul file
  void enable_default();
  // @cmember Controlla se il campo e' abilitato di default
  bool enabled_default() const 
  { return _flags.enable_default; }
  
  // @cmember Permette di rendere visibile/invisibile un campo
  virtual void show(bool on = TRUE);
  // @cmember Permette di rendere invisibile un campo (chiama <mf TMask_field::enable>)
  void hide() 
  { show(FALSE); }
  // @cmember Ritorna TRUE se il campo e' visibile
  bool shown() const 
  { return _flags.shown; }
  // @cmember Ritorna TRUE se il campo e' nascosto
  bool hidden() const 
  { return !shown(); }
  
  // @cmember Rimette lo stato di in/visibilta' del campo a seconda di come era
  //              settato sul file
  void show_default();

  // @cmember Ritorna TRUE se il campo e' sia visibile che abilitato
  bool active() const;  
  
  // @cmember Setta l'handler del controllo
  virtual void set_handler(CONTROL_HANDLER);
  
  // @cmember Ritorna TRUE se il campo e' di tipo operable
  virtual bool is_operable() const { return FALSE; }
  // @cmember Ritorna TRUE se il campo e' di tipo editable
  virtual bool is_editable() const { return FALSE; }
  // @cmember Ritorna TRUE se il campo e' di tipo edit
  virtual bool is_edit() const { return FALSE; }

  // @cmember Permette di spedire il check
  bool to_check(KEY k, bool checkrun = FALSE) const;
  
  // @cmember Gestisce la chiamata all'handler del campo
  virtual bool on_hit();

  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);

  // @cmember Setta il contenuto del campo inserendo la stringa <p s>
  virtual void set(const char* s);
  
  // @cmember Setta il contenuto del campo inserendo il numero <p n>
  void set(long n);
  
  // @cmember Ritorna il contenuto del campo
  virtual const TString& get() const;
  
  virtual bool empty() const { return FALSE; }
  
  // @cmember Ritorna la dimensione del buffer associato al campo
  virtual word size() const 
  { return 0; }
  
  // @cmember Ritorna il prompt del campo
  virtual const char* prompt() const;
  // @cmember Setta il prompt del campo
  virtual void set_prompt(const char* p);
  
  // @cmember Controlla se il campo appartiene al gruppo <p group> (TRUE se appartiene)
  bool in_group(byte group) const 
  { return _groups ? (*_groups)[group] : FALSE; }
  // @cmember Assegna il campo al gruppo <p group>
  void set_group(byte group);

  // @cmember Setta il focus al campo
  virtual void set_focus() const;
  
  // @cmember Crea una message-box relativamente al campo (chiama <f message_box>)
  bool message_box(const char* fmt, ...) const;
  // @cmember Crea una warning-box relativamente al campo (chiama <f warning_box>)
  bool warning_box(const char* fmt, ...) const;
  // @cmember Crea una error-box relativamente al campo (chiama <f error_box>)
  bool error_box(const char* fmt, ...) const;
  // @cmember Crea una yesno-box relativamente al campo (chiama <f yesno_box>)
  bool yesno_box(const char* fmt, ...) const;
  // @cmember Crea una yesnocancel-box relativamente al campo (chiama <f yesnocancel_box>)
  KEY yesnocancel_box(const char* fmt, ...) const;
  
  // @cmember Ritorna per riferimento la maschera di appartenenza del campo
  TMask& mask() const 
  { return *_mask; }
  // @cmember Costruttore
  TMask_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TMask_field();
};

// @doc EXTERNAL

// @struct TField_Flags | Flag indicante il settaggio del campo
// @comm ATTENZIONE: Questa struttura e' definita ed utilizzata unicamente nella classe
//     <c TMask_field>
// @field bool | automagic: 1 | Indica se il campo e' automagic
// @field bool | dirty: 2 | Indica se il campo e' stato modificato
// @field bool | enabled: 1 | Indica se il campo e' editabile
// @field bool | enable_default: 1 | Indica se il campo e' abilitato di default
// @field bool | firm: 1 | Indica se il campo appartiene alla ditta corrente
// @field bool | focusdirty: 1 | Indica se il campo e' stato modificat mentre aveva il focus
// @field bool | ghost: 1 | Indica se il campo e' ghost
// @field bool | password: 1 | Indica che e' un campo password (no si vede quello che scrivi)
// @field bool | persistent: 1 | Indica se il valore del campo deve rimanere anche quando viene ricaricata la maschera
// @field bool | rightjust: 1 | Indica se il campo e' allineato a destra
// @field bool | roman: 1 | Indica se il campo contiene un numero romano
// @field bool | shown: 1 | Indica se il campo e' visibile
// @field bool | show_default: 1 | Indica se il campo e' visibile di default
// @field bool | trim: 1 | Indica se bisogna fare il trim della stringa (vedi <mf TString::trim>)
// @field bool | uppercase: 1 | Indica se il campo e' maiuscolo
// @field bool | exchange: 1 | Indica se si tratta di un cambio valuta
// @field bool | zerofilled: 1 | Indica se il campo e' zerofilled
// @field bool | pipeallowed: 1 |  Indica se il campo e' pipeallowed
// @field void | TField_Flags() | Costruttore
// @field char | update(const char*) | Aggiorna i bit della struttura secondo i valori letti da file

class TText_field : public TMask_field
{
protected:                 
  virtual void create(WINDOW parent);

public: // TObject
  word class_id() const;
  bool is_kind_of(word cid) const;
  
public:
  TText_field(TMask* m) : TMask_field(m) {}
  virtual ~TText_field() {}
};

// @doc EXTERNAL

// @class TGroup_field | Classe per la gestione del disegno dei group box
//
// @base public | TMask_field
class TGroup_field : public TMask_field
// @author:(INTERNAL) Guido
{
  // @access Protected Member
protected:
  // @cmember Legge un item del controllo dal file <p scanner>
  virtual void parse_head(TScanner& scanner);
  // @cmember Crea il controllo
  virtual void create(WINDOW parent);

  // @access Public Member
public:  
  // @cmember Costruttore
  TGroup_field(TMask* mask);
  virtual ~TGroup_field() {}
};



class TOperable_field : public TMask_field
{                
  // @cmember Comandi da eseguire in caso di modifica del campo
  TString_array* _message;
  
  // @cmember Handler del controllo
  CONTROL_HANDLER _handler;

protected:  // TMask_field
  bool handler(KEY k);

  virtual bool parse_item(TScanner& scanner);
  virtual bool is_operable() const { return TRUE; }
  virtual bool on_hit();
  
  TToken_string* message(int m, bool crea = FALSE);

  // @cmember Setta il focus sul campo
  virtual void highlight() const;
  
public:
  virtual bool is_kind_of(word cid) const;

  // @cmember Esegue processo in background
  virtual void on_idle() 
  {}

  // @cmember Esegue il messaggio <p n>-esimo sul campo
  bool do_message(int n);
  
  // @cmember Controlla se il campo ha un messaggio
  virtual bool has_message() const 
  { return _message != NULL; }

  // @cmember Setta l'handler del controllo
  virtual void set_handler(CONTROL_HANDLER handler) 
  { _handler = handler; }
  
  // @cmember Setta il focus al campo
  virtual void set_focus() const;

  // @cmember Gestisce il tasto <p k>
  virtual bool on_key(KEY k);
  
  // @cmember Abilita/disabilita il campo (lo rende scrivibile) (vedi <mf TMask_field::enable>)
  virtual void enable(bool on = TRUE);
  
  // @cmember Setta il valore del cambio nel campo
  virtual void exchange(bool, const real&) 
  { }

  TOperable_field(TMask* m);
  virtual ~TOperable_field();
};

// @doc EXTERNAL

// @class TButton_field | Classe per la gestione dei campi bottone
//
// @base public | TMask_field
class TButton_field : public TOperable_field

// @author:(INTERNAL) Guido
{
  // @access:(INTERNAL) Private Member
  
  // @cmember:(INTERNAL) Valore della combinazione di tasti che sostituisce il bottone
  KEY _virtual_key;
  // @cmember:(INTERNAL) Tasto generato quando viene premuto il bottone che si sta gestendo
  KEY _exit_key;
  
  // @access Protected Member
protected:
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;
  
  // @cmember Ritorna TRUE se il controllo deriva dalla classe cid
  virtual bool is_kind_of(word cid) const;

  // @cmember Crea il controllo
  virtual void create(WINDOW parent);

  // @cmember Legge un item del controllo dal file <p scanner>
  void parse_head(TScanner& scanner);
  // @cmember Legge un item del controllo dal file <p scanner>
  bool parse_item(TScanner& scanner);

  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);

public:
  // @cmember Ritorna il valore della combinazione di tasti che sostituiscono il bottone
  KEY virtual_key() const
  { return _virtual_key; }
  // @cmember Ritorna il valore del tasto di uscita
  KEY exit_key() const
  { return _exit_key; }
  
  void set_hot_key(KEY k) { _virtual_key = _exit_key = k; }
  void set_bmp(short up, short dn);

  // @cmember Costruttore
  TButton_field(TMask* mask);
  virtual ~TButton_field() {}
};                          

class TEditable_field : public TOperable_field
{ 
  // @cmember Campo su file
  TFieldref* _field;

  // @cmember:(INTERNAL) Prompt del campo
  TText_control* _prompt;

  // @cmember:(INTERNAL) Chiave al quale appartiene il campo
  TBit_array* _keys;
  
  // @cmember Messaggi da mandare in caso di errore sul campo
  TString* _warning;
  
  // @cmember:(INTERNAL) Stringa definibile dall'utilizzatore della classe da utilizzare a piacimento
  TToken_string* _userdata;

  struct TValidation_data
  {
    // @cmember Identificatore della funzione di validazione
    int _func;
    // @cmember Parametri da passare alla funzione di validazione
    TArray _parms;
  };  
  TValidation_data* _validate;

protected:  // TMask_field
  virtual bool parse_item(TScanner& scanner);

protected:
  // @cmember Valore corrente del campo
  TString _str;
  
  word create_prompt(WINDOW parent, word width, word heigth);
  
  virtual const char* reformat(const char* data) const;
  virtual TString& get_window_data() pure;
  virtual void set_window_data(const char* data) pure;
  
  int validate_func() const { return _validate ? _validate->_func : -1; }

public: // TMask_field        
  // @cmember Ritorna il prompt del campo
  virtual const char* prompt() const;
  
public:
  bool test_key_complete(bool normal = TRUE) const;
  // @cmember Controlla se il campo appartiene alla chiave <p key> (TRUE se appartiene)
  bool in_key(byte key) const
  { return _keys ? (*_keys)[key] : FALSE; }
  // @cmember Setta il campo alla chiave <p key>
  void set_key(byte key);
  // @cmember Rimuove il campo dalla chiave <p key>
  void reset_key(byte key);
  // @cmember Ritorna l'ultima chiave di appartenenza del campo
  word last_key() const;
  // @cmember Ritorna l'ultima chiave di appartenenza del campo
  word first_key() const;
  // @cmember Verifica che il campo abbia almeno una chiave in con il campo <p f>
  bool has_a_common_key(const TMask_field & f) const;
 
  // @cmember Ritorna il nome del campo corrsipondente sul file
  virtual const TFieldref* field() const 
  { return _field; }
  // @cmember Setta il nome del campo corrsipondente sul file
  void set_field(const TString& fr);
  
  // @cmember Legge dalla relazione il valore del campo
  bool autoload(const TRelation& r);

  // @cmember Scrive sulla relazione il valore del campo
  virtual bool autosave(TRelation& r) const;
  
  // @cmember Chiama l' eventuale funzione di validazione
  bool validate(KEY k);   
  
  bool has_warning() const { return _warning != NULL; }
  void set_warning(const char* w);
  const char* get_warning() const;
  
  virtual void show(bool on);
  
  virtual void set_prompt(const char* p);

  // @cmember Setta il contenuto del campo inserendo la stringa <p s>
  virtual void set(const char* s);

  // @cmember Ritorna il contenuto del campo
  virtual const TString& get() const;
  
  // @cmember Trasforma una stringa su file in una rappresentabile a video
  virtual const char* raw2win(const char* r) const;
 
  // @cmember Trasforma una stringa a video in un valore su file
  virtual const char* win2raw(const char* w) const;
  
  // @cmember Ritorna TRUE se il campo e' di tipo editable
  virtual bool is_editable() const { return TRUE; }
  
  TEditable_field(TMask* m);
  virtual ~TEditable_field();
};


// @doc EXTERNAL

// @class TBoolean_field | Classe per la gestione dei campi boolean (check box)
//
// @base public | TEditable_field
class TBoolean_field : public TEditable_field

// @author:(INTERNAL) Guido
{
  // @access Protected Member
protected:   // TMask_field
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;

  // @cmember Crea il controllo
  virtual void create(WINDOW parent);
  
  // @cmember Legge un item del controllo dal file <p scanner>
  virtual bool parse_item(TScanner& scanner);

protected: // TOperable
  // @cmember Gestisce la chiamata all'handler del campo
  virtual bool on_hit();
  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);

protected: // TEditable  
  // @cmember Riaggiusta una stringa in formato RAW
  virtual const char* reformat(const char* raw) const;
  virtual TString& get_window_data();
  virtual void set_window_data(const char* data);
  virtual void set_prompt(const char* p);
  
  // @access Public Members
public:
  // @cmember Costruttore
  TBoolean_field(TMask* mask);
  
  // @cmember Distruttore
  virtual ~TBoolean_field() 
  {}
};


///////////////////////////////////////////////////////////
// TBrowse_button
///////////////////////////////////////////////////////////

class TEdit_field;

class TBrowse_button : public TObject
{ 
  TEdit_field* _fld;  

protected:
  // @cmember Ritorna il primo valore di <p _fld>
  TEdit_field& field() const
  { return *_fld; }

  // @cmember Ritorna il campo <p n>-esimo
  TEditable_field& field(short id) const;

public:             
  // @cmember Controlla la sintassi della input del campo e ne setta i membri
  virtual void parse_input(TScanner& scanner) pure;

  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  virtual void parse_output(TScanner& scanner) pure;
          
  virtual KEY run() pure;
  
  // @cmember Controlla la validita' del campo
  virtual bool check(CheckTime = RUNNING_CHECK) pure;
  
  virtual bool is_browse() const { return FALSE; }
  
  TBrowse_button(TEdit_field* f);
  virtual ~TBrowse_button();
};


///////////////////////////////////////////////////////////
// TBrowse
///////////////////////////////////////////////////////////
                
// @class TList_sheet | Classe per la gestione dei list sheet
class TList_sheet : public TBrowse_button
// @author:(INTERNAL) Guido
{
  // @access:(INTERNAL) Private Memeber

  // @cmember:(INTERNAL) Numero di riga corrente dello sheet
  int _row;
  
  // @cmember:(INTERNAL) Titolo dello sheet
  TString       _caption;
  
  // @cmember:(INTERNAL) Testate delle colonne dello sheet
  TToken_string _head;
  
  // @cmember:(INTERNAL) Righe dello sheet
  TString_array _data;

  // @cmember:(INTERNAL) Campi di input sulla maschera
  TToken_string _inp_id;
  
  // @cmember:(INTERNAL) Campi di output sulla maschera
  TToken_string _out_id;

  // @access Protected Member
protected:
  // @cmember Ritorna il numero di riga selezionata
  int do_input();
  // @cmember Scrive l'output della ricerca sulla maschera
  void do_output(CheckTime = RUNNING_CHECK);

  // @cmember Controlla la sintassi della input del campo e ne setta i membri 
  void parse_input(TScanner& scanner);
  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  void parse_output(TScanner& scanner);
  
  // @access Public Memeber
public:
  // @cmember Legge dal file gli item dello sheet
  void parse_item(TScanner& scanner);

  // @cmember Controlla la validita' del campo
  virtual bool check(CheckTime = RUNNING_CHECK);

  // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca
  virtual KEY run();
  
  TString_array& rows_array() { return _data; }
  
    // @cmember Costruttore
  TList_sheet(TEdit_field* f, const char* caption, const char* head);
  // @cmember Distruttore
  virtual ~TList_sheet();
};
                
// @doc INTERNAL

// @class TBrowse | Classe per la definizione dei campi con ricerca
class TBrowse : public TBrowse_button
// @author:(INTERNAL) Guido
{
  // @access:(INTERNAL) Private Member

  // @cmember:(INTERNAL) Relazione della ricerca    
  TRelation* _relation;
  // @cmember:(INTERNAL) Cursore sulla relazione
  TCursor* _cursor;
  // @cmember:(INTERNAL) Comando da eseguire alla pressione del tasto Gestione
  TString _insert;
  // @cmember:(INTERNAL) Filtro sul cursore
  TString _filter;
  // @cmember:(INTERNAL) Record selezionato
  long _rec;
  // @cmember:(INTERNAL) Indica se e' presente un campo secondario nella ricerca
  bool _secondary;
  // @cmember:(INTERNAL) Indica se sul campo e' gia' stato effettuato il check
  bool _checked;

  // @cmember:(INTERNAL) Testata della maschera di ricerca
  TToken_string _head;
  // @cmember:(INTERNAL) Item della maschera di ricerca
  TToken_string _items;
  // @cmember:(INTERNAL) Campi di input sulla maschera
  TToken_string _inp_id;
  // @cmember:(INTERNAL) Campi di input sul file
  TToken_string _inp_fn;
  // @cmember:(INTERNAL) Campi di output sulla maschera
  TToken_string _out_id;
  // @cmember:(INTERNAL) Campi di output sul file
  TToken_string _out_fn;

  // @access Protected Member
protected:
  // @cmember Azzera i campi di output sulla maschera
  void do_clear(CheckTime t);
  // @cmember Chiama la maschera di gestione della ricerca
  bool do_link(bool insert);

  // @cmember Crea lista identificatori di ricerca
  TToken_string& create_siblings(TToken_string& siblings);

  // @access Public Member
public:
  // @cmember Ritorna il numero di inputs senza contare quelli che funzionano
  //          solo da filtro
  int input_fields();

  // @cmember Ritorna la lista completa degli identificatori dei campi di input
  const char* get_input_fields() const;
  
  // @cmember Ritorna la lista completa dei nomi dei campi di input
  const char* get_input_field_names() const;
  
  // @cmember Ritorna la lista completa dei campi di output
  const char* get_output_fields() const;

  // @cmember Ritorna il numero di campi non vuoti e non filtrati
  int do_input(bool filter = FALSE);

  // @cmember Scrive l'output della ricerca sulla maschera
  void do_output(CheckTime = RUNNING_CHECK);

  // @cmember Costruttore
  TBrowse(TEdit_field* f, TRelation* r, int key = 1, const char* filter = "");
  // @cmember Costruttore
  TBrowse(TEdit_field* f, TCursor* c);
  // @cmember Distruttore
  ~TBrowse();

  // @cmember Controlla la sintassi della join del campo e ne setta i membri 
  void parse_join(TScanner& scanner);
  // @cmember Controlla la sintassi della input del campo e ne setta i membri
  void parse_input(TScanner& scanner);
  // @cmember Controlla la sintassi della display del campo e ne setta i membri
  void parse_display(TScanner& scanner);
  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  void parse_output(TScanner& scanner);
  // @cmember Controlla la sintassi della insert del campo e ne setta i membri
  void parse_insert(TScanner& scanner);
  // @cmember Controlla la sintassi della copy del campo e ne setta i membri
  bool parse_copy(const TString& what, const TBrowse& b);

  // @cmember Permette di settare il comando alla pressione del tasto Gestione
  void set_insert(const char* s)
  { _insert = s;}
  // @cmember Ritorna il valore di <p _insert>
  const TString& get_insert() const
  { return _insert;}
  // @cmember Ritorna il valore di <p _filter>
  const TString& get_filter() const
  { return _filter;}

  // @cmember Controlla la validita' del campo
  bool check(CheckTime = RUNNING_CHECK);
  // @cmember Controlla se il campo puo' essere vuoto
  bool empty_check();
  // @cmember Ritorna il valore di <p _head>
  const TToken_string& head() const
  { return _head;}
  // @cmember Ritorna il valore di <p _items>
  const TToken_string& items() const
  { return _items;}
  // @cmember Ritorna il valore di <p _cursor>
  TCursor* cursor() const
  { return _cursor;}
  // @cmember Ritorna il valore di <p _checked>
  bool checked() const
  { return _checked;}
  // @cmember Ritorna il valore di <p _secondary>
  bool secondary() const
  { return _secondary;}
  
  virtual bool is_browse() const { return TRUE; }

  // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca
  virtual KEY run();
};


// @doc EXTERNAL

// @class TEdit_field | Classe per la definizione dei campi editabili
//
// @base public | TEditable_field
class TEdit_field : public TEditable_field
{
  // @access Protected Member
protected:
  // @cmember Formato che deve avere il campo
  TString _picture;
  
  // @cmember Dimensione del buffer del campo
  word _size;
  
  // @cmember Accettabilita' di valori nulli
  CheckType _check;
  // @cmember Controllo da effettuare anche in <e TMaskmode.MODE_QUERY>
  bool _forced;
  // @cmember Controllo abilitato
  bool _check_enabled;

  // @cmember Oggetto che contiene la ricerca e il controllo del campo
  TBrowse_button* _browse;

  // @cmember Ritorna la browse
  const TBrowse* parse_browse(TScanner& scanner) const;

  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;
  // @cmember Legge la testata del controllo dal file <p scanner>
  virtual void parse_head(TScanner& scanner);
  // @cmember Legge un item del controllo dal file <p scanner>
  virtual bool parse_item(TScanner& scanner);
  
  // @cmember Crea il controllo
  virtual void create(WINDOW parent);

  // @cmember Ritorna <p data> formattato secondo i flags settati del campo
  virtual const char* reformat(const char* data) const;

  // @cmember Scrive il valore del campo direttamente sulla finestra del controllo
  virtual void set_window_data(const char* data);
  
  // @cmember Mostra un messaggio di errore di default per il campo
  bool default_error_box() const;

  // @access Public Member
public:
  // @cmember Gestisce la chiamata all'handler del campo
  virtual bool on_hit();
  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);
  // @cmember Controlla se il campo ha un check
  virtual bool has_check() const;
  // @cmember Controlla se il campo ha una ricerca
  virtual bool has_query_button() const
  { return _browse != NULL || _flags.button; }
  
  // @cmember Ritorna TRUE se il campo e' di tipo edit
  virtual bool is_edit() const { return TRUE; }
  
  // @cmember Legge il valore del campo direttamente dalla finestra del controllo
  virtual TString& get_window_data();

  // @cmember Converte da campo a video
  virtual const char* raw2win(const char* r) const;
  
  // @cmember Converte da video a campo
  virtual const char* win2raw(const char* w) const;
  
  // @cmember Ritorna TRUE se il campo e' vuoto
  virtual bool empty() const { return _str.empty(); }

  // @cmember Ritorna la dimensione del buffer associato al campo
  virtual word size() const { return _size; }

  // @cmember Ritorna il tipo di check assegnato al campo (vedi <t Checktype>)
  virtual CheckType check_type() const
  { return _check; }

  // @cmember Setta il tipo di check da assegnare al campo (vedi <t Checktype>)
  void check_type(CheckType c)
  { _check = c; }

  // @cmember Controlla se un campo e' forced
  bool forced() const
  { return _forced;}

  // @cmember Esegue il controllo
  virtual bool check(CheckTime = RUNNING_CHECK);

  // @cmember Ritorna l'oggetto _browse
  TBrowse* browse() const    
  { return (_browse && _browse->is_browse()) ? (TBrowse*)_browse : NULL; }

  // @cmember Ritorna l'oggetto _sheet
  TList_sheet* sheet() const
  { return (_browse && !_browse->is_browse()) ? (TList_sheet*)_browse : NULL;}
  
  // @cmember Permette di abilitare/disabilitare il campo
  virtual void enable(bool on = TRUE);

  // @cmember Permette di abilitare/disabilitare il check del campo
  void enable_check(bool on = TRUE) ;
  
  // @cmember Attiva o no la selezione automatica del testo
  void autoselect(bool on);
  
  // @cmember Controlla se un campo ha abilitato o disabilitato il check (TRUE se abilitato)
  bool check_enabled() const
  { return _check_enabled;}

  // @cmember Ritorna la picture del campo
  const char* picture() const
  { return _picture; }

  // @cmember Costruttore
  TEdit_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TEdit_field();
};

// @doc EXTERNAL

// @class TReal_field | Classe per la gestione dei campi di numeri reali
//
// @base public | TEdit_field
class TReal_field : public TEdit_field
// @author:(INTERNAL) Guido
{
  // @access:(INTERNAL) Private Member

  // @cmember:(INTERNAL) Numero di decimali del campo
  int _decimals;

  // @access Protected Member
protected:   // TMask_field
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;

  virtual bool is_kind_of(word cid) const;

  // @cmember Crea il controllo
  virtual void create(WINDOW parent);

  // @cmember Legge un item del controllo dal file .msk <p scanner>
  virtual void parse_head(TScanner& scanner);
  // @cmember Legge una riga di definizione del controllo dal file .msk <p scanner>
  virtual bool parse_item(TScanner& scanner);

protected:   // TEditable_field
  virtual const char* reformat(const char* data) const;

  virtual const char* win2raw(const char* data) const;
  
  virtual const char* raw2win(const char* data) const;

  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);
  
protected:
  // @cmember Setta il valore del cambio nel campo
  virtual void exchange(bool show_value, const real& n);

  // @access Public Member
public:
  // @cmember Setta la precisione (numero di decimali) del reale e la sua picture
  void set_decimals(int d);
  // @cmember Ritorna la precisione del reale (numero di decimali)
  int decimals() const
  { return _decimals; }
  
  // @cmember Costruttore
  TReal_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TReal_field() 
  { }
};

// @doc EXTERNAL

// @class TDate_field | Classe per la gestione dei campi data
//
// @base public | TEdit_field
class TDate_field : public TEdit_field

// @author:(INTERNAL) Guido
{
  // @access Protected Member
protected: // TMask_field
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;
  // @cmember Crea il controllo
  virtual void create(WINDOW parent);

protected: // TOperable_field
  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);

protected: // TEditable_field
  // @cmember Converte una eventuale data ANSI in formato gg-mm-aaaa
  const char* reformat(const char* str) const;
  
  // @cmember Converte l'input dell'utente in una data
  virtual const char* win2raw(const char* data) const;

  // @cmember Formatta una data normale o ANSI in gg-mm-aaaa
  virtual const char* raw2win(const char* data) const;

  // @cmember Scrive sulla relazione il valore del campo  gestendo formato ANSI
  virtual bool autosave(TRelation& r) const;
  
  // @access Public Member
public:
  // @cmember Legge un item del controllo dal file <p scanner>
  virtual void parse_head(TScanner& scanner);
  
  virtual bool is_kind_of(word cid) const;
  
  // @cmember Costruttore
  TDate_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TDate_field() 
  { }
};


// @doc EXTERNAL

// @class TList_field | Classe per la gestione dei campi lista (list box)
//
// @base public | TEditable_field
class TList_field : public TEditable_field
// @author:(INTERNAL) Guido
{
  word _size;
  // @access Private Member
  // @cmember Crea una lista con i mesi
  void add_list();                                  
  
  // @cmember seleziona all'offset dato dal corrente
  bool select_by_ofs(int n);

  // @access Protected Member
protected:
  // @cmember Lista delle voci
  TToken_string _values;
  // @cmember Lista dei codice delle voci
  TToken_string _codes;

  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;

  // @cmember Legge il valore del campo direttamente dalla finestra del controllo
  virtual TString& get_window_data();
  
  virtual void set_window_data(const char* data);

  // @cmember Crea il controllo
  virtual void create(WINDOW parent);

  // @cmember Setta la voce corrente
  virtual void current(int n);
  // @cmember Ritorna la voce corrente
  virtual int current() const;

  // @cmember Trasforma la voce nel corrispondente valore
  int str2curr(const char* data);
  // @cmember Gestisce la chiamata all'handler del campo
  virtual bool on_hit();
  // @cmember Gestisce la pressione del tasto (TRUE se la gestione ha avuto successo)
  virtual bool on_key(KEY key);

  // @cmember Legge dal file gli item dello sheet
  virtual void read_item(TScanner& scanner);

  // @cmember Legge la testata del controllo dal file <p scanner>
  virtual void parse_head(TScanner& scanner);

  // @cmember Legge un item del controllo dal file <p scanner>
  virtual bool parse_item(TScanner& scanner);                                             
                                             
  // @access Public Member
public:                                                                

  // @cmember Ritorna la dimensione del buffer associato al campo
  virtual word size() const { return _size; }
  
  // @cmember Esegue la ricerca. Torna il tasto che ha terminato la ricerca
  virtual bool has_query_button() const 
  { return TRUE; }

  // @cmember Conversione da formato visuale a valore
  virtual const char* win2raw(const char* data) const;

  // @cmember Conversione da valore a formato visuale
  virtual const char* raw2win(const char* data) const;

  // @cmember Scrive il valore del campo direttamente dalla finestra del controllo
  virtual void set(const char* data);
  
  // @cmember Ritorna la tokenstring dei codici ammessi
  const char* get_codes() const { return _codes; }
  
  // @cmember Ritorna la tokenstring dei valori ammessi
  const char* get_values() const { return _values; }

  // @cmember Sostituisce alle voci correnti quelle passate come parametri
  virtual void replace_items(const char* codes, const char* values);

  // @cmember Aggiunge una voce
  virtual void add_item(const char* code_value);

  // @cmember Elimina la voce con codice <p code>
  virtual void delete_item(const char* code);

  // @cmember Ritorna il numero di voci presenti
  int items() const;

  // @cmember Tipo 
  virtual bool is_kind_of(word cid) const;

  // @cmember Seleziona sulla base dell'iniziale
  bool select_by_initial(char c);

  // @cmember Seleziona il prossimo se possibile (no wrap)
  bool select_next() { return select_by_ofs(1); }

  // @cmember Seleziona il precedente se possibile (no wrap)
  bool select_prev() { return select_by_ofs(-1); }
  
  // @cmember Azzera il contenuto del campo
  virtual void reset();

  // @cmember Costruttore
  TList_field(TMask* mask);
  virtual ~TList_field() {}
};

// @doc EXTERNAL

// @class TRadio_field | Classe per la gestione dei campi lista (list box)
//
// @base public | TList_field
class TRadio_field : public TList_field
// @author:(INTERNAL) Guido
{
  // @access Protected Member
protected:
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const;
  // @cmember Crea il controllo
  virtual void create(WINDOW parent);
  
  // @cmember Setta la voce corrente      
  virtual void current(int n);
  // @cmember Ritorna la voce corrente
  virtual int current() const;

  // @access Public Member
public:
  // @cmember Costruttore
  TRadio_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TRadio_field();
};


// @doc EXTERNAL

// @class TMemo_field | Classe per la gestione dei campi memo
//
// @base public | TMask_field
class TMemo_field : public TEdit_field
// @author:(INTERNAL) Guido
{
  // @access:(INTERNAL) Private Member

  // @access Protected Member
protected: // TObject
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const
  { return CLASS_MEMO_FIELD; }
  // @cmember Ritorna il nome della classe
  virtual const char* class_name() const
  { return "MEMO"; }
  
protected: // TMask_field  
  // @cmember Crea il controllo
  virtual void create(WINDOW parent);
  // @cmember Legge un item del controllo dal file <p scanner>
  virtual void parse_head(TScanner& scanner);

protected: // TEditable_field  
  // Gestisce solo l'acquisto e la perdita del focus
  virtual bool on_key(KEY k);
  // @cmember Non fa' nulla
  virtual const char* reformat(const char* data) const;
  // @cmember Trasforma i '/n' in '/r'
  virtual const char* raw2win(const char* data) const;
  // @cmember Trasforma i '/r' in '/n'
  virtual const char* win2raw(const char* data) const;

  // @access Public Member
public: 
  // @cmember Costruttore
  TMemo_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TMemo_field();
};

// @doc EXTERNAL

// @class TZoom_field | Come <c TEdit_field> ma zooma per l'editing dei campi memo
//
// @base public | TEdit_field
class TZoom_field : public TEdit_field
// @author:(INTERNAL) Guido
{
  // @access Protected Member
protected:
  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const
  { return CLASS_ZOOM_FIELD; };
  // @cmember Ritorna il nome della classe
  virtual const char* class_name() const
  { return "ZOOM"; }
  
protected:  
  // @cmember Crea il controllo
  virtual void create(WINDOW parent);
  
  // @cmember Gestisce tasti inviati al controllo
  virtual bool on_key(KEY key);

protected:                                       
  // @cmember Non fa nulla
  virtual const char* reformat(const char* data) const;

  // @cmember Trasforma <p data> in una riga sola
  virtual const char* raw2win(const char* data) const;

  // @cmember Trasforma  la riga <p data> nell'intero memo
  virtual const char* win2raw(const char* data) const;
  
  // @access Public Member
public:   
  const char* get_first_line() const;

  // @cmember Costruttore
  TZoom_field(TMask* mask);
  // @cmember Distruttore
  virtual ~TZoom_field();
};

#endif // __MASKFLD_H


