/* Steven Andrews, 10/22/01 */
/* header for smollib.c */
/* See documentation called Smoldyn doc */
/* Copyright 2003-2005 by Steven Andrews.  Permission is granted
   for non-commercial use of and modifications to the code. */

#ifndef __smollib_h__
#define __smollib_h__

#include "SimCommand.h"

typedef struct moleculestruct {
	long int serno;																	// serial number
  double *pos;																			// dim dimensional vector for position
  double *posx;																		// dim dimensional vector for old position
	int *wrap;																			// cumulative wrapping on periodic bndries
  int ident;																			// identity of molecule; 0 is empty
  struct boxstruct *box;													// pointer to box which molecule is in
	struct panelstruct *pnl;												// last panel interacted with
	char face;																			// face of last panel interacted with
	double *via;																			// location of last surface interaction
	} *moleculeptr;

typedef struct molsuperstruct {
	double *difc;																		// diffusion constants for each identity
	double *difstep;																	// rms diffusion step for each identity
	double **difm;																		// diffusion matrix for each identity
	double *display;																	// size of molecule in graphical display
	double **color;																	// RGB color vector for each identity
	double **grphdata;																// all position data for graphics
	int *grphser;																		// number of rows in columns of grphdata
	moleculeptr *live[2];														// live molecules in system (0 mobile, 1 fixed)
	moleculeptr *dead;															// list of dead molecules
	int max;																				// size of each molecule list
	int nl[2];																			// number of molecules in live lists
	int topl[2];																		// index for live lists; above are reborn
	int nd;																					// total number of molecules in dead list
	int topd;																				// index for dead list; above are resurrected
	long int serno;  } *molssptr;										// serial number for next resurrected molec.

typedef struct wallstruct {
	int wdim;																				// dimension number of perpendicular to wall
	int side;																				// low side of space (0) or high side (1)
	double pos;																			// position of wall along dim axis
	char type;																			// properties of wall
	struct wallstruct *opp; } *wallptr;							// pointer to opposite wall

#define PSMAX 5																		// maximum number of panel shapes

typedef struct panelstruct {
	char pshape;																		// panel shape: (r)ect, (t)riangle, (s)phere
	struct surfacestruct *srf;											// surface that owns this panel
	int npts;																				// number of defining points
	double **point;																	// defining points, [number][dimension]
	double front[3];																	// front parameters, which depend on the shape
	} *panelptr;

typedef struct surfacestruct {
	char *faction;																	// action for molecules on front [nident]
	char *baction;																	// action for molecules on back [nident]
	double fcolor[4];																// RGBA color vector for front
	double bcolor[4];																// RGBA color vector for back
	double edgepts;																	// thickness of edge for drawing
	char fpolymode;																	// polygon drawing mode for front
	char bpolymode;																	// polygon drawing mode for back
	int maxpanel[PSMAX];														// allocated number of panels [ps]
	int npanel[PSMAX];															// actual number of panels [ps]
	panelptr *panels[PSMAX];												// list of panels [ps][p]
	 } *surfaceptr;

typedef struct surfacesuperstruct {
	int maxsrf;																			// maximum number of surfaces
	int nsrf;																				// number of surfaces
	char **snames;																	// surface names [s]
	surfaceptr *srflist;														// list of surfaces [s]
	} *surfacessptr;


typedef struct boxstruct {
	int *indx;																			// dim dimensional index of the box
	int nneigh;																			// number of neighbors in list
	int midneigh;																		// logical middle of neighbor list
	struct boxstruct **neigh;												// all box neighbors, using sim. accuracy
	int *wpneigh;																		// wrapping code of neighbors in list
	int nwall;																			// number of walls in box
	wallptr *wlist;																	// list of walls that cross the box
	int npanel;																			// number of surface panels in box	SSSSSSSSSSSSSSSSSSSSSSSSSSSSS
	panelptr *panel;																// list of panels in box SSSSSSSSSSSSSSSSSSSSSSSSSSSSS
	int maxmol[2];																	// allocated size of live lists
	int nmol[2];																		// number of molecules in live lists
	moleculeptr *mol[2]; } *boxptr;									// lists of live molecules in the box

typedef struct boxsuperstruct {
	double mpbox;																		// requested number of molecules per box
	double boxsize;																	// requested box width
	int nbox;																				// total number of boxes
	int *side;																			// number of boxes on each side of space
	double *min;																			// position vector for low corner of space
	double *size;																		// length of each side of a box
	boxptr *blist; } *boxssptr;											// actual array of boxes

typedef struct rxnstruct {
	int order;																			// order of reactions listed: 0, 1, or 2
	int *nrxn;																			// number of reactions for each set of reactants
	int **table;																		// lookup list of reaction numbers
	int lists;																			// live lists that have reactions
	int total;																			// total number of reactions listed
	char **rname;																		// names of reactions
	double *rate;																		// list of requested reaction rates
	double *rate2;																		// reaction rates modified for compuation
	double *rpar;																		// parameter for reaction of products
	char *rpart;																		// type of parameter in rpar
	int *nprod;																			// number of products for each reaction
	moleculeptr **prod; } *rxnptr;									// templates of products for each reaction

