#ifndef __VISWIN_H
#define __VISWIN_H

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

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

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

class TBrowsefile_field;                                 

// @doc EXTERNAL

// @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

// @access Private Member
{
  // @cfriend TBrowsefile_field
  friend class TBrowsefile_field;

  // @ccost MAXBUT | 4 | Numero massimo di bottoni disponibili nella pagina
  enum { MAXBUT = 4, 
         // @ccost MAXLEN | 256 | Lunghezza massima del modulo di stampa
         MAXLEN = 256, 
         // @ccost BUFFERSIZE | 256 | Dimensione del buffer di stampa
         BUFFERSIZE = 256, 
         // @ccost MAXPIC | 4 | Numero massimo di immagini gestibili nell'anteprima
         MAXPIC=4};


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

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

  // @cmember Bottone Collega
  WINDOW _link_button;
  // @cmember Bottone Stampa
  WINDOW _print_button;

  // @cmember Numero di righe di testo
  long _textrows;
  // @cmember Numero di colonne di testo
  long _textcolumns;

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

  // @cmember Strina di testo da cercare
  TString _txt_to_find;
  // @cmember Posizione dell'ultima ricerca
  TPoint _last_found;
  // @cmember Direzione della ricerca (TRUE verso il basso FALSE verso l'alto)
  bool _down_dir;
  // @cmember Indica se si deve fare una ricerca case sensitive
  bool _case_sensitive;

  // @cmember Lunghezza della pagina
  int _formlen;
  
  // @cmember Posizione corrente del punto
  TPoint _point;
  // @cmember Posizione corrente dell'incrocio della crossbar
  PNT _cross;
  // @cmember Inizio della selezione (colonna, line del FILE)
  TPoint _sel_start;
  // @cmember Fine della selezione (colonna, line del FILE)
  TPoint  _sel_end;

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

  // @cmember 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 Testo del link
  TString80 _linktxt;
  // @cmember Identificatore del link
  int _linkID;
  // @cmember Indica tutti i link della riga nel caso di link multiplo
  TToken_string _multiple_link;
  
  // @cmember Array di colori di background
  TArray* _bg;
  // @cmember Indica se la stampa e' stata interrotta
  bool _frozen;
  // @cmember Finestra in primo piano (se FALSE e un campo di una maschera)
  bool _toplevel;
  // @cmember Indica se mostrare il righello
  bool _rulers;
  // @cmember Indica se visualizzare i bottoni
  bool _showbuts;
  // @cmember Indica se si sta attivando un link
  bool _inside_linkexec;
  // òcmember Indica se e' presente il menu' specifico della calsse
  bool _menu_present;  

  // @cmember Viene istanziato soltanto se e' usata come controllo
  TBrowsefile_field* _brwfld;

  // @access Protected Member  
protected:
  // @cmember !!!???!!!
  virtual bool on_key (KEY);
  // @cmember !!!???!!!
  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 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();

  // @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 Ritorna se in punto <p p> e' nel testo mostrato
  bool in_text(const TPoint& p) const; 

  // @cmember Aggiunge un bottone alla finestra
  WINDOW  add_button(short id, const char* caption);
  // @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 !!!???!!!
  virtual void update();
  // @cmember !!!???!!!
  virtual void handler(WINDOW win, EVENT* ep);
  
  // @cmember !!!???!!!
  void check_menu_item(MENU_TAG item, bool on = TRUE);
  // @cmember !!!???!!!
  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);
  // @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=TRUE,
  //                                                                                                     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=TRUE, WINDOW parent=NULL_WIN, TBrowsefile_field* =NULL);
  // @cmember Distruttore
  virtual ~TViswin ();
};

#endif

// @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>
