#ifndef __WINDOW_H
#define __WINDOW_H

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

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

class TString_array;

// @doc EXTERNAL

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

//@class TPoint | Struttura per la definizione di un punto sullo schermo
struct TPoint
{
  // @cmember Coordinata x del punto
  long x; 
  // @cmember Coordinata y del punto
  long y; 

  // @cmember Costruttore
  TPoint(long sx = 0, long sy = 0) : x(sx), y(sy)   
  {}
  // @cmember Costruttore (occorre passare il punto)
  TPoint(PNT pnt) : x(pnt.h/CHARX), y(pnt.v/CHARY)  
  {}
  // @cmember Setta le coordinate x e y del punto
  void set(long sx, long sy)      
  { x = sx; y = sy; }
  // @cmember Setta le coordinate x e y del punto
  void set(PNT pnt)               
  { x = pnt.h/CHARX; y = pnt.v/CHARY; }
  // @cmember Operatore di assegnamento tra punti
  TPoint& operator= (PNT pnt)     
  { set(pnt); return *this; }
  // @cmember Operatore di assegnamento tra punti
  TPoint& operator= (TPoint pnt)  
  { set(pnt.x,pnt.y); return *this; }
  // @cmember Confronta se due punti sono uguali (TRUE se uguali)
  bool operator ==(const TPoint& p) 
  { return p.x == x && p.y == y; }
  // @cmember Confronta se due punti sono diversi (TRUE se diversi)
  bool operator !=(const TPoint& p) 
  { return p.x != x || p.y != y; }
};

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

// @class TImage | Classe per la gestione delle imagini a video
//
// @base public | TObject
class TImage : public TObject
{
  // @access Private Member

  // @cmember Immagine de gestire
  XVT_IMAGE _image;
  // @cmember Rettangolo originale (origine 0,0 e dimensioni originali) dell'immagine
  RCT _src;
  // @cmember Rettangolo di visualizzazione dell'immagine (dove mettere l'immagine)
  RCT _dst;
  
  // @access Public Member
public:
  // @cmember Fa corrispondere la palette della finestra a quella dell'immagine
  void set_palette(WINDOW w) const;
  // @cmember Permette di settare la posizione della figura
  void set_pos(int x, int y);

  // @cmember Disegna l'immagine nella poszione di default e nella dimensione
  //          di defalut
  void draw(WINDOW w) const ;
  // @cmember Disegna l'immagine con dimensione default in un punto dello schermo
  void draw(WINDOW w, int x, int y) const;
  // @cmember Disegna/modifica l'immagine sullo schermo
  void draw(WINDOW w, const RCT& dst) const;
  // @cmember Disegna l'immagine sulla finestra
  void draw(WINDOW w, const RCT& dst, const RCT& src) const;
  
  // @cmember Setta l'immagine e le sue dimensioni
  XVT_IMAGE set(XVT_IMAGE i);
  // @cmember Legge l'immagine dal file
  XVT_IMAGE load(const char* n);
  // @cmember Legge l'immagine dal file di risorse
  XVT_IMAGE load(short id);
  
  // @cmember Controlla che l'immagine sia un oggetto valido (diverso da NULL)
  virtual bool ok() const
  { return _image != NULL; }
  
  // @cmember Ritorna la larghezza dell'immagine
  short width() const
  { return _src.right; }
  // @cmember Ritorna l'altezza dell'immagine
  short height() const
  { return _src.bottom; }
  // @cmember Ritorna il rettangolo dell'immagine originale
  const RCT& rect() const
  { return _src; }
  
  // @cmember Setta i colori dell'immagine  in modo da renderlo trasparente
  void convert_to_default_colors();
  // @cmember Setta l'<p n>.esime entry della paletta al colore <p c>
  void set_clut(byte n, COLOR c);

  // @cmember Costruttore. Viene passato il nome del file
  TImage(const char* n);
  // @cmember Costruttore. Viene passato l'identificatore dell'immagine sul file di risorsa
  TImage(short id);
  // @cmember Costruttore. Viene passata l'immagine e le sue diemsioni
  TImage(const TImage& i, short width, short height);

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

// @class TWindow | Classe per la definizione di una finestra generica
class TWindow
{
  // @author:(INTERNAL) Guido

