#ifndef __BRWBUT_H
#define __BRWBUT_H

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

class TEdit_field;
class TEditable_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; }
  virtual bool is_sheet() const   { return false; }
  virtual bool is_filesel() const { return false; }
  virtual bool is_profile() 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();

  virtual bool is_sheet() const  { return true; }
  
  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) Chiave di ricerca alternativa (quando il testo del campo comincia con %)
  TBrowse_button* _alt_browse;  

  // @cmember:(INTERNAL) Testate della maschera di ricerca
  TToken_string _head;
  // @cmember:(INTERNAL) Campi visualizzati dalla 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;
  // @cmember:(INTERNAL) handler di filtro custom
	CONTROL_HANDLER _custom_filter_handler;

  // @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 Modifica il cursore
	void custom_cursor();

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

  // @access Public Member
public:
  // @cmember Modifica il display
	void custom_display();

	// @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 Aggiorna la lista completa degli identificatori dei campi di input
	void set_input_fields(const char * inp_id) { _inp_id = inp_id;}

	// @cmember Aggiorna la lista completa degli identificatori dei campi di input da un campo
	void copy_input(const TBrowse * b);
  
  // @cmember Aggiorna la lista completa dei nomi dei campi di input
	void set_input_field_names(const char * inp_names) { _inp_fn = inp_names;}
  
  // @cmember Aggiunge un campo di input alla posizione <pos>
	void add_input_field(const char * id, const char * name, const int pos = - 1, bool select = false);

// @cmember Elimina un campo di display alla posizione <pos>
  void remove_display_field(const int pos = -1);

  // @cmember Aggiorna la lista completa degli identificatori dei campi di output
	void set_display_fields(const char * hds, const char * names) { _head = hds; _items = names;}
  int get_display_fields(TToken_string& hds, TToken_string& names) const { hds =_head; names = _items; return names.items(); }

	// @cmember Aggiorna la display da un campo
	void copy_display(const TBrowse * b);

	// @cmember Aggiunge un campo di diplay alla posizione <pos>
	void add_display_field(const char * hd, const char * name, const int pos = -1);

// @cmember Elimina un campo di input alla posizione <pos>
	void remove_input_field(const int pos = -1);

  // @cmember Ritorna la lista completa dei campi di output
  const char* get_output_fields() const;

  // @cmember Ritorna la lista completa dei nomi dei campi di output
  const char* get_output_field_names() const;

  // @cmember Aggiorna la lista completa degli identificatori dei campi di output
	void set_output_fields(const char * out_id) { _out_id = out_id;}
  
  // @cmember Aggiorna la lista completa dei nomi dei campi di input
	void set_output_field_names(const char * out_names) { _out_fn = out_names;}
  
	// @cmember Aggiorna la lista completa degli identificatori dei campi di output da un campo
	void copy_output(const TBrowse * b);

	// @cmember Aggiunge un campo di output alla posizione <pos>
	void add_output_field(const char * id, const char * name, const int pos = -1);

  // @cmember Elimina un campo di output alla posizione <pos>
	void remove_output_field(const int pos = -1);

  // @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 Cambia il filtro della browse 
  void set_filter(const char * filter)
  { _filter = filter;}

  // @cmember Cambia il cursore della browse 
  void set_cursor(TCursor * c);

  // @cmember Cambia il filtro della browse 
	void set_custom_filter_handler(CONTROL_HANDLER custom_filter_handler) { _custom_filter_handler = custom_filter_handler;}

  // @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;}

  bool set_alt_browse(int altkey);
  
  virtual bool is_browse() const { return true; }

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

class TFuzzy_browse : public TBrowse_button
{
protected:
  virtual void parse_input(TScanner& scanner) {}
  virtual void parse_output(TScanner& scanner) {}
  long find_magic(const TString& magic_val, double& best);

protected:
  const int _altkey;
  TString16 _altfld, _outfld;
  virtual TCursor& cursor();

public:
  virtual bool check(CheckTime = RUNNING_CHECK);
  virtual KEY run();
  virtual long find(const TString& val);
  TFuzzy_browse (TEdit_field* ef, int key);
};


class TAlternative_browse : public TFuzzy_browse
{
  TCursor* _cursor;

protected:
  virtual TCursor& cursor();

public:
  virtual KEY run();
  
  TAlternative_browse(TEdit_field* ef, int altkey);
  ~TAlternative_browse();
};

class TFile_select : public TBrowse_button
{
  TFilename _filter;

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

  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  virtual void parse_output(TScanner& scanner);
          
  virtual KEY run();
  
  // @cmember Controlla la validita' del campo
  virtual bool check(CheckTime = RUNNING_CHECK);

  virtual bool is_filesel() const { return true; }

  TFile_select(TEdit_field* ef, const char* filter);
  virtual ~TFile_select() { }
};

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

  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  virtual void parse_output(TScanner& scanner);
          
  virtual KEY run();
  
  // @cmember Controlla la validita' del campo
  virtual bool check(CheckTime = RUNNING_CHECK);

  virtual bool is_filesel() const { return TRUE; }

  TDir_select(TEdit_field* ef);
  virtual ~TDir_select() { }
};

class TReport_select : public TBrowse_button
{
  TString _classe;

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

  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  virtual void parse_output(TScanner& scanner);
          
  virtual KEY run();
  
  // @cmember Controlla la validita' del campo
  virtual bool check(CheckTime = RUNNING_CHECK);

  virtual bool is_filesel() const { return true; }

  TReport_select(TEdit_field* ef, const char* classe);
  virtual ~TReport_select() { }
};


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

  // @cmember Controlla la sintassi della output del campo e ne setta i membri
  virtual void parse_output(TScanner& scanner);

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

  // @cmember E' un campo profilo
  virtual bool is_profile() const { return true; }
  
  // @cmember Estrae dal .ini tutti i profili
  int get_descriptions(TString_array& a) const;

  TProfile_select(TEdit_field* ef);
  virtual ~TProfile_select() { }
};

#endif