typedef struct simstruct {
	unsigned int randseed;													// random number generator seed
	int dim;																				// dimensionality of space.
	int maxident;																		// maximum number of identities
	int nident;																			// number of identities, including empty mols.
	char **name;																		// names of molecules
	int graphics;																		// graphics: 0=none, 1=opengl, 2=good opengl
	int graphicit;																	// number of time steps per graphics update
	int tiffit;																			// number of time steps per tiff save
	double framepts;																	// thickness of frame for graphics
	double gridpts;																	// thickness of virtual box grid for graphics
	double framecolor[4];														// frame color
	double backcolor[4];															// background color
	double accur;																		// accuracy, on scale from 0 to 10
	double time;																			// current time in simulation
	double tmin;																			// simulation start time
	double tmax;																			// simulation end time
	double dt;																				// simulation time step
	rxnptr rxn[3];																	// list of reactions
	molssptr mols;																	// molecule superstructure
	wallptr *wlist;																	// list of walls
	surfacessptr srfss;															// surface superstructure
	boxssptr boxs;																	// box superstructure
	cmdssptr cmds;																	// command superstructure
	double *v1,*v2,*v3;															// scratch space, each size dim or nident
	double *m1,*m2,*m3;															// scratch space, each size dim x dim
	int *z1,*z2,*z3;  } *simptr;										// scratch space, each size dim or nident


// molecule routines
moleculeptr molalloc(int dim);
void molfree(moleculeptr mptr);
molssptr molssalloc(int dim,int max,int nident);
void molssfree(molssptr mols,int nident);
void molssoutput(simptr sim);
void setdiffusion(simptr sim);
int molsort(molssptr mols,int difsort);
void diffuse(simptr sim);

// walls
wallptr wallalloc(void);
void wallfree(wallptr wptr);
wallptr *wallsalloc(int dim);
void wallsfree(wallptr *wlist,int dim);
void walloutput(int dim,wallptr *wlist);
int checkwalls(simptr sim);

// reactions
rxnptr rxnalloc(int order,int nident,int total);
void rxnfree(rxnptr rxn,int nident);
int loadrxn(simptr sim,FILE *fptr,int *lctrptr,char *erstr);
void rxnoutput(simptr sim,int order);
int findreverserxn(simptr sim,int i1,int i2,int r,int *optr,int *rptr);
int setrates(simptr sim,int order);
int setproducts(simptr sim,int order,char *erstr);
double calcrate(simptr sim,int i1,int i2,int r,double *pgemptr);
int doreact(rxnptr rxn,int r,moleculeptr mptr1,moleculeptr mptr2,simptr sim);
int zeroreact(simptr sim);
int unireact(simptr sim);
int bireact(simptr sim,int neigh);

// surfaces
int pshape2ps(char pshape,int dim,int *nptsptr);
int panelsalloc(surfaceptr srf,int dim,int maxpanel,char pshape);
void panelfree(panelptr pnl);
surfaceptr surfacealloc(int maxident,int dim);
void surfacefree(surfaceptr srf);
surfacessptr surfacessalloc(int maxsurface,int maxident,int dim);
void surfacessfree(surfacessptr srfss);
int loadsurface(simptr sim,FILE *fptr,int *lctrptr,char *erstr);
void surfaceoutput(simptr sim);
char panelside(double* pt,panelptr pnl,int dim);
int lineXpanel(double *pt1,double *pt2,panelptr pnl,char *faceptr,double *crsspt,double *cross,int dim);
int rxnXsurface(simptr sim,moleculeptr mptr1,moleculeptr mptr2);
void fixpt2panel(double *pt,panelptr pnl,int dim,char face);
void surfacereflect(moleculeptr mptr,panelptr pnl,double *crsspt,char face,int dim);
int dosurfinteract(moleculeptr mptr,panelptr pnl,char face,double *crsspt,int dim);
int checksurfaces(simptr sim,int ll,int reborn);

// boxes
boxptr boxalloc(int dim);
void boxfree(boxptr bptr);
boxptr *boxesalloc(int dim,int nbox);
void boxesfree(boxptr *blist,int nbox);
boxssptr boxssalloc(int dim);
void boxssfree(boxssptr boxs);
void boxoutput(int dim,boxssptr boxs);
void boxssoutput(simptr sim);
int expandbox(boxptr bptr,int n,int ll);
boxptr pos2box(simptr sim,double *pos);
void box2pos(simptr sim,boxptr bptr,double *pos);
boxptr line2nextbox(simptr sim,double *pt1,double *pt2,boxptr bptr);
int panelinbox(simptr sim,panelptr pnl,boxptr bptr);
int setupboxes(simptr sim);
int assignmolecs(simptr sim,int ll);
int reassignmolecs(simptr sim,int ll,int reborn);

// simulation structure
simptr simalloc(int dim,int nident,char *root);
void simfree(simptr sim);
int loadsimul(simptr *smptr,char *fileroot,char *filename,char *erstr);
int setupstructs(char *root,char *name,simptr *smptr,int vb);
void simoutput(simptr sim);
void checkparams(simptr sim);

#endif


