// $Id: sheet.hh,v 1.36 1998/09/29 01:19:43 cthulhu Exp $

#ifndef _SHEET_DOT_HH_
#define _SHEET_DOT_HH_


// Every 600 cells, we update the spreadsheet and give the user a chance 
#define UPDATE_RATE 600  
#define MAX_GRAPHS 100

extern "C" {
#include "tcl.h"
#include "tk.h"
}
#include "utils.hh"
#include "stdlib.h"
#include "string.hh"
#include "defines.hh"
#include "format.hh"
#include "cell.hh"
#include "calc.hh"
#include "array.hh"
#include "constants.hh"
#include "event.hh"
#include "list.hh"

#include "canvas.h"

#define PASTE_CELLS 1
#define PRINT_WHOLE_SHEET 1
#define PRINT_PRINT_RANGE 2

#define UNDO 0
#define REDO 1

#define ON 1
#define OFF 0

#define SET_ERROR(pt,error) { \
  pt->contents.error_code = error; \
}

#define CHECK_COL_BOUNDS(c)  ((c) >= 0 && (c) < DEFSHEETWIDTH) 
#define CHECK_ROW_BOUNDS(r)  ((r) >= 0 && (r) < DEFSHEETHEIGHT) 

class Sheet;

class Paste_buffer {
  public:
    int type;
    Sheet *sheet;
    Range rg;
    array<Cell> cells;
};

class Cellp {
    Cell *pt;
};

class Cell_buffer {
  public:
    array<Cell *> cells;
};


class Sheet_format {
public:
  short type;
  short sh_val1; 
  short sh_val2;
  unsigned char c_val1;
};

class Cell_info {
  short row;
  short col;
  Cell *cell;
};

class Rc_info {
public:
  array<Cell*> cells;
};

class Graph {
public:
    int iter;
    int number;
    int used;
    int graphType;
    Range range;
    int graphX;
    int graphY;
    int graphHeight; 
    int graphWidth;
    int graphCol;
    int graphRow;
    int iparams[10];
    double fparams[10];
    Graph() {
        int i;
        iter = -1;
        used = FALSE;
        for(i=0; i<10; i++) {
            iparams[i] = 0;
            fparams[i] = 0;
        }
        
    }
};


class Print_Settings {
public:
  int set;
  float leftMargin,rightMargin,topMargin,bottomMargin;
  float scale;
  int colorMode;
  int typeView;
  
  int fromPage, toPage;
  int pageType;
  int print_selection;

  int reserved1;
  int reserved2;
  int reserved3;
  int reserved4;
  int reserved5;
  int reserved6;
  int reserved7;
  int reserved8;
  Print_Settings() {
    set = 0;
    print_selection = PRINT_WHOLE_SHEET;
  }
};

class Sheet {
  Tcl_Interp *interp;
  short def_cell_width;
  short def_cell_height;
  Stack_elem *stack;
  int modified;
  int iteration;
  array<Dependence> cells_to_eval;
  Lista<Event> event_l;
  Node<Event> *event_it;
  short undo_on;
  short redo_on;
public:
  unsigned char automatic_recalc;
  char recalculate_before_saving;
  
  Range print_range;
  
  Range sort_range;
  Print_Settings psettings;
  Graph *graphs[MAX_GRAPHS];
  int graphs_cnt;
  Canvas *canvas_info;
  char canvas[80];
  char row_labels[80];
  char col_labels[80];
  char vscroll[80];
  char hscroll[80];
  int modified_after_save;
  int borderItemId;
  int empty;
  int display_cell_borders;
  int page_borders;
  Fontinfo default_font;
  char *default_font_name;

  /* Initializations */
  Sheet(char *,Tcl_Interp *interp);
  ~Sheet();
  void fill_widget_names(char *name);

  Format *format;

  array<Rc_info> rows;
  array<Rc_info> cols;

  array<Sheet_format> formats;

  int max_col, max_row;
  int max_col_used, max_row_used;
  int min_col_used, min_row_used;

  string name;
  Tcl_HashTable cells;
  Tcl_HashTable dirty_cells;
  Parser parser;

  /* Column and Row formats */
  Tcl_HashTable row_formats;
  Tcl_HashTable col_formats;
  
  /* Geometry management */
  int cell_width(short col) {
    return(canvas_info->col_origin[col+1]-canvas_info->col_origin[col]);
  }
  int cell_height(short row) {
    return(canvas_info->row_origin[row+1]-canvas_info->row_origin[row]);
  }
  int col_origin(short col) {
    return(canvas_info->col_origin[col]);
  }
  int row_origin(short row) {
    return(canvas_info->row_origin[row]);
  }
  int max_text_width(short col) ;
  int text_width(Cell *cell) ;
  void set_col_width(int col, int width);
  void set_row_height(int row, int width);

  void get_first_and_last_col(Cell *cell, int &first, int &last);
    
  /* Defaults, so far */
  int width() {return(DEFSHEETWIDTH);}
  int height() {return(DEFSHEETHEIGHT);}

  /*  int x_coord(short);
  int y_coord(short);*/
  void display(Cell *cell, int clear = TRUE);
  void display(array<Cell *> &cells, int clear=TRUE);

  /* Cell access functions */
  Stack_elem *cellRef(short col, short row);
  Cell *cellSet(short col, short row, char *form);
  char * stack_string(Stack_elem *);
  double stack_value(Stack_elem *);
  Cell *cellFind(Ref &ref);
  int propagate_error(Stack_elem *ptfrom, Stack_elem *ptto) ;
  int propagate_error(Cell *cell, Stack_elem *ptto) ;
  Cell *cellExists(short col, short row);
  Cell *cellFind(short col, short row);
  int evalCell(Cell *cell);

  /* Cell manipulation */
  void manipulateReferences(Cell *cell, int operation, Oper_info *info = NULL);
  void insertCell(Cell *cell);
  void removeCell(Cell *cell);
  short findIndex(Rc_info &arr,short, int /* 0 = row, 1 = col */);
  void depth_first_search(Cell *cell) ;
  void copyToBuffer(Cell *cell, Cell_buffer &buffer);
  void removeFromCellList(Cell *cell) ;
  void insertInCellList(Cell *cell);
  void add_graph_deps(Graph *grp);
  void remove_graph_deps(Graph *grp);

  /* Primitives for display */
  void redraw();
  void update();
  void scroll_to(int x, int y, int actualize_origin);
  Tk_Item *draw_text(char *st, int x, int y, int anchor,
                     int col,int row,char *font);
  int draw_rectangle(char *st, int x, int y, int anchor,
                     int col,int row,char *font);
  int draw_borders(Cell *cell,int x1, int y2, int x2, int y2);

  /* Primitives required for evaluation */
  void global_recalc();
  int recalc(Cell *cell);
  int recalc(array<Cell *> &cells);
  int recalculate_list_of_cells();
  void remove_from_dirty(Cell *cell);
  void add_to_dirty(Cell *cell);


  Stack_elem *cell_value(short col, short row);
  Stack_elem *top;
  Stack_elem *formula(Cell *cell);
  Stack_elem *evaluate(Cell *cell);
  char *formula_string(Cell *cell);

  /* IO functions */
  int load(char *filename);
  int save(char *filename,short query=1);
  int write_record(int f, short code, short length, char *data);

  /* Undo and Redo */
  void SetUndoRedoGUI(int,int);
  void RegisterEvent(Event *);
  void Undo();
  void Redo();

  /* Run external tcl code from script or from given filename */
  void RunScript(char *);
  int RunScriptFromFile(char *);
};

int DefCellWidth();
int CharWidth();


#endif

