// (c) Jean MICHEL June 1993 -- any modifications must be signaled to the
// author

// cell.h: classes to compute life generations. This is completely
// independant from windows, and can be used on any system

typedef int BOOL;
#define FALSE 0
#define TRUE 1

#define INTCELL unsigned long
#define BASE 0x10000l
#define HALFBASE 0x8000l
/* point (x,y) coded as (x+HALFBASE)+BASE*(y+HALFBASE)
		     (origin (-HALFBASE,-HALFBASE)),
   sorted, end marked by INFINI */

class cell_type
{ public:
  unsigned x,y;
  cell_type(){x=y=0;}
  cell_type(INTCELL l){*(INTCELL*)this=l;}
  cell_type(unsigned xx,unsigned yy){x=xx+HALFBASE;y=yy+HALFBASE;}
  cell_type operator +(cell_type c){return cell_type(x+c.x,y+c.y);}
  cell_type operator -(cell_type c){return cell_type(x-c.x,y-c.y);}
  operator INTCELL(){return *(INTCELL*)this;}
  BOOL operator ==(cell_type c){return *(INTCELL*)this==(INTCELL)c;}
  BOOL operator !=(cell_type c){return *(INTCELL*)this!=(INTCELL)c;}
  BOOL operator <(cell_type c){return *(INTCELL*)this<(INTCELL)c;}
  BOOL operator >(cell_type c){return *(INTCELL*)this>(INTCELL)c;}
  int cellx(){return (int)(x-HALFBASE);}
  int celly(){return (int)(y-HALFBASE);}
};

enum {UNSET,SET,RESET};
enum {LAY_ON=1,LAY_OFF=2,LAY_XOR=3};

// cellpop: a population of cells

class cellpop
{ public:
  cell_type *v;
  int pop;                // number of cells
  cellpop();              // default constructor (empty population)
  cellpop(cell_type *);   // constructor from a vector of cell_type
  cellpop(char *);        // constructor from a string
  cellpop(int n);         // constructs a line of n cells
  ~cellpop();
  cellpop(cellpop&w);     // copy constructor
  void operator=(const cellpop& w);  // assignment operator
  BOOL operator==(cellpop& w);       // equality test
  void nextgen(cellpop& w);          // w is next generation from this
  BOOL in(cell_type c);              // tests if c is in this
  BOOL error(){return v==0;}
  void erase_rect(cell_type start,cell_type end);
                                     // erase all cells between bounds
  void save(char *FileName);
                                     // save population to file
  void save_rect(char *FileName,cell_type start,cell_type end);
                                     // save cells within bounds to file
  cell_type firstx(void);            // find leftmost cell
  cell_type firsty(void);            // find topmots cell
  cell_type lastx(void);             // find rightmost cell
  cell_type lasty(void);             // find bottommost cell
  void transform(char orientation);  // rotate pop. or mirror it
  void add(cellpop&v,cellpop &shape,cell_type offset,int mode);
                                     // this=v+shape added at given offset
				     // where mode is one of ON, OFF,XOR
  void clear_pop();
};

cellpop readfile(char *filename);    // read pop. from file
void readshapelib(char *FileName);   // load shape library
cellpop getshape(int i);             // find ith shape in library
char *getshapename(int i);           // find name of ith shape in library
