#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "diag.h"
#include "parms.h"
#include "init.h"

extern char whites[];		/*  white chars (init)	*/
extern char line[];		/*  parsing buf. (init)	*/

char axisdev_filename[256], reflectivity_filename[256];
char geo_filename[256];

/*  Prototypes  */
extern void setall(long iseed1,long iseed2);	/* rnds */
static void ReadCerfiles(FILE *parfile);

static void ReadCerfiles(FILE *parfile)
{   char *value_ptr = NULL;	/*  ptr at parm value	*/
    extern FILE *GetNextFile(char *cername); /*  in main.c	*/

    filelist = parfile;
    parfile = NULL;
    if (fgets(line, LINE_MAX_LENGTH, filelist) == NULL ||
	(value_ptr=strtok(line, whites)) == NULL)
      FatalError(FLST_NSPEC_FTL); 
    else if (value_ptr[0] == '@')
      {	fclose(filelist);
	if ((filelist=fopen(value_ptr+1, "r")) == NULL)
	  FatalError(FLST_NFND__FTL, value_ptr+1);
	else if (fgets(line, LINE_MAX_LENGTH, filelist) == NULL)
	  FatalError(FLST_NSPEC_FTL); 
	value_ptr = strtok(line, whites);   }

    /*  Set cername and find out event number bounds  */
    strcpy(cername, value_ptr);
    if ((value_ptr=strtok(NULL, whites)) == NULL)
      {	first_Event = 0;
	last_Event  = 1000000;   }
    else
      {	first_Event = atol(value_ptr);
	value_ptr = strtok(NULL, whites);
	last_Event = value_ptr ? atol(value_ptr) : 1000000;  }

    /*  Try to open cerfile.  */

    if ((cerfile=fopen(cername, "r")) == NULL)
      {   Message(CERF_NFND__MSG, cername);
	  cerfile=GetNextFile(cername);  }

    /*  If no valid cerfile is found then exit  */
    if (cerfile == NULL)
      FatalError(CERF_NSPEC_FTL);

    /*  Check boundaries  */
    if (first_Event > last_Event)
      {	Error(EVTN_WRONG_ERR, first_Event, last_Event, cername);
	first_Event = 0;
	last_Event  = 1000000;  }

  } /*  end of ReadCerfiles  */

void ParmsSwitch(FILE *parfile)
{   char *value_ptr = NULL;	/*  ptr at parm value	*/
    int   switch_end = FALSE;	/*  bool to exit loop	*/
    extern FILE *geofile;	/*  geo file (init)	*/
    extern void SetVerbose(int vlevel);	/*  from diag.c	*/
    extern void SetAtmModel(char *model); /*  from atm.c	*/
    extern int ParseLine(FILE *parfile,	/*  FILE with parms	*/
			 const char *token_list[], /*  array w/tokens	*/
			 int tokens, /*  nr of tokens	*/
			 char **value_ptr); /*  ptr->parm val.	*/

    do  
      {	switch(ParseLine(parfile, parms, ARRAY_SZ(parms), &value_ptr))
	  {   case output_file:
		if ((rflfile=fopen(value_ptr, "w+")) == NULL)
		  FatalError(OUTF_ERROR_FTL, value_ptr);
		Message(OUTF_OPEN__MSG, value_ptr);
		break;
	      case ct_file:
		if ((geofile=fopen(value_ptr, "r")) == NULL)
		  FatalError(GEOF_ERROR_FTL, value_ptr);
		else
		  strcpy(geo_filename, value_ptr); 
		Message(GEOF_OPEN__MSG, value_ptr);
		break;
	      case axisdev_file:
		strcpy(axisdev_filename, value_ptr);
		break;
	      case reflectivity_file:
		strcpy(reflectivity_filename, value_ptr);
		break;
	      case atm_model:
		SetAtmModel(value_ptr);
		break;
	      case verbose_level:
		SetVerbose(atoi(value_ptr));
		break;
	      case fixed_target:
		is_Fixed_Target = TRUE;
		fixed_Theta = (float) atof(value_ptr);
		value_ptr = strtok(NULL, whites);
		if (value_ptr == NULL)
		  {   Error(FIXD_TARGT_ERR);
		      is_Fixed_Target = FALSE; }
		else
		  {   fixed_Phi = (float) atof(value_ptr);
		      Message(FIXD_ENABL_MSG, fixed_Theta, fixed_Phi);
		      fixed_Theta *= (float) (M_PI/180.);
		      fixed_Phi   *= (float) (M_PI/180.); }
		break;

		/* Added May 2002, AM: */
	      case telescope_position:
		Telescope_x = (float) atof(value_ptr);
		value_ptr = strtok(NULL, whites);
		if (value_ptr == NULL)
		  {   Error(TEL_POS_ERR);
		      exit(-1);}
		else
		  {   Telescope_y = (float) atof(value_ptr);
		      Message(TEL_POS_MSG, Telescope_x, Telescope_y);}
		break;

	      case max_events:
		Message(MAX__EVTS__MSG, max_Events=atol(value_ptr));
		break;

		/* AM, Nov 2002, added wobble option: */
	      case wobble_mode:
		wobble_position = (int) atoi(value_ptr);
		if ( (wobble_position > 1 || wobble_position < -1) &&
		    wobble_position != 3)
		  {
		    Message(WOBBLE_POS_ERR);
		    exit(-1);
		  }
		else
		  {
		    Message(WOBBLE_POS_MSG, wobble_position);
		    break;
		  }
	      case energy_cuts:
		low_Ecut = (float) atof(value_ptr);
		value_ptr = strtok(NULL, whites);
		if (value_ptr == NULL)
		  {   Error(ENRG_LIMIT_ERR);
		      low_Ecut = 0.; }
		else
		  {   high_Ecut = (float) atof(value_ptr);
		      Message(ENRG_CUTS__MSG, low_Ecut, high_Ecut); }
		break;
	      case seeds:
		Seeds[0] = atol(value_ptr);
		value_ptr = strtok(NULL, whites);
		if (value_ptr) Seeds[1] = atol(value_ptr);
		else
		  {   Error(SEED_ERROR_ERR);
		      Seeds[0] = 3141592L; }
		break;
	      case cer_files:
		ReadCerfiles(parfile);
		switch_end = TRUE;
	      default: switch_end = TRUE;
		break;  }}
    while (!switch_end);

    if (filelist == NULL)
      FatalError(FLST_NSPEC_FTL);

    /*  Set random seeds  */
    setall(Seeds[0], Seeds[1]);
    Message(SEED_SET___MSG, Seeds[0], Seeds[1]);

  } /*  end of ParmsSwitch  */
