#ifndef __VISWIN_H
#define __VISWIN_H

#ifndef __CONTROLS_H
class TPushbutton_control;
#endif

#ifndef __WINDOW_H
#include <window.h>
#endif

#ifndef __TEXTFILE_H
#include <text.h>
#endif

class TBrowsefile_field;                                 

// @doc INTERNAL

// @class TViswin | Classe per la gestione della finestra video di anteprima di stampa
//
// @base public | TScroll_window
class TViswin : public TScroll_window

// @author:(INTERNAL) Villa

{
  // @cfriend TBrowsefile_field
  friend class TBrowsefile_field;
  
  // @access:(INTERNAL) Private Member

  
  enum { 
         // @ccost:(INTERNAL) MAXLEN | 256 | Lunghezza massima del modulo di stampa
         MAXLEN = 256, 
         // @ccost:(INTERNAL) BUFFERSIZE | 256 | Dimensione del buffer di stampa
         BUFFERSIZE = 256, 
         // @ccost:(INTERNAL) MAXPIC | 4 | Numero massimo di immagini gestibili nell'anteprima
         MAXPIC=4};

  enum scroll { none, up, down, left, right };

  // @cmember:(INTERNAL) Nome del file di visualizzazione
  TFilename _filename;
  // @cmember:(INTERNAL) Indica la presenza del bottone Collega
  bool _islink;
  // @cmember:(INTERNAL) Indica la presenza del bottone Edit
  bool _isedit;
  // @cmember:(INTERNAL) Indica la presenza del bottone Stampa
  bool _isprint;
  // @cmember:(INTERNAL) Indica se effettuare il disegno della crossbar
  bool _iscross;
  // @cmember:(INTERNAL) Indica se e' in corso la selezione
  bool _selecting;
  // @cmember:(INTERNAL) Indica se la selezione e' attiva   
  bool _isselection;
  // @cmember:(INTERNAL) Indica se disegnare la X-bar al posto del cursore a punto
  bool _isbar;
  // @cmember:(INTERNAL) Indica se in corso lo scrolling
  bool _scrolling;
  // @cmember:(INTERNAL) Indica se e' necessario un update completo
  bool _need_update;
  // @cmember:(INTERNAL) Indica se il timer successivo e' attivo
  bool _istimer;
  // @cmember:(INTERNAL) Indica se possono arrivare nuove linee
  bool _isopen;
  // @cmember:(INTERNAL) Indica se sono stati selezionati flag
  bool _selflag; 
  // @cmember:(INTERNAL) Indica se e' evidenziata la selezione
  bool _sel_displayed;
  // @cmember:(INTERNAL) Indica se e' visualizzato il link
  bool _link_displayed;
  // @cmember:(INTERNAL) Indica se' e' visualizzata l'incrocio della crossbar
  bool _cross_displayed;
  // @cmember:(INTERNAL) Indica se e' visualizzato il cursore a carattere
  bool _point_displayed;
  // @cmember:(INTERNAL) Timer per evitare autorepeat di tasti
  long _timer;
  // �cmember:(INTERNAL) Timer di attesa prima della chiusura del file
  long _wtimer;
  // @cmember:(INTERNAL) Indica il tipo di scroll richiesto (vedi <t scroll>)
  scroll _need_scroll;
  // @cmember:(INTERNAL) Flag per il disegno intelligente
  bool _wasneeded;
  // @cmember:(INTERNAL) Array di bottoni attivi nella finestra
  TArray _button;
  // @cmember:(INTERNAL) Bottone che ha il focus
  int _curbut;

  // @cmember:(INTERNAL) Bottone Collega
  TPushbutton_control* _link_button;
  // @cmember:(INTERNAL) Bottone Stampa
  TPushbutton_control* _print_button;

  // @cmember:(INTERNAL) Numero di righe di testo
  long _textrows;
  // @cmember:(INTERNAL) Numero di colonne di testo
  long _textcolumns;

  // @cmember:(INTERNAL) Testo che deve essere visualizzato
  TTextfile _txt;
  // @cmember:(INTERNAL) Prima linea di testo che deve essere visualizzata
  long _firstline;
  // @cmember:(INTERNAL) Ultima linea di testo che deve essere visualizzata                                                                                        
  long _lastline;

  // @cmember:(INTERNAL) Stringa di testo da cercare
  TString _txt_to_find;
  // @cmember:(INTERNAL) Posizione dell'ultima ricerca
  TPoint _last_found;
  // @cmember:(INTERNAL) Direzione della ricerca (TRUE verso il basso FALSE verso l'alto)
  bool _down_dir;
  // @cmember:(INTERNAL) Indica se si deve fare una ricerca case sensitive
  bool _case_sensitive;
  // @cmember:(INTERNAL) Memorizza lo stato del flag "espressione regolare" nella fin. di search
  bool _regexp;                                                              
                                                                
  // @cmember:(INTERNAL) Lunghezza della pagina
  int _formlen;
  
  // @cmember:(INTERNAL) Posizione corrente del punto
  TPoint _point;
  // @cmember:(INTERNAL) Posizione corrente dell'incrocio della crossbar
  PNT _cross;
  // @cmember:(INTERNAL) Inizio della selezione (colonna, line del FILE)
  TPoint _sel_start;
  // @cmember:(INTERNAL) Fine della selezione (colonna, line del FILE)
  TPoint  _sel_end;

  // @cmember:(INTERNAL) Array di link ammessi
  TArray* _links;
  // @cmember:(INTERNAL) Array di hotspots
  TArray* _hotspots;
  // @cmember:(INTERNAL) Array di segnalibri
  TArray* _bookmarks;
                                          
  // @cmember:(INTERNAL) Indica se occorre ridisegnare la selezione
  bool need_paint_sel(bool smart = TRUE);                                            
  
  // @cmember:(INTERNAL) Array di icone del modulo scorrevole durante la stampa
  TArray _modules;
  // @cmember:(INTERNAL) Array di immagini propriamente ridimensionate
  TArray _images;

  // @cmember:(INTERNAL) Indica se e' attivato il link multiplo se si' vengono passati all'handler tutti i 
  //          link presenti sulla stessa riga anziche' solo il selezionato
  bool _multiple;
  // @cmember:(INTERNAL) Testo del link
  TString _linktxt;
  // @cmember:(INTERNAL) Identificatore del link
  int _linkID;
  // @cmember:(INTERNAL) Indica tutti i link della riga nel caso di link multiplo
  TToken_string _multiple_link;
  
  // @cmember:(INTERNAL) Array di colori di background
  TString_array* _bg;
  // @cmember:(INTERNAL) Indica se la stampa e' stata interrotta
  bool _frozen;
  // @cmember:(INTERNAL) Finestra in primo piano (se FALSE e un campo di una maschera)
  bool _toplevel;
  // @cmember:(INTERNAL) Indica se mostrare il righello
  bool _rulers;
  // @cmember:(INTERNAL) Indica se visualizzare i bottoni
  bool _showbuts;
  // @cmember:(INTERNAL) Indica se si sta attivando un link
  bool _inside_linkexec;
  // �cmember:(INTERNAL) Indica se e' presente il menu' specifico della calsse
  bool _menu_present;  
  // @cmember:(INTERNAL) Viene istanziato soltanto se e' usata come controllo
  TBrowsefile_field* _brwfld;                          
  // @cmember: (INTERNAL) Rettangolo finestra madre
  RCT _wr;

  // @access Protected Member  
protected:
  // @cmember Gestisce la pressione del tasto
  virtual bool on_key (KEY);
  // @cmember Apre la finestra di visualizzazione???
  virtual void open();
  
  // @cmember Converte i caratteri in x in pixel
  int tabx(int x) const;
  // @cmember Converte i caratteri in y in pixel
  int taby(int y) const;

  // @cmember Cancella l'area di testo col colore <p c>
  void txt_clear(COLOR c);

  // @cmember Sposta lo schermo nella direzione <p dir> di 1
  void shift_screen(scroll dir);
  // @cmember Disegna lo schermo sulla porzione corrente di testo
  void paint_screen();
  // @cmember Disegna il cursore a crossbar in XOR
  void draw_crossbars();

  virtual void on_button(short dlg);

  // @cmember Disegna l'header del video (righello)
  void paint_header();
  // @cmember Disegna il cursore in xor nello stile del momento 
  void paint_point(bool erase = FALSE);
  // @cmember Disegna la riga <p r>-esima (in coordinate testo)
  void paint_row(long r);
  // @cmember Disegna una colonna
  void paint_column(long r, bool end); 
  // @cmember Disegna in xor la selezione corrente a meno che non sia gia' disegnata
  void paint_selection();                             
  // @cmember Controlla l'immagine di 'busy'; xor serve solo per UNIX, dove si 
  //          disegna una barra che viene cancellata alla prossima paint.
  void paint_waitbar(bool xor = TRUE); 
  // @cmember Permette di stampare il bakcground di riga <p row> e colonna <p col>
  void paint_background(long, int);
  // @cmember Chiama l'editor selezionato nel file PRASSI.INI. Ritorna il risultato della 
  //          chiamata (TRUE se e' riuscito a chiamarlo)
  bool call_editor();
  // @cmember copia l'eventuale selezione nella clipboard 
  void sel_to_clipboard();
  // @cmember Ritorna se in punto <p p> e' nel testo mostrato
  bool in_text(const TPoint& p) const; 

  // @cmember Aggiunge un bottone alla finestra
  TPushbutton_control* add_button(short id, const char* caption, short bup = 0, short bdn = 0);
  // @cmember Riposiziona i bottoni centrandoli a seconda di quanti sono presenti
  void repos_buttons();
  // @cmember Assicura che la selezione rimanga nei limiti fisici del testo
  void adjust_selection(TPoint& p1, TPoint& p2);
  // @cmember Interfaccia per paint_selection: mostra se non c'e'
  void display_selection();
  // @cmember Interfaccia per paint_selection: cancella se c'e'
  void erase_selection();
  // @cmember Interfaccia per paint_point (se cross): mostra se non c'e'
  void display_crossbar();
  // @cmember Interfaccia per paint_point (se cross): cancella se c'e'
  void erase_crossbar();
  // @cmember Interfaccia per paint_point (se point): mostra se non c'e'
  void display_point();
  // @cmember Interfaccia per paint_point (se point): cancella se c'e'
  void erase_point(); 

  // @cmember Controlla se la posizione cursore <p where> cade su un
  //          link ipertestuale e si comporta di conseguenza
  bool check_link(TPoint* where = NULL);
  // @cmember Modifica le dimensione di un box
  bool adjust_box(long& x1, long& x2, long y);

  // @cmember Mostra il link ipertestuale se non c'e'
  void paint_link(long y, long x1, long x2);  
  // @cmember Cancella il link ipertestuale se c'e'
  void erase_link(long y, long x1, long x2);
  // @cmember Mostra in xor il link ipertestuale (utilizzata da <mf TViswin::paint_link> e da
  //          <mf TViswin::erase_link>
  void display_link(long y, long x1, long x2, const char* d); 

  // @cmember Usata internamente per bloccare l'aggiunta di nuove righe
  void freeze() 
  { _frozen = TRUE; }

  // @cmember Chiama l'handler del link se si preme collega o si batte spazio su un link
  void exec_link();
  // @cmember Controlla la generazione menu indice se ci sono segnalibri
  void build_index_menu();

  // @cmember Viene chiamata quando si tenta di fare uno scroll impossibile da <p x> o <p y>:
  //          emette un suono e non effettuata lo scroll
  void scroll_error(long x, long y);
  
  // @cmember Aggiorna la finestra di stampa
  virtual void update();
  // @cmember Gestisce l'handler della finestra (vedi <mf TWindow::handler>
  virtual void handler(WINDOW win, EVENT* ep);
  
  // @cmember Controlla se e' stato selezionato la voce <p item> (parametro <p on>???)
  void check_menu_item(MENU_TAG item, bool on = TRUE);
  // @cmember Abilita/Disabilita una voce di menu'
  void enable_menu_item(MENU_TAG item, bool on = TRUE);
  
  // @access Public Member
public:
  // @cmember Permette di gestire i collegamenti ipertestuali. Occorre passare il testo completo
  //          <p txt>, il punto di inizio selezione <p start> e quello di fine selezione <p end>;
  //          se non c'e' selezione non viene chiamata affatto (il bottone non fa nulla)
  //          Se serve, si faccia <mf TWindow::stop_run> qui dentro.
  virtual void process_link(TTextfile& txt, TPoint start, TPoint end)
  { }
  // @cmember Termina la stampa su video e crea il menu indice se c'e'
  void close_print();
  // @cmember Interrompe la stampa
  bool frozen()
  { return _frozen; }
  // @cmember Interrompe la stampa su video (ESC durante la stampa)
  void abort_print();

  // @cmember Ritorna il numero di righe del testo da stampare
  long lines() 
  { return _txt.lines(); }
  // @cmember Ritorna il testo da stampare
  TTextfile& text() 
  { return _txt; }

  // @cmember Sposta la visualizzazione di stampa alle chiavi (chiama <mf TViswin::goto_pos>)
  void goto_end();
  // @cmember Sposta la visualizzazione di stampa alle azioni del menu' (chiama 
  //          <mf TViswin::goto_pos>)
  void goto_top();
  // @cmember Sposta la visualizzazione di stampa alla posizione indicata
  void goto_pos(long r, long c, bool moveorigin = TRUE);

  // @cmember Opera un ridisegno della pgina di anteprima a video
  void refresh();

  // @cmember Indica se mostrare o no il righello
  void show_rulers (bool on = TRUE);
  // @cmember Indica se mostrare o no i bottoni della finestra di anteprima
  void show_buttons(bool on = TRUE);

  // @cmember Stampa nella finestra la riga <p l>-esima
  void add_line(const char* l);                                       
  
  // @cmember Funzione di ricerca non interattiva
  long search (const char* txt,  int& pos, long from = 0, bool down = TRUE, bool casesens = FALSE, bool regx = FALSE);
  // @cmember Funzione di sostituzione di un testo all'interno di una riga non interattiva
  int replace(long line, const char* txt, int pos = 0, int len = -1);

  // @cmember Funzione di ricerca interattiva
  void find();
  // @cmember Funzione di ricerca prossimo elemento interattiva
  void find_next();

  // @cmember void | TViswin | const char* fname=NULL, const char* title=NULL, 
  //                           bool editbutton=TRUE, int width=0, bool rulers=3,
  //                   WINDOW parent=NULL_WIN, TBrowsefile_field*=NULL | Costruttore
  TViswin(const char* fname=NULL, const char* title=NULL, bool editbutton=TRUE,
          bool printbutton=TRUE, bool linkbutton=TRUE, int x=-1, int y=-1, int height=0,
          int width=0, bool rulers=3, WINDOW parent=NULL_WIN, TBrowsefile_field* =NULL);
  // @cmember Distruttore
  virtual ~TViswin ();
};

#endif

// @doc INTERNAL

// @enum scroll | Direzioni da utilizzare nello scroll
//
// @emem none | Nessuno scroll
// @emem up | Scroll verso l'alto
// @emem down | Scroll verso il basso
// @emem left | Scroll verso sinistra
// @emem right | Scroll verso destra
//
// @comm Questa struttura viene usata esclusivamente all'interno della classe <c TViswin>