#ifndef __SHEET_H
#define __SHEET_H

#ifndef __MASK_H
#include <mask.h>
#endif

// @doc INTERNAL

// @class TSheet | Classe per la definizione e la gestione degli sheet per le ricerche
//
// @base public | TScroll_window
class TSheet : public TMask

// @author:(INTERNAL) Guido

// @access:(INTERNAL) Privete Member
{
  friend class TSheet_control;
  TSheet_control* _sheet;       // Spreadsheet contenuto

  TToken_string _park;          // Ultima riga richiesta 
  long _parked;                 // Numero riga richiesta
  long _select_row;             // Riga da selezionare
  
  // @access Protected Member
protected:  // TMask
  // @cmember Lavori in background
  virtual void on_idle();

  static bool tutti_handler(TMask_field& f, KEY k);
  
protected:  
  virtual void get_row(long r, TToken_string& row) { row.cut(0); }
  virtual long get_items() const { return 0L; }
                                
  TSheet_control& sheet();                              
                                
  // @cmember Permette di riposizionare i bottoni all'interno della pagina
  virtual void repos_buttons() const;
  
  void post_select(long rec);
  
  // @access Public Member
public:  // TWindow
  // @cmember Gestisce la pressione del tasto (vedi <mf TWindow::on_key>)
  virtual bool on_key(KEY);
  
  // @cmember Inizializzazione
  virtual void start_run();

public:
  // @cmember Aggiunge un bottone nella finestra
  void add_button(short id, const char* caption, KEY key, short bmp_up = 0, short bmp_dn = 0);

  // @cmember Ritorna il numero di elementi di <p _page>
  long items() const { return get_items(); }
  // @cmember Ritorna il contenuto di una riga
  TToken_string& row(long s = -1);

  // @cmember Ritorna il numero della riga corrente
  long selected() const;
  // @cmember Seleziona una riga facendola diventare corrente
  virtual void select(long n);
  
  // @cmember Ritorna se la riga <p n>-esima e' attivata
  bool checked(long n) const;
  // @cmember Permette di attivare/disattivare una riga
  void check(long n, bool on = TRUE);
  // @cmember Permette di disattivare una riga (chiama <mf TSheet::check>)
  void uncheck(long n)
  { check(n, FALSE); }
  // @cmember Permette di abilitare (<p yn> = TRUE) o disabilitare (<p yn> = FALSE)
  //          la gestione dei check sullo sheet
  void enable_check(bool on = TRUE);
  // @cmember Permette di disabilitare (<p yn> = FALSE) i check sullo sheet
  void disable_check()
  { enable_check(FALSE); }
  // @cmember Ritorna TRUE se e' possibile mettere un check sulle righe
  bool check_enabled() const;
  
  // @cmember Abilita/disabilita una riga
  void enable_row(long n, bool on = TRUE);
  // @cmember Disabilita una riga (chiama <mf TSheet::enable_row>)
  void disable_row(long n)
  { enable_row(n, FALSE); }
  // @cmember Ritorna se e' abilitata la riga <p n>-esima
  bool row_enabled(long n) const;
  // @cmember Ritorna se e' disabilitata la riga <p n>-esima
  bool row_disabled(long n) const { return ! row_enabled(n); }
  
  // @cmember Ritorna se esistono elementi attivati nello sheet (TRUE se esitono)
  bool one_checked() const;
  // @cmember Ritorna il numero di elementi attivati (vedi <mf TBit_array::ones>)
  long checked() const;
  
  // @cmember Costruttore
  TSheet(short x, short y, short dx, short dy, const char* title, const char* head, byte buttons = 0, short sht_y = 0);

  // @cmember Distruttore
  virtual ~TSheet();
};

// @doc EXTERNAL

// @class TArray_sheet | Classe per la gestione degli sheet i cui dati sono
//                       forniti da un array di stringhe
//
// @base public | TSheet
class TArray_sheet : public TSheet
// @author:(INTERNAL) Guido