  // @cfriend TWindow_manager
  friend class TWindow_manager;

  // @access PRovate Member

  // @cmember Set di drawing tools (definito in xvttype.h)
  static DRAW_CTOOLS _ct;
  // @cmember Indica se e' stato salvato il set di drawing tools
  static bool _ctools_saved;

  // @cmember Descrittore finestra
  WINDOW _win;
  // @cmember Codice del tasto di uscita
  KEY _lastkey;

  // @cmember Compila la struttura <p _ct> con i valori correnti
  //          (TRUE se la compilazione ha luogo)
  bool save_ctools();
  // @cmember Ripristina i valori dalla struttura <p _ct> (TRUE se i valori
  //          vengono recuperati)
  bool restore_ctools();

  // @access Protected Member
protected:
  // @cmember Indica che la finestra e' aperta
  bool _open    : 1;
  // @cmember Indica che la finestra e' modale
  bool _modal   : 1;
  // @cmember Indica che la finestra e' abilitata
  bool _active  : 1;
  // @cmember Indica che la finestra e' in esecuzione
  bool _running : 1;
  // @cmember Indica che le coordinate sono in pixel
  bool _pixmap  : 1;

  // @cmember Intercetta tutti i messaggi diretti alla finestra di XVT
  static long XVT_CALLCONV1 window_handler(WINDOW win, EVENT* ep);
  // @cmember Crea la finestra
  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) ;

  // @cmember Cambia l'handle della finestra di XVT (usare con cautela)
  void set_win(WINDOW w)
  { _win = w; }

  // @cmember Permette di modificare il flag <p _modal>
  void set_modal(bool m)
  { _modal = m; }

  // @cmember Ritorna l'handler della finestra padre
  WINDOW parent() const;

  // @cmember Fa' l'update della finstra
  virtual void update()
  {}
  // @cmember Gestisce la pressione del tasto
  virtual bool on_key(KEY)
  { return TRUE; }

  // @cmember Converte le coordinate logiche (caratteri) in coordinate fisiche (pixel)
  virtual PNT log2dev(long x, long y) const;
  // @cmember Converte le coordinate fisiche (pixel) in coordinate logiche (caratteri)
  virtual TPoint dev2log(const PNT& p) const;

  // @access Public Member
public:
  // @cmember Costruttore
  TWindow();
  // @cmember Distruttore
  virtual ~TWindow();

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

  // @cmember Ritorna TRUE se la finestra e' aperta
  bool is_open() const
  { return _open; }
  // @cmember Ritorna TRUE se la finestra e' modale
  bool is_modal() const
  { return _modal; }
  // @cmember Ritorna TRUE se la finestra e' in esecuzione
  bool is_running() const
  { return _running; }
  // @cmember Ritorna TRUE se la finestra e' attiva
  bool active() const
  { return _active; }

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

  // @cmember Inizia l'esecuzione della finestra
  virtual void start_run()
  {}
  // @cmember Interrompe l'esecuzione della finestra
  virtual bool stop_run(KEY key);
  // @cmember Forza ridisegno della finestra
  void force_update();

  // @cmember Mostra la finestra
  virtual void open();
  // @cmember  Nasconde la finestra
  virtual void close();
  // @cmember Indica se la finestra puo' essere chiusa brutalmente
  virtual bool can_be_closed() const;
  // @cmember Permette di fare tutti gli aggiornamenti necessari
  virtual void on_idle();

  // @cmember Iconizza la finestra
  void iconize() const;
  // @cmember Massimizza la finestra
  void maximize() const;
  // @cmember Attiva/disattiva la finestra
  virtual void activate(bool = TRUE);
  // @cmember Disattiva la finestra (chiama <mf TWindow::activate>)
  void deactivate()
  { activate(FALSE); }

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

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

  // @cmember Permette di settare il titolo della finestra
  virtual void set_caption(const char* title);
  // @cmember Ritorna il titolo della finestra
  virtual const char* get_caption() const;

