/* actually -*-c++-*- */
#ifndef __TEXTFILE_H
#define __TEXTFILE_H

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

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

#ifndef __STDIO_H
#include <stdio.h>
#endif                                     

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


enum direction {up, down, updown};
enum style     {normal = 0, bold = FS_BOLD, italic = FS_ITALIC, underlined = 0x0004, 
                overstrike = 0x0008, smallcaps = 0x0010};        

class TTextfile: public TObject
{
  enum {DEFAULT_PAGESIZE = 128};

  TArray        _page;
  long          _page_start;
  long          _page_end;
  long          _page_size;
  long          _lines;
  long          _cur_line;                             
  TFilename     _filename;
  TFilename     _indname;
  FILE*         _index;
  FILE*         _instr;
  direction     _direction;
  TToken_string _line;
  long          _styles[256];
  int           _item;  
  TArray        _hotspots;
  TArray        _spots;
  bool          _dirty;
  bool          _isopen;   
  bool          _istemp;        
  bool          _accept;

  void   _read_page(long line);         
  bool   _in_page(long l) 
  { return  l >= _page_start && l < _page_end; }
  //  void   _parse_style(long j);
  style  _trans_style(char c);          
  
public:
  
  long        lines()   { return _lines; }
  bool        changed() { return _dirty; }   
  
  // line() ritorna la stringa di caratteri senza formattazione
  const char* line(long row, long column = 0);
  // line_formatted() la ritorna, come e' logico attendersi, con
  // la formattazione
  const char* line_formatted(long row);
  // appende una riga al text (con i formati del caso)
  bool        append(const char* l);  
  
  // chide tutti i files per poter copiare o eseguire operazioni
  // dopo close() non si puo' piu' fare nulla
  void        close();
  void        print();                     
  // chiude l'aggiunta di nuove linee
  void        freeze() { _accept = FALSE; }
  bool        frozen() { return  !_accept; }
  
  // per leggere il testo formattato, si fa prima read_line, poi      
  // si prende un pezzo per volta 
  // style() ritorna lo stile (vedi enum) del piece() corrente
  // se chiamata con parametri ritorna lo stile del carattere alla 
  // posizione data 
  // get_background() e get_foreground() ritornano il suo colore di bg e fg
  // piece() ritorna il pezzo di linea successivo con stile e colore
  // invarianti, o NULL quando non ce n'e' piu'     
  // bello, vero?
  
  void        read_line(long j, long b = 0, bool pg = TRUE);
  const char* piece();            
  int         get_style(int pos = -1);
  char        get_background(int pos = -1);              
  char        get_foreground(int pos = -1); 
  
  long        get_attribute(int pos = -1);
  
  // ritorna la parola alla posizione indicata
  const char* word_at(long x, long y);                  
  // TBI ritorna il pezzo di testo da x a y  
  // allochera' un altro TText che deve essere disfatto dall'utente
  TTextfile*  section(TPoint& from, TPoint& to) { return this; }    
  const char* name() { return (const char*)_filename; }  
  
  // scrive il testo (non formattato) su file, da punto a punto
  // (tutto per default)
  bool        write(const char* path, TPoint* from = NULL, TPoint* to = NULL);
  // disfa tutto e svuota il file
  void        destroy(); 

  // hypertext cazzuls                         
  // le si dice il colore che devono avere i punti selezionabili;
  // ritorna l'array in cui vengono messi gli hotspots relativi alla
  // pagina in memoria (come TToken_string con x|y|text)
  void set_hotspots(char fg, char bg = 'w');
  TArray& hotspots() { return _spots; }
  
  TTextfile(const char* file = NULL, int pagesize = DEFAULT_PAGESIZE, 
            direction preferred = updown);
  virtual ~TTextfile();
};

#endif