// @access:(INTERNAL) Private Member
{
  // @cmember:(INTERNAL) Contenuto dell'array di cui costruire lo sheet
  TString_array _data;

  // @access Protected Member
protected:
  // @cmember Ritorna il contenuto dell'elemento <p n>-esimo
  TToken_string& data(long n)
  { return _data.row((int)n); }
  
  // @cmember Ritorna la riga n
  virtual void get_row(long n, TToken_string& row)
  { row = data(n); }
  
  // @cmember Ritorna il numero degli elementi dello sheet
  virtual long get_items() const 
  { return _data.items(); }

  // @access Public Member
public:
  // @cmember Costruttore
  TArray_sheet(short x, short y, short dx, short dy, const char* caption, const char* head, byte buttons = 0);
  // @cmember Ritorna il contenuto dello sheet
  TString_array& rows_array() 
  { return _data; }
  // @cmember Aggiunge un elemento allo sheet
  long add(const TToken_string& s);
  // @cmember Aggiunge un elemento (passato per indirizzo) allo sheet
  long add(TToken_string* s);
  // @cmember Inserisce un elemento nella posizione <p n>
  long insert(const TToken_string& s, long n);
  // @cmember Azzera l'array dello sheet
  bool destroy(int i = -1);
};


// @doc EXTERNAL

// @class TCursor_sheet | Classe per la gestione di uno sheet i cui dati
//                        sono prelevati da un <c TCursor>
//
// @base public | TSheet
class TCursor_sheet : public TSheet
// @author:(INTERNAL) Guido

// @access:(INTERNAL) Private Member
{
  // @cmember:(INTERNAL) Array di <c TRecfield>
  TArray _fields;
  // @cmember:(INTERNAL) Numero del records collegato al cursore
  long _records;

  // @cmember:(INTERNAL) Cursore da cui prelevare i dati
  TCursor* _cursor;

  // @access Protected Member
protected:  // TSheet
  
  // @cmember Ritorna il numero dei records del cursore
  virtual long get_items() const 
  { return _records; }
  
  // @cmember Ritorna la riga n
  virtual void get_row(long n, TToken_string& row);

  // @access Public Member
public: // TSheet
  
  // @cmember Lancia la finestra con lo sheet
  virtual KEY run();

  // @access Public Member
public:
  // @cmember Ritorna il cursore
  TCursor* cursor() const
  { return _cursor; }
  
  const TArray& fields_array() const { return _fields; }

  // @cmember Costruttore
  TCursor_sheet(TCursor* cursor, const char* fields, const char* title, const char* head, byte buttons = 0, short sht_y = 0);
  // @cmember Distruttore
  virtual ~TCursor_sheet() 
  {}                     
};

// @doc EXTERNAL

// @class TBrowse_sheet | Classe per la gestione degli sheet legati ad un
//                        cursore del campo della maschera
//
// @base public | TCursor_sheet
class TBrowse_sheet : public TCursor_sheet
// @author:(INTERNAL) Guido

// @access:(INTERNAL) Private Member
{
  // @cmember:(INTERNAL) Campi collegati ai campi editabili (vedi <c TEdit_field>)
  TEdit_field* const _field;
  
  // @cmember:(INTERNAL) Campo di ricerca attuale (Tag button selezionato)
  int _sel;
  
//  long _select_row;
  
  // @access Protected Member
protected:
  // @cmember Gestisce la pressione del tasto (vedi <mf TWindow::on_key>)
  virtual bool on_key(KEY k);
  // @cmember Gestisce gli eventi della finestra
  virtual void handler(WINDOW win, EVENT* ep);
  
  // @cmember Ritorna il campo a cui si riferisce lo sheet
  TEdit_field& field() 
  { return *_field; }
  
  static bool browse_field_handler(TMask_field& f, KEY k);
  static bool last_browse_field_handler(TMask_field& f, KEY k);
  
  // @access Public Member
public:
  // @cmember Costruttore
  TBrowse_sheet(TCursor* cursor, const char* fields, const char* title, const char* head, byte buttons, TEdit_field* f, TToken_string& siblings);
  // @cmember Distruttore
  virtual ~TBrowse_sheet()
  {}
  // @cmember Esegue la finestra. Ritorna il tasto premuto nella finestra
  virtual KEY run();
};

#endif
