#ifndef __CONTROLS_H
#define __CONTROLS_H

#ifndef __STRINGS_H
#include <strings.h>
#endif

class TWindow;      // __WINDOW_H
class TMask_field;  // __MASKFLD_H
 
#ifndef XVT_INCL_XVT
#include <xvt.h>
#endif

#ifndef INCL_XI
struct XI_OBJ;
struct XI_EVENT;
#endif


void init_controls();
void free_controls();
XVT_FNTID xvtil_default_font(bool bold = false, bool big = false);

WINDOW create_interface(WINDOW parent, short x, short y, short dx, short dy,
                        const char* caption, TWindow* mask /*, bool tags*/);

void attach_interface(WINDOW win, COLOR back);
short low_get_focus_id(WINDOW win);
void low_set_focus_id(WINDOW win, short cid);
bool has_virtual_keyboard();

///////////////////////////////////////////////////////////
// Custom control
///////////////////////////////////////////////////////////

// @doc INTERNAL

// @class TControl | Classe per la creazione di controlli
class TControl : public TObject
// @author:(INTERNAL) Guido

// @access:(INTERNAL) Private Member
{

// @access Protected Member
protected:
  // @cmember:(INTERNAL) Puntatore al controllo creato
  XI_OBJ* _obj;

  // @cmember:(INTERNAL) Puntatore al TMask_field eventualmente associato
  TMask_field* _fld;

  // @cmember Ricava l'interfaccia da una finestra
  XI_OBJ* get_interface(WINDOW win = 0L) const;
  
  // @cmember Cerca un controllo operabile (in avanti o all'indietro)
  XI_OBJ* find_operable(XI_OBJ* container, bool forward, bool normal) const;

  // @cmember Setta l'identificatore del prossimo controllo per il tasto TAB
  void set_tab_cid(XI_OBJ* obj, short id) const;

  void coord2rct(WINDOW win, short left, short top, short width, short height, RCT& rct) const;
  unsigned long flags2attr(const char* flags) const;
  void update_tab_cid();
  const char* parse_caption(const char* cap, bool& bold, bool& big, COLOR& color) const;

  void change_attrib(unsigned long attr, bool on, XI_OBJ* obj = NULL);
  

// @access Public Member
public:
  TControl();
  virtual ~TControl();
  
  static KEY xiev_to_key(const XI_EVENT* xiev);
  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* ep);

  bool notify_key(KEY k);
  bool is_edit_key(KEY k) const;

  // @cmember Ritorna l'identificatore assegnato al controllo
  short id() const;
  WINDOW parent() const;                
  XI_OBJ* xi_object() { return _obj; }
  
  int type() const;
  
  // @cmember Ritorna il prompt del controllo
  virtual const char* caption() const;
  // @cmember Setta il prompt del controllo
  virtual void set_caption(const char* c);

  // @cmember Abilita/disabilita il controllo
  virtual void enable(bool on = TRUE);
  void disable() { enable(FALSE); }
  
  // @cmember Mostra/nasconde il controllo
  virtual void show(bool on = TRUE);
  void hide() { show(FALSE); }

  virtual void destroy();
 
  virtual void set_rjust(bool on = TRUE);
  void set_ljust() { set_rjust(FALSE); }

  virtual bool read_only() const;
  virtual void set_read_only(bool on = TRUE);
  
  void autoselect(bool on);
  
  // @cmember Forza il focus al controllo
  virtual void set_focus() const;
  
  virtual RCT& get_rect(RCT& r) const;
  virtual void set_rect(const RCT& r);

	// @cmember imposta la posizione del cursore a <pos>
	void set_caret_pos(int pos = -1);
  
  bool on_key(KEY k);
};


class TText_control : public TControl
{         
public: // TControl
  virtual void set_caption(const char* text);
  
public:
  TText_control(WINDOW win, short cid, 
                short left, short top, short width, short height,
                const char* flags, const char* text);
  virtual ~TText_control() {}
};


class TGroupbox_control : public TText_control
{
  XI_OBJ* _rct;      // Rettangolo del gruppo
 
public: // TControl
  virtual void show(bool on);
  virtual RCT& get_rect(RCT& r) const;

public:
  TGroupbox_control(WINDOW win, short cid, 
                short left, short top, short width, short height,
                const char* flags, const char* text);
  virtual ~TGroupbox_control() {}
};

class TField_control : public TControl
{             
protected:
  bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
  
  void create(WINDOW win, short cid, 
              short left, short top, 
              short width, short height, short maxlen, 
              const char* flags, const char* text, int button);

