/* This is really -*-c++-*- */
#ifndef __VISWIN_H
#define __VISWIN_H

#ifndef __ARRAY_H
#include <array.h>
#endif

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

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

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

class TBrowsefile_field;                                 

class TViswin : public TScroll_window
{                                 
  friend class TBrowsefile_field;

  enum { MAXBUT = 4, MAXLEN = 256, BUFFERSIZE = 256, MAXPIC=4};
  enum scroll { none, up, down, left, right };

  TFilename _filename;    // name of visfile
  bool      _islink;      // "link" button present
  bool      _isedit;      // "edit" button present
  bool      _isprint;     // "print" button present
  bool      _iscross;     // crossbars being drawn
  bool      _selecting;   // selection in progress    
  bool      _isselection; // selection active
  bool      _isbar;       // X-bar drawn instead of cursor at point
  bool      _scrolling;   // scrolling in progress
  bool      _need_update; // full update required 
  bool      _istimer;     // timer successivo attivo?
  bool      _isopen;      // new lines may arrive 
  bool      _selflag; 
  bool      _sel_displayed;                         
  bool      _link_displayed;
  bool      _cross_displayed;
  bool      _point_displayed;
  long      _timer;       // timer per evitare autorepeat tasti
  long      _wtimer;      // wait timer before close()
  scroll    _need_scroll; // scrolling required?       
  bool      _wasneeded;   // flag for smart painting 
  WINDOW    _button[MAXBUT]; // button array        
  int       _curbut;      // button which currently has focus 
  int       _buttons;     // button count
  WINDOW    _link_button;

  long      _textrows;    // righe di testo
  long      _textcolumns; // indovina indovinello

  TTextfile _txt;         // text being displayed
  long _firstline;        // 1rst text line being displayed
  long _lastline;         // last text line being displayed

  TString   _txt_to_find; // text to find
  TPoint    _last_found;  // position of last find
  bool      _down_dir;    // search direction 
  bool      _case_sensitive;

  int _formlen;           // length of a page
  
  TPoint _point;          // current point position 
  PNT    _cross;          // current crossbar point
  TPoint  _sel_start;     // start of selection (column, line of FILE)
  TPoint  _sel_end;       // end   of selection (ibidem)

  TArray* _links;         // admitted links
  TArray* _hotspots;      // hotspots
  
  bool need_paint_sel(bool smart = TRUE);                                            
  PICTURE  _picture[MAXPIC]; // pictures
  PICTURE  _modpic;                                   
  bool     _multiple;
  TString80 _linktxt;
  int      _linkID;  
  TToken_string _multiple_link;     
  
  TArray*  _bg;
  bool     _isbackground;
  bool     _frozen;
  bool     _toplevel;             
  bool     _rulers;                                      
  bool     _showbuts;
  bool     _inside_linkexec;
  
  // viene istanziato soltanto se e' usata come controllo BROWSEFILE                          
  TBrowsefile_field* _brwfld;
  
protected:
  
  virtual bool on_key (KEY);                                 
  virtual void open();
  
  void    shift_screen(scroll);
  void    paint_screen();
  void    draw_crossbars();

  void    paint_header();
  void    paint_point(bool erase = FALSE);
  void    paint_row(long r);
  void    paint_column(long r, bool end); 
  void    paint_selection();                             
  void    paint_waitbar(bool xor = TRUE); 
  void    paint_background(long, int);
  bool    call_editor();
  bool    in_text(const TPoint& p)  const; 
  WINDOW  add_button(short id, const char* caption);
  void    repos_buttons();                
  void    adjust_selection(TPoint& p1, TPoint& p2);
  void    display_selection();
  void    erase_selection();
  void    display_crossbar();
  void    erase_crossbar();
  void    display_point();
  void    erase_point(); 
  bool    check_link(TPoint* where = NULL);
  bool    adjust_box(long& x1, long& x2, long y);
  void    paint_link(long, long, long);  
  void    erase_link(long, long, long);  
  void    display_link(long, long, long, const char*); 
  void    freeze() { _frozen = TRUE; }
  void    exec_link();

protected:
  
  virtual void update();
  virtual void handler(WINDOW win, EVENT* ep);
  
  void check_menu_item(MENU_TAG item, bool on = TRUE);
  void enable_menu_item(MENU_TAG item, bool on = TRUE);
  
public:
  
  // gestione "collegamenti": vengono passati il testo completo, 
  // il punto di inizio selezione e quello di fine selezione; se
  // non c'e' selezione non viene chiamata affatto (il bottone non fa nulla)
  // Se serve, si faccia stop_run() qui dentro
  virtual void process_link(TTextfile& txt, TPoint start, TPoint end)   { }
  void close_print();                 
  bool frozen() { return _frozen; }
  void abort_print();
  long lines() { return _txt.lines(); }               

  void goto_end();
  void goto_top();
  void goto_pos(long r, long c, bool moveorigin = TRUE);
  void refresh();

  void show_rulers (bool on = TRUE);
  void show_buttons(bool on = TRUE);

  void add_line(const char* l);                                       
  
  // non_interactive search and replace 
  long search (const char* txt,  int& pos, long from = 0,
               bool down = TRUE, bool casesens = FALSE);
  int  replace(long line, const char* txt, int pos = 0, int len = -1);

  // interactive search
  void find();
  void find_next();                                     
  
  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);
  
  virtual ~TViswin ();
};

#endif