/* File containing description of types, typedefs, and structures
   used in the program.

   06/17/94 AW  Created.
*/

/* To monitor the progress of the program, define DEBUG.  This
   prints a message each time the program enters and leaves a
   subroutine.
*/
#define DEBUG	0
#undef DEBUG

#define ERROR	0
#define OK	1

/***** output files *****/

#define	NUM_OUTPUT_FILES	4

#define PR_PARAMS	1
#ifdef 	PR_PARAMS
#define PARAMS_FILE	0
#define	PARAMS_EXT	"params"
#define PARAMS_HEADER	TRUE
#endif

#define PR_RANDOM	1
#ifdef  PR_RANDOM
#define RANDOM_FILE     1
#define RANDOM_EXT      "random"
#define RANDOM_HEADER   FALSE
#endif

#define PR_STATS	1
#ifdef  PR_STATS
#define STATS_FILE	2
#define STATS_EXT	"stats"
#define STATS_HEADER	TRUE
#endif

#define PR_GENEOLOGY	1
#ifdef  PR_GENEOLOGY
#define GENE_FILE	3
#define GENE_EXT	"geneology"
#define GENE_HEADER	FALSE
#endif

/***** constants *****/
#define NUM_METABOLITES 10

/***** typedefs *****/
/*  All of our types begin with a capital letter */

typedef enum {FALSE, TRUE} Boolean;  /* FALSE=0, TRUE=1 */
typedef unsigned int	Metabolite;
typedef int 		Genetype;
typedef Genetype 	*Chromosome;  /*An array of Genetypes.*/
typedef int	 	Gut;         /*An array of # of metabolites.*/

typedef enum {BREAKDOWN, CREATION} Reaction_class;


/***** structures *****/

/* the Reaction structure stores an efficient representation of one */
/* reaction in a critter's metabolism.  The entire metabolism of a */
/* critter will be a linked list of these Reaction structures.  I'm */
/* leaving the details of this to James ***/

struct reaction_struct
{
  struct reaction_struct *next_reaction; /*the next reaction in the */
					 /*linked list.*/
  Reaction_class reaction_type; /*creation or breakdown*/
  int first_reactant;
  int second_reactant; 
};

typedef struct reaction_struct Reaction;


/* An interaction_list structure stores the number of parasitisms 
   from members of the species para_species on members of the 
   species host_species.  Each structure is a member of two separate 
   linked lists.  One is a list of the current host species of para_species,
   and is accessed by following the next_host pointer.  The other is a 
   list of species which are currently parasites on host_species; this 
   is accessed by following the next_para pointer. */
struct interaction_list {
  /* The following two pointers specify the host and parasite species.
     No memory is allocated for these when the node is created.  They 
     just point to the appropriate species_list structs, defined below. */
  struct species_list *host_species;  
  struct species_list *para_species;  

  int num_interactions;    /* How many critters from para_species are 
			      parasites on critters from host_species  */

  struct interaction_list *next_host;   /* next host of para_species */
  struct interaction_list *prev_host;   /* prev host of para_species */
  struct interaction_list *next_para;   /* next para of host_species */
  struct interaction_list *prev_para;   /* prev para of host_species */
} ;

typedef struct interaction_list Interaction_node;

/* The species_list structure stores the metabolism of a gvien species
   (which is how the species is identified), a list of the 
   species which are currently parasitizing it (para_species), and a 
   list of the species which it is currently a parasite on (host_species).  
   The set of current species is represented by a linked list these
   structures. */
struct species_list {
  Reaction *species;  /* A species is identified by it's metabolism. */
  int num_critters;   /* number of critters alive in this species. */

  struct species_list *next_species;
  struct species_list *prev_species;
  Interaction_node *host_species;     /* list of hosting species */
  Interaction_node *para_species;     /* list of parasitizing species */
} ;

typedef struct species_list Species_list;  

/* the Critter structure stores all info on a single agent */
struct critter_struct
   {
  /* Critter ID info */
   int id_num;		/* id number specific to critter */
   int parent_id;	/* the id_num of the parent, 0 = orig gen */
   struct critter_struct  *p_next;	/* ptr to next critter in population */
   struct critter_struct  *p_prev;	/* ptr to previous critter in */
					/* the population. */ 

  /* genetic material */
   Chromosome hide;	
   Chromosome seek;
   Chromosome metabolism;
   int hide_len;	/* length of the above chromosomes */
   int seek_len;
   int meta_len;

  /* metabolism stuff */
   Reaction *fast_metabolism; /*A more efficient representation of the */
			  /*matabolism as an array of numbers, rather */
			  /*than bits. (goes here)*/
   Reaction *next_reaction; /*This points to the next reaction in the */
			    /*metabolism that the critter will execute.*/
   Species_list *species;   /* Pointer into the species list. */
   Gut gut[NUM_METABOLITES];	/* list of stored metabolites */
   int amt_food;	/* how many metabolites are currently in gut */
	/* how do we add and delete metabolites? 
           Probably don't want linked list */
	/* instead of a list of metabolites, could have a list of
	   how many of each metabolite there are -- but then we
	   would have to specify all possible metabolites before
	   the run starts. */
   struct critter_struct *mouth;  /* if parasite, hosts stomach; ow, NULL */
   struct critter_struct *prev_metabolizer;
   struct critter_struct *next_metabolizer; /*These set up a doubly */
					    /*linked list of critters */
					    /*for iterating the */
					    /*metabolisms.*/ 
   

  /* Critter's current state */
   int energy;		/* energy level of parasite */
   int age;		/* age in timesteps */
   int para_age;	/* # timesteps critter has been a parasite */
   int num_offspring;	/* # of offspring sired */
   int num_times_host;	/* # times critter has hosted parasites */
   int num_times_para;	/* # times critter has been a parasite */
   int num_curr_para;	/* # parasites currently being hosted */
   };

typedef struct critter_struct Critter;


/* the Population structure stores info on the population and
   a pointer to the linked list of Critters in the population.
   It now also stores the population's environment.
*/
typedef struct
   {
   int current_size;	/* # Critters in population */
   Gut environment[NUM_METABOLITES]; 
                        /* An array of resouceses (Metabolites) in the */
			/* environment.*/ 
   Critter *metabolizer; /* pointer to the next critter to metabolize.*/
   Critter *critters;    /* pointer to population of individuals, */
			 /* which will be a doubly linked list. */
   int num_species;      /* number of species in current population. */
   Species_list *species_list;  /* a list of all current species. */
   }  Population;

/* the Context structure stores parameter information and
   current global run variables for the program */
typedef struct
   {
  /* general run information */
   int run_num;		/* id num for current run */
   int rerun;		/* -1 = don't rerun, >0 = run num */
   long seed;		/* random seed, necessary for reruns */
   char output_path[100]; /* where output files should be printed */

   int time_step;	/* current timestep */
   int critter_num;	/* id num of last critter */

  /* limits and standard values for run */
   int max_steps;	/* max # timesteps to execute */
   double mutation_prob;  /* mutation rate */
   
   }  Context;

/* the Output_file structure holds name, pointer, and other
   information on all output files that the user chooses to
   have printed out.  The user chooses the files by defining
   or undefining PR_constants in this file.  Those files that
   are not to be printed will still have a structure in the
   output_file array, but the pointer and name will be undefined.
*/
typedef struct
   {
   Boolean active;	/* t=file will be printed, f=ignore file */
   Boolean header;	/* t=print header, f=don't print header */
   char filename[100];  /* file name max length = 100 chars */
   FILE *fp;		/* pointer to file */
   }  Output_file;

  

/* the Stats structure collects statistical and other data
   from each run for printout into files if desired */
typedef struct
   {
   int num_critters;
   int num_hosts;
   int num_parasites;
   int num_species;
   double avg_num_para_per_host;
   double avg_num_offspring;
   double avg_age;
   double avg_energy;
   double avg_size;	/* length of genome */
   }  Stats;

/***** global variables *****/
Context *the_context;
Population *the_population;
Stats *stats;
Output_file *output_file;