  TField_control() {}
  
public:          
  // @cmember Mostra o nasconde il bottone associato
  void show_button(bool on);
  
  // @cmember Forza il focus al controllo
  virtual void set_focus() const;                    
  void set_back_color(COLOR col);

  // @cmember Costruttore
  TField_control(WINDOW win, short cid, 
                 short left, short top, 
                 short width, short maxlen, 
                 const char* flags, const char* text);
  // @cmember Distruttore
  virtual ~TField_control() {}
};

class TMultiline_control : public TField_control
{             
public:
  TMultiline_control(WINDOW win, short cid, 
                     short left, short top, 
                     short width, short height, short maxlen, 
                     const char* flags, const char* text);
  virtual ~TMultiline_control() {}
};

class TButton_control : public TControl
{     
protected:
  void create(WINDOW win, short cid, 
              short left, short top, short width, short height,
              const char* flags, const char* text, 
              WIN_TYPE wc, XI_OBJ* container = NULL, bool drawable = false);

  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* ep);

public:             
  bool checked() const;
  virtual void check(bool on = true);
  void uncheck() { check(false); }
  bool toggle();

  int button_type() const;
  XI_OBJ* container() const;
                            
  virtual void set_icon(unsigned int icon_up, unsigned int icon_dn = 0);

  TButton_control() {}
  virtual ~TButton_control() {}
};

class TPushbutton_control : public TButton_control
{   
  int _bmp_up, _bmp_dn;

protected:
  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
  TPushbutton_control() { } // Internal use only
  
public:
  virtual void update();

  // @cmember Setta il prompt del bottone
  virtual void set_caption(const char* c);
  
  void set_bmp(int up, int dn);
  void set_bmp(const char * up, const char * dn);
  void set_icon(int icon_up, int icon_dn = 0);
  void set_central_icon(unsigned int hicon);
  char mnemonic() const;

  TPushbutton_control(WINDOW win, short cid, 
                      short left, short top, short width, short height,
                      const char* flags, const char* text,
                      int bmp_up = 0, int _bmp_dn = 0);
  virtual ~TPushbutton_control();
};

class TRadiobutton_control : public TButton_control
{                    
protected:  // TControl
  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
  virtual void set_focus() const;
  
protected:
  TRadiobutton_control() { }    // To be derived

public:
  // @cmember Abilita/disabilita il controllo
  virtual void enable(bool on = TRUE);
  // @cmember Mostra/nasconde il controllo
  virtual void show(bool on = TRUE);

  byte get_checked() const;
  void check_button(byte b);
  
  void show_button(byte b, bool on = TRUE);
  void hide_button(byte b) { show_button(b, FALSE); }

  TRadiobutton_control(WINDOW win, short cid, 
                      short left, short top, short width, short height,
                      const char* flags, const char* text);
  virtual ~TRadiobutton_control() {}
};

class TTagbutton_control : public TRadiobutton_control
{                    
protected:   // TControl
  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);

public:                                       
  virtual void set_caption(const char* text);

  TTagbutton_control(WINDOW win, short cid, 
                     short left, short top, short width, short height,
                     const char* flags, const char* text, int tag);
  virtual ~TTagbutton_control() {}
};


class TCheckbox_control : public TButton_control
{
public:
  TCheckbox_control(WINDOW win, short cid, 
                    short left, short top, short width,
                    const char* flags, const char* text);
  virtual ~TCheckbox_control() {}
};

class TCheckbutton_control : public TButton_control
{
  int _pic_up, _pic_dn;

protected:
  virtual void check(bool on);

public:
  virtual void set_icon(int icon_up, int icon_dn);

  TCheckbutton_control(WINDOW win, short cid,
                       short left, short top, short width, int height,
                       const char* flags, const char* text,
                       int icon_up, int icon_dn);
  virtual ~TCheckbutton_control() {}
};

class TListbox_control : public TField_control
{                            
  TToken_string _codes, _values;
  int _current;

protected: // TTField_control
  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);

public:
  void set_values(const char* c, const char* v);
  int  items() const;
  bool select(int i);
  bool select_by_initial(char c);
  bool select_by_ofs(int i);
  int  selected() const;
  
  TListbox_control(WINDOW win, short cid, 
                   short left, short top, short width,
                   const char* flags, const char* text, 
                   const char* codes, const char* values);
  virtual ~TListbox_control();
};

int xvtil_drop_down_list(XI_OBJ* field_or_cell, const char* codes, const char* values);
const char* xvtil_get_cell_selection(XI_OBJ* field_or_cell, int sel, const char* cod, const char* val);

#endif