// $Log: sheet.hh,v $
// Revision 1.36  1998/09/29 01:19:43  cthulhu
// Added query option to sheet::save for autosave.
//
// Revision 1.35  1998/08/25 20:57:46  cthulhu
// Added RunScriptFromFile to run user-based scripts (macros).
//
// Revision 1.34  1998/08/06 21:08:49  aml
// Released alpha version of Abacus.
//
//Revision 1.33  1997/03/27  10:00:44  aml
//Started implementing graphs.
//Fixed bug in tkCanvasPs.c
//Created bindings for composite characters in Portuguese.
//
// Revision 1.32  1997/02/10 15:11:08  aml
// Print settings now are saved to file.
// Fixed buggy error message when loading sheets.
//
// Revision 1.31  1997/01/07 01:07:49  aml
// Error propagation for formulas fixed.
// Edit operations in place.
//
//Revision 1.30  1996/12/31  17:38:48  aml
//On-demand calculation improved. Loops are detected.
//Automatic recalculation can now be disabled.
//Printing was improved.
//
// Revision 1.29  1996/12/11 21:40:07  aml
// Sumif implemented.
// Diverse time functions implemented.
// Fixed needtoscroll2 to avoid out of control scroll.
//
// Revision 1.28  1996/11/22 16:29:25  aml
// First cut at transforming canvas into a true cell widget.
// Text, lines and rectangles are now relative to row and colunm numbers.
// It still has a bug with wrong estimation of column widths.
//
// Revision 1.27  1996/10/09 13:55:16  aml
// First cut of full print.
//
// Revision 1.26  1996/09/19 12:17:21  aml
// Created row and column insert.
// Fixed small problem with display of vergrown cells.
//
// Revision 1.25  1996/09/15 19:25:26  aml
// Rulling and shading.
// Optionally hide cell borders.
// Works well, but is very slow for large spreadsheets.
//
//Revision 1.24  1996/09/02  10:52:09  aml
//Cell fonts created, loaded and saved.
//Row height created.
//
//Revision 1.23  1996/08/27  17:19:08  aml
//First version of regressive tests created.
//Changes were made to allow for string functions.
//String function upper created. Raises the problem
//that formulas do NOT have a space for string values,
//and therefore have to be evaluated upon loading.
//
// Revision 1.22  1996/08/26 12:08:59  aml
// Fixed problem with several sheets. Each canvas now has its own
// canvas info.
// Fixed scroll up and down. Implemented max_row and max_col.
// Fairly stable version.
//
//Revision 1.21  1996/08/24  10:16:15  aml
//Scroll almost fixed. We are missing scroll steps.
//Several sheets work again, but need to be fixed right.
//
//Revision 1.20  1996/07/23  14:01:20  aml
//Changed canvas widget to handle special items like cell borders.
//Seems to work well. Spreadsheet size is no more limited now.
//
// Revision 1.19  1996/07/18 10:19:44  aml
// Created formats for cells.
// Load cell now makes copy of old file.
//
// Revision 1.18  1996/04/23 09:43:10  aml
// Data structures for ordered scans of rows and columns are in place.
// Cell overlap is working.
// Forward cell dependences inserted. Automatic recalculation created.
// Uniformizaed label entry procedure.
//
// Revision 1.17  1996/04/21 13:28:28  aml
// Sped up scroll functions, caching keys presses.
// First cut at handling overflowing cells.
// Overflow into ajoining filled cells not solved.
//
//Revision 1.16  1996/04/19  10:46:45  aml
//First cut at speeding up canvas critical functions.
//CanvasWidgetCommand is now called directly from draw_sheet.
//Fixed bug in reading values from datafiles. Also works
//for Suns now.
//Created canvas directory, replacing builtin command canvas.
//
// Revision 1.15  1996/03/11 15:47:55  aml
// Made redraw more efficient by removing at once all cells before redrawing.
// Fixed problem with unsufficient difinition of logical expressions.
// Added >=, <=, <>, @and and @or functions.
//
// Revision 1.14  1996/03/07 20:33:16  aml
// Created print range ability.
// Set in gray non-working menus.
// Created RangeKill command.
// Created round function and macros for single argument functions.
//
// Revision 1.13  1996/03/06 20:25:33  aml
// Improved user waiting times during redraw and loads by calling update.
//
// Revision 1.12  1996/03/01 13:08:52  aml
// Stack references are now pushed instead of double value.
// Fixed problem with integers too large on formulas.
// Scroll with cursors now works better.
//
// Revision 1.11  1996/02/19 15:47:42  aml
// Fixed abnormality with mouse click.
// Variable width columns implemented, but not yet saved.
// Labels are now a lex element, fixing some aberrant behavior that existed.
//
//Revision 1.10  1996/02/13  12:04:01  aml
//Fixed bug with range definition via mouse.
//Fixed bug in range iterators.
//
// Revision 1.9  1996/01/09 18:34:59  aml
// Load, save, open, close and exit now work properly (hopefuly).
// Sheet utility functions also work : SheetExists, SheetEmpty, SheetModified
//
//Revision 1.8  1996/01/07  09:07:57  aml
//Sheet::save and Sheet::load created.
//Program can now write and read wk1 files.
//Slight changes made to relative references. Bit 14 is now always 0.
//
//Revision 1.7  1996/01/05  23:06:07  aml
//Cell references evaluated.
//Spreadsheet is recalculated at every change, by an arbitrary order.
//Reformulated program structure. Evaluation and reverse parsing
//are member functions of Sheet.
//
//Revision 1.6  1996/01/03  23:07:21  aml
//Absolute and relative references to cells introduced.
//They are parsed and reverse parsed, not yet evaluated.
//
//Revision 1.5  1996/01/02  16:22:27  aml
//Formula compilation, evaluation and decompilation now work.
//Cells can be of type label, numerical formula or numbers.
//
//Revision 1.4  1995/12/28  19:20:41  aml
//Created skeleton to merge calculation engine
//
//Revision 1.3  1995/12/27  23:13:08  aml
//First draft of Sheet::display
//
//Revision 1.2  1995/12/13  14:39:21  aml
//None
//
//Revision 1.1  1995/12/13  14:33:26  aml
//Initial revision
//

