#ifndef __WINDOW_H
#define __WINDOW_H

#ifndef __OBJECT_H
#include <object.h>
#endif

#ifndef __XVTILITY_H
#include <xvtility.h>
#endif

class TString_array;

void close_all_dialogs();
bool can_close();
WINDOW cur_win();

// @C
// Classe TPoint
// @END

// @N
// Punto dello schermo
// @END

struct TPoint
{
  // @DPUB
  long x, y;
  // Coordinate

  // @FPUB
  TPoint(long sx = 0, long sy = 0) : x(sx), y(sy) {}
  // Costruttore
  TPoint(PNT pnt) : x(pnt.h/CHARX), y(pnt.v/CHARY) {}
  void set(long sx, long sy) { x = sx; y = sy; }
  void set(PNT pnt) { x = pnt.h/CHARX; y = pnt.v/CHARY; }
  TPoint& operator= (PNT pnt) { set(pnt); return *this; }
  TPoint& operator= (TPoint pnt) { set(pnt.x,pnt.y); return *this; }
  bool operator ==(const TPoint& p) { return p.x == x && p.y == y; }
  bool operator !=(const TPoint& p) { return p.x != x || p.y != y; }
};

///////////////////////////////////////////////////////////
// TImage
///////////////////////////////////////////////////////////

class TImage : public TObject
{ 
  XVT_IMAGE _image;
  RCT _src, _dst;
  
public:  
  void set_palette(WINDOW w) const;                              
  void set_pos(int x, int y);

  void draw(WINDOW w) const ;                 // Draw at default position with default size
  void draw(WINDOW w, int x, int y) const;    // Draw with default size at x,y
  void draw(WINDOW w, const RCT& dst) const;  // Draw/resize 
  void draw(WINDOW w, const RCT& dst, const RCT& src) const;
  
  XVT_IMAGE set(XVT_IMAGE i);  
  XVT_IMAGE load(const char* n);
  XVT_IMAGE load(short id);
  
  virtual bool ok() const { return _image != NULL; }
  
  short width() const { return _src.right; }
  short height() const { return _src.bottom; }
  const RCT& rect() const { return _src; }
  
  void convert_to_default_colors();
  void set_clut(byte n, COLOR c);

  TImage(const char* n);  
  TImage(short id);
  TImage(const TImage& i, short width, short height);

  virtual ~TImage();
};

// @C
// Classe TWindow
//
// @END

class TWindow
{
  friend class TWindow_manager;

  // @DPRIV
  static DRAW_CTOOLS _ct;       // Set di drawing tools (xvttype.h)
  static bool _ctools_saved;    // E' stata salvata _ct ?

  WINDOW _win;                  // Descrittore finestra
  KEY _lastkey;                 // Tasto di uscita

  // @FPRIV
  bool save_ctools();           // Compila la struct _ct con i valori correnti
  bool restore_ctools();        // Ripristina i valori DA _ct

protected:
  // @DPROT
  bool _open    : 1;            // Se la finestra e' aperta
  bool _modal   : 1;            // Se la finestra e' modale
  bool _active  : 1;            // Se la finestra e' abilitata
  bool _running : 1;            // Se la finestra e' in esecuzione
  bool _pixmap  : 1;            // Se se le coordiante sono in pixel

  // @FPROT
  static long XVT_CALLCONV1 window_handler(WINDOW win, EVENT* ep);
  virtual WINDOW create(short x, short y, short dx, short dy,
                        const char* title = "", long flags = WSF_NONE,
                        WIN_TYPE rt = W_DOC, WINDOW parent = NULL_WIN, int menu = 0) ;

  void set_win(WINDOW w) { _win = w; }          // Usare con cautela

  void set_modal(bool m) { _modal = m; }        // Modifica il flag _modal

  WINDOW parent() const;

  virtual void update() {}                      // E_UPDATE
  virtual bool on_key(KEY) { return TRUE; }     // E_CHAR

  virtual PNT log2dev(long x, long y) const;
  virtual TPoint dev2log(const PNT& p) const;

public:
  // @FPUB
  TWindow();                                    // Costruttore
  virtual ~TWindow();

  virtual void handler(WINDOW win, EVENT* ep); // Handler finestra
  virtual void set_focus();                    // Mette la finestra in primo piano
  virtual WINDOW win() const { return _win; }  // Ritorna il descrittore della finestra