  // @cmember Riempie la finestra con il colore <p color>
  void clear(COLOR color);

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

  // @cmember Setta il colore della finestra e dello sfondo
  void set_color(COLOR fore, COLOR back);

  // @cmember Setta opaque_text
  void set_opaque_text(bool o);

  // @cmember Sceglie la penna da utilizzare nella finestra
  void set_pen(COLOR color, int width = 1, PAT_STYLE pat = PAT_SOLID, PEN_STYLE st = P_SOLID);
  // @cmember Nasconde la penna
  void hide_pen();
  // @cmember Nasconde il pennello
  void hide_brush();
  // @cmember Sceglie il pennello da utilizzare nella finestra (vedi <mf TWindow::set_pen>)
  void set_brush(COLOR color, PAT_STYLE = PAT_SOLID);
  // @cmember Sceglie il font da utilizzare nella finestra
  void set_font(const char* family = XVT_FFN_FIXED, int style = 0, int dim = 0);

  // @cmember 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);

  // @cmember Chiama <mf TWindow::frame> con il flag 2
  void rect(short left, short top, short right, short bottom);
  // @cmember Chiama <mf TWindow::frame> con il flag 1
  void bar(short left, short top, short right, short bottom);
  // @cmember Chiama <mf TWindow::frame> con il flag 5
  void invert_bar(short left, short top, short right, short bottom);

  // @cmember Scrive una stringa nella finestra all posizione indicata
  void stringat(short x, short y, const char* str);
  // @cmember Scrive il testo formattato nella finestra all posizione indicata
  void printat(short x, short y, const char* fmt, ...);

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

  // @cmember Aggiunge voci di menu' durante l'esecuzione di una finestra
  bool add_menu(TString_array& menu, MENU_TAG id = 0, bool force = TRUE);
  // @cmember Rimuove il menu' runtime dalla finestra
  bool remove_menu(MENU_TAG id);
};

// @class TTemp_window | Classe per la definizione di finestre temporanee
//
// @base public | TWindow
class TTemp_window : public TWindow
{
  // @author:(INTERNAL) Guido

  // @access Public Member
public:
  // @cmember Costruttore
  TTemp_window(WINDOW w);
  // @cmember Distruttore
  virtual ~TTemp_window();
};


// @class TScroll_window | Classe per la definizione di finestre con scrollbar
//
// @base public | TWindow
class TScroll_window : public TWindow
{
  // @author:(INTERNAL) Guido

  // @access Private Member

  // @cmember Posizione attuale della scrollbar
  TPoint _origin;
  // @cmember Massima lunghezza della scrollbar
  TPoint _max;
  // @cmember Utilizzato per finestre molto grosse, per poter gestire l-intera finestra
  short _shift;

  // @cmember Indica se sommare (TRUE) o no alle coordinate attuali le coordinate passate
  bool _autoscroll  : 1;
  // @cmember Indica che la finestra ha la barra di scorrimento orizzontale
  bool _has_hscroll : 1;
  // @cmember Indica che la finestra ha la barra di scorrimento verticale
  bool _has_vscroll : 1;

  // @access Protected Member
protected:
  // @cmember Crea la finestra (vedi <mf TWindow::create>)
  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) ;

  // @cmember Converte le coordinate logiche (caratteri) in coordinate fisiche (pixel)
  virtual PNT log2dev(long x, long y) const;
  // @cmember Gestice la pressione del tasto
  virtual bool on_key(KEY key);

  // @access Public Member
public:
  // @cmember Costruttore
  TScroll_window();

  // @cmember Gestisce l'handler della finestra (vedi <mf TWindow::handler>)
  virtual void handler(WINDOW win, EVENT* ep);

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

  // @cmember Setta il member <p _autoscroll>
  void autoscroll(bool on)
  { _autoscroll = on; }

  // @cmember Ritorna il membro <p _autoscroll>
  bool autoscrolling() const
  { return _autoscroll; }

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

#endif // __WINDOW_H
