#ifndef SHEET_H
#define SHEET_H

/* Solaris needs termios.h to be included or NCC will not be defined :( */
#include <termios.h>
#include <curses.h>

#include "scanner.h"

typedef enum { LEFT=0, RIGHT=1, CENTER=2 } Adjust;

typedef enum { IN_X, IN_Y, IN_Z } Direction;

#define ASCENDING  001

typedef struct
{
  int x;
  int y;
  int z;
  int sortkey; /* OR-ed value of the above constants */
} Sortkey;

typedef struct
{
  Token **contents;
  char *label;
  Token value;
  Adjust adjust;
  int precision;
  int updated:1;
  int shadowed:1;
  int scientific:1;
  int locked:1;
} Cell;

typedef struct
{
  int curx, cury, curz;
  int mark1x, mark1y, mark1z;
  int mark2x, mark2y, mark2z;  
  int marking;
  int offx, offy;
  Cell **sheet;
  int *column;
  int dimx, dimy, dimz;
  WINDOW *window;
  char *name;
  int changed:1;
} Sheet;

extern Sheet *upd_sheet;
extern int upd_x;
extern int upd_y;
extern int upd_z;

void forceupdate(Sheet *sheet);
void freecell(Sheet *sheet, int x, int y, int z);
int columnwidth(Sheet *sheet, int x, int z);
void setwidth(Sheet *sheet, int x, int z, int width);
int cellwidth(Sheet *sheet, int x, int y, int z);
void putcont(Sheet *sheet, int x, int y, int z, Token **t);
Token **getcont(Sheet *sheet, int x, int y, int z);
Token getvalue(Sheet *sheet, int x, int y, int z);
char *geterror(Sheet *sheet, int x, int y, int z);
void printvalue(char *s, size_t size, int star, int quote, int scientific, int precision, Sheet *sheet, int x, int y, int z);
Adjust getadjust(Sheet *sheet, int x, int y, int z);
void setadjust(Sheet *sheet, int x, int y, int z, Adjust adjust);
void shadow(Sheet *sheet, int x, int y, int z, int yep);
int shadowed(Sheet *sheet, int x, int y, int z);
void lockcell(Sheet *sheet, int x, int y, int z, int yep);
int locked(Sheet *sheet, int x, int y, int z);
void setscientific(Sheet *sheet, int x, int y, int z, int yep);
int getscientific(Sheet *sheet, int x, int y, int z);
void setprecision(Sheet *sheet, int x, int y, int z, int precision);
int getprecision(Sheet *sheet, int x, int y, int z);
const char *getlabel(Sheet *sheet, int x, int y, int z);
void setlabel(Sheet *sheet, int x, int y, int z, const char *buf);
Token findlabel(Sheet *sheet, const char *label);
void freesheet(Sheet *sheet);
const char *savexdr(Sheet *sheet, const char *name);
const char *savetbl(Sheet *sheet, const char *name, const char *pages);
const char *savelatex(Sheet *sheet, const char *name, const char *pages);
const char *savetext(Sheet *sheet, const char *name, const char *pages);
const char *saveport(Sheet *sheet, const char *name);
const char *loadxdr(Sheet *sheet, const char *name);
const char *loadport(Sheet *sheet, const char *name);
void insertcube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction ins);
void deletecube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction ins);
void moveblock(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int copy);
const char *sortblock(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction dir, Sortkey *sk, size_t sklen);

#endif
