/* This file contains all of the initialization routines.

   06/19/94 AW  Created.
   06/19/94 AW  Reads values from parameters file.  
   06/20/94 AW  Initializes random seed and output files.
*/
#include <stdio.h>
#include <stdlib.h>
#include "types.h"

/* ----- prototype files ------------------------------------------------ */
#include "init.h"	/* prototypes file */
#include "output.h"

/* ----- constants ------------------------------------------------------ */
#define GUTSIZE 5  /*** This should be initialized in context later
                       and make it proportional to critter size ***/

/* ----- ifdef constants ------------------------------------------------ */
#define CONTEXT 1
#define PRINT_RANDOM 1

/***** initialize_context *****/
/* This allocates memory for the context structure and initializes */
/* its fields.

   Called by: main()
   Calls:
*/

Context *initialize_context(char *params_file)
{
Context *the_context;
FILE *fp;		/* file pointer to read params file */
FILE *fp2;		/* file pointer to run_num & random files */
char fieldname[100];	/* reads in name of structure field */
char runfile[100];	/* name of file where run_num is stored */
char filename[100];
long temp;

#ifdef DEBUG
   printf(" ---in init context---\n");
#endif
 
  /* allocate space for context structure */
   the_context = (Context *) malloc(sizeof(Context));

  /* set pointer to params file */
   fp = fopen(params_file, "r");
   if (fp == NULL)
      {
      printf(" Error(init_context): cannot open file: %s\n", params_file);
      return(NULL);
      }

  /* Generate the next run_num.  Each experiment is assigned a unique
     run_num.  This number is simply one more than the value in the
     run_num_file (run.num) specified in the parameters file (params.in).
     Even when we are rerunning an experiment, a new run_num will be
     generated -- the random seed is what is re-used.
  */
   fscanf(fp, "%s %s", runfile, fieldname);
#ifdef CONTEXT
   printf(" runfile = %s\n",  runfile);
#endif
   fp2 = fopen(runfile, "r");
   fscanf(fp2, "%d", &the_context->run_num);
   the_context->run_num++;
   fclose(fp2);
   fp2 = fopen(runfile, "w");
   fprintf(fp2, "%d\n", the_context->run_num);
   fclose(fp2);
#ifdef CONTEXT
   printf(" run_num = %d\n", the_context->run_num);
#endif

  /***** Read in the rest of the parameter values *****/
   fscanf(fp, "%d %s", &the_context->rerun, fieldname);
   fscanf(fp, "%s %s", &the_context->output_path, fieldname);
   fscanf(fp, "%d %s", &the_context->max_steps, fieldname);
   fscanf(fp, "%lf %s", &the_context->mutation_prob, fieldname);

#ifdef CONTEXT
   printf(" Parameter values read in:\n");
   printf("    output_path = %s\n", the_context->output_path);
   printf("    max_steps = %d\n", the_context->max_steps);
   printf("    mutation_prob = %lf\n", the_context->mutation_prob);
#endif

  /***** initialize the output file structure *****/
  output_file = init_output_files(the_context);
  if (output_file == NULL)
     {
     return;
     }
	
  /***** Generate random seed and print to file *****/
  /* Generate the random seed depending on the rerun
     parameter value.  If the value is -1, then generate
     a new random seed for this run.  If the value is >= 0, then
     this value specifies the run number of the experiment to rerun. 
  */
   fscanf(fp, "%d %s", &the_context->rerun, fieldname);
   if (the_context->rerun < 0)
      {
      the_context->seed = seed_random(the_context->rerun);
#ifdef PR_RANDOM
     /* print to .random file */
      fprintf(output_file[RANDOM_FILE].fp, " %ld", the_context->seed);
      fclose(output_file[RANDOM_FILE].fp);
#endif  /* PRINT_RANDOM */
      }  /* if generate new random seed */
   else
      {
     /* get old random seed by reading in from a file or something */
      sprintf(filename, "%srun.%d.random", the_context->output_path,
              the_context->rerun);
      fp2 = fopen(filename, "r");
      if (fp2 == NULL)
         {
         printf(" Error(ga_start): cannot open file: %s\n", filename);
         return NULL;
         }  /* if */
      fscanf(fp2, "%ld", &temp);
      the_context->seed = seed_random(temp);
      fclose(fp2);
#ifdef PRINT_RANDOM
     /* print to .random file */
      fprintf(output_file[RANDOM_FILE].fp, " %ld", the_context->seed);
      fclose(output_file[RANDOM_FILE].fp);
#endif  /* PRINT_RANDOM */
      }  /* get old random seed -- rerun an old run */
#ifdef CONTEXT
   printf(" Random seed = %ld\n", the_context->seed);
#endif

  /* close params file pointer */
   fclose(fp);

#ifdef DEBUG
   printf(" ---end init context---\n");
#endif
   return(the_context);
}
 
/***** init_random *****/
/* parameters:	the_context
		output_file
   called by:	main
   actions:	 Generate the random seed depending on the rerun
     parameter value.  If the value is -1, then generate
     a new random seed for this run.  If the value is >= 0, then
     this value specifies the run number of the experiment to rerun.
*/
void init_random(Context *the_context, Output_file *output_file)
   {
   }  /* init_random */

/***** initialize_population *****/
Population * initialize_population()
{
Population *the_population;

#ifdef DEBUG
  printf(" ---in init population---\n");
#endif

  the_population = (Population *) malloc(sizeof(Population));
  the_population->current_size = 0;
  the_population->environment = calloc(GUTSIZE, sizeof(Metabolite));

  /*** seed the population ***/
  /*** initialize the environment ***/
#ifdef DEBUG
  printf(" ---end init population---\n");
#endif

return(the_population);
}

/***** initialize_stats *****/
void initialize_stats(/*the stats object*/)
{
#ifdef DEBUG
  printf(" ---in init stats---\n");
#endif
#ifdef DEBUG
  printf(" ---end init stats---\n");
#endif
}

/***** init_output_files *****/
/* parameters:	the_context
   called by:	initialize_context()
   actions:	stores all output file information into an array
		of structures that it returns.  Info includes
		file name, pointer to file, whether the file is
		active, if the header should be printed.
*/
Output_file *init_output_files(Context *the_context)
   {
   int i;
   Output_file *output_file;

#ifdef DEBUG
   printf(" ---in init_output_files---\n");
#endif

   output_file = (Output_file *)calloc(NUM_OUTPUT_FILES,
                                       sizeof(Output_file));
   for (i=0; i<NUM_OUTPUT_FILES; i++)
      output_file[i].active = FALSE;

#ifdef  PR_PARAMS
   sprintf(output_file[PARAMS_FILE].filename,
           "%srun.%d." PARAMS_EXT,
           the_context->output_path,
           the_context->run_num);
   output_file[PARAMS_FILE].header = PARAMS_HEADER;
   output_file[PARAMS_FILE].active = TRUE;
   output_file[PARAMS_FILE].fp = 
           fopen(output_file[PARAMS_FILE].filename, "w");
#endif

#ifdef  PR_RANDOM
   sprintf(output_file[RANDOM_FILE].filename,
           "%sfun.%d." RANDOM_EXT,
           the_context->output_path,
           the_context->run_num);
   output_file[RANDOM_FILE].header = RANDOM_HEADER;
   output_file[RANDOM_FILE].active = TRUE;
   output_file[RANDOM_FILE].fp = 
           fopen(output_file[PARAMS_FILE].filename, "w");
#endif

   write_header(the_context, output_file);

#ifdef DEBUG
   printf(" ---end init_output_files---\n");
#endif
   return(output_file);
   }  /* init_output_files */