  bool is_open() const { return _open; }        // Ritorna _open
  bool is_modal() const { return _modal; }      // Ritorna _modal
  bool is_running() const { return _running; }  // Ritorna _running
  bool active() const { return _active; }

  TPoint size() const;                          // Determina numero di righe e colonne nella finestra
  short rows() const { return (short)size().y; }// Ritorna numero di righe
  short columns() const { return (short)size().x; } // Ritorna numero di colonne

  virtual void start_run() {}
  virtual bool stop_run(KEY key);
  void force_update();                          // Forza ridisegno della finestra

  virtual void open();                          // Mostra la finestra
  virtual void close();                         // Nasconde la finestra
  virtual bool can_be_closed() const;           // Puo' essere chiusa brutalmente?
  virtual void on_idle();                       // Non c'e' piu' niente da fare!

  void iconize() const;
  void maximize() const;
  virtual void activate(bool = TRUE);
  void deactivate() { activate(FALSE); }

  void open_modal();                            // Mostra la finestra modale
  void close_modal();                           // Nasconde la finestra modale

  KEY run();                                    // Esegue la finestra
  KEY last_key() const { return _lastkey; }     // Ritorna l'ultimo tasto

  virtual void set_caption(const char* title);
  virtual const char* get_caption() const;

  // Riempie la finestra con il colore in color
  void clear(COLOR color);

  // Setta il draw mode
  void set_mode(DRAW_MODE mode);

  // Setta il colore
  void set_color(COLOR fore, COLOR back);

  // Setta opaque_text. Quando e' FALSE il testo viene scritto in modo trasparente
  void set_opaque_text(bool o);

  // Sceglie penna con colore color eccetera
  void set_pen(COLOR color, int width = 1, PAT_STYLE pat = PAT_SOLID, PEN_STYLE st = P_SOLID);
  void hide_pen();              // Nasconde la penna
  void hide_brush();            // Nasconde il pennello
  void set_brush(COLOR color, PAT_STYLE = PAT_SOLID); // Sceglie pennello con colore color
  void set_font(const char* family = XVT_FFN_FIXED, int style = 0, int dim = 0); // Sceglie il font

  // Disegna un rettangolo con la possibilita' di settare la penna e il draw_mode
  void frame(short left, short top, short right, short bottom, int flag);

  // Queste funzioni chiamano tutte frame con diversi flag
  void rect(short left, short top, short right, short bottom);
  void bar(short left, short top, short right, short bottom);
  void invert_bar(short left, short top, short right, short bottom);

  void stringat(short x, short y, const char* str);
  void printat(short x, short y, const char* fmt, ...); // Scrive un testo nella finestra alla posizione indicata

  void line(short x0, short y0, short x1, short y1); // Disegna una linea nella finestra
  void icon(short x0, short y0, int iconid = -1);

  // menu runtime interface 
  bool add_menu(TString_array& menu, MENU_TAG id = 0, bool force = TRUE);
  bool remove_menu(MENU_TAG id);
};

class TTemp_window : public TWindow
{
public:
  TTemp_window(WINDOW w);
  virtual ~TTemp_window();
};

// @C
// Classe TScroll_window : public TWindow
//
// Finestra con scrollbar
//
// @END

class TScroll_window : public TWindow
{
  
  // @DPRIV
  TPoint _origin;
  TPoint _max;
  short _shift;

  bool _autoscroll  : 1;
  bool _has_hscroll : 1;
  bool _has_vscroll : 1;

protected:

  // @FPROT
  virtual WINDOW create(short x, short y, short dx, short dy,
                        const char* title = "", long flags = WSF_NONE,
                        WIN_TYPE rt = W_DOC, WINDOW parent = NULL_WIN,
                        int menu = 0) ;        // Crea la finestra

  virtual PNT log2dev(long x, long y) const;
  virtual bool on_key(KEY key);

public:
  // @FPUB

  TScroll_window();
  // Costruttore

  virtual void handler(WINDOW win, EVENT* ep);

  void set_scroll_max(long maxx, long maxy);
  // Setta punto di massimo scroll
  void update_thumb(long x = -1, long y = -1);
  // Aggiorna la scrollbar

  void autoscroll(bool on) { _autoscroll = on; }
  // Setta autoscroll

  bool autoscrolling() const { return _autoscroll; }

  const TPoint& origin() const { return _origin; }
  // Ritorna punto origine
  const TPoint& range() const { return _max; }
  // Ritorna punto massimo
};

#endif // __WINDOW_H