/* 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 TViswin : public TScroll_window
{
  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

  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;
  
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);
  
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 add_line(const char* l);

  TViswin (const char* fname = NULL, 
           const char* title = NULL, 
           bool editbutton   = TRUE, 
           bool printbutton  = TRUE, 
           bool linkbutton   = TRUE,
           int height        = 0,
           WINDOW parent     = NULL_WIN);
  
  virtual ~TViswin ();
};

#endif
