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

/*  extern declarations  */
FILE *filelist = NULL,		/*  filelist ptr	*/
     *rflname = NULL;		/*  reflector (out)file	*/
char  cername[LINE_MAX_LENGTH];	/*  current cername	*/
long  first_Event = 0,		/*  first proc. event	*/
      last_Event = 1000000, 	/*  last proc. event	*/
      max_Events = 50000;	/*  max proc. events	*/
float low_Ecut = 0.0f,		/*  lower Ecut (GeV)	*/
      high_Ecut = 100000.0f;	/*  upper Ecut (GeV)	*/

int   is_Fixed_Target = FALSE;	/*  fixed target?	*/
float fixed_Theta,		/*  zenith angle (rad)	*/
      fixed_Phi;		/*  azi (0N->90E) (rad)	*/

int   is_Random_Pointing=FALSE;	/*  random pointing?	*/
float Random_Pointing_MaxDist;  /*  in metres		*/
int   nRepeat_Random = 1;	/*  nr of times a sh. is reused	*/

long  Seeds[2] = {3141592L, 2718182L}; 

/*  Other declarations  */
char whites[] = " \v\t\n\r";	/*  White chars def	*/
char line[LINE_MAX_LENGTH];	/*  parsing buffer	*/

/*  Prototypes  */
static void CheckSignature(char *line);
int ParseLine(FILE *parfile,		/*  FILE with parms	*/
	      const char *token_list[],	/*  array w/tokens	*/
	      int tokens,		/*  nr of tokens	*/
	      char **value_ptr);	/*  ptr to parm val.	*/

/*  Checks signature.
 *  It separates tokens and compare the first
 *  token with PROGRAM and the second with VERSION.
 *  Both values are stored in "version.h".
 *  Return value is set to true if check fails.  */

static void CheckSignature(char *line)
{   char *cp;				/*  To parse signature	*/

    if ((cp=strtok(line, whites)) == NULL || strcmp(cp, QUOTE(PROGRAM)) ||
	(cp=strtok(NULL, whites)) == NULL || strcmp(cp, QUOTE(VERSION)))
        FatalError(SIGN_ERROR_FTL, QUOTE(PROGRAM), QUOTE(VERSION));
}   /*  end of CheckSignature  */

int ParseLine(FILE *parfile,		/*  FILE with parms	*/
	      const char *token_list[],	/*  array w/tokens	*/
	      int tokens,		/*  nr of tokens	*/
	      char **value_ptr)		/*  ptr to parm val.	*/
{   int item = tokens;
    char *cp;

    do
    {	if (fgets(line, LINE_MAX_LENGTH, parfile) == NULL)
	    break;
	else if (line[0] == '#'); /*  skip comments (start with '#') */
	else if (line[0] == '>')  /*  show user comments (start with '>') */
	{   if ((cp=strchr(line, '\n')) != NULL) *cp = 0;
	    puts(line); }
	else if ((cp = strtok(line, whites)) != NULL)
	{   /*  check which param it is */ 
	    for (item=0; item<tokens; item++)
		if (strcmp(cp, token_list[item])==0)
		    break;
	    if (item < tokens)
		*value_ptr = strtok(NULL, whites);
	    else Message(SKIP_TOKEN_MSG, cp);	}}
    while (item >= tokens);

    return item;
}   /*  end of ParseLine  */

FILE *geofile = NULL;		/*  geometry file	*/

void init(char *filename)
{   FILE *parfile = NULL;	/*  parms file     */
    extern void ParmsSwitch(FILE *parfile);	/*  std parsing fn	*/
    extern void GeometrySwitch(FILE *geofile);	/*  geometry parsing fn	*/

    /*  Open file or read from stdin  */
    if (filename) parfile = fopen("filename", "r");
    if (parfile == NULL) parfile = stdin;
    fgets(line, LINE_MAX_LENGTH, parfile);

    /*  Check signature  */
    CheckSignature(line);

    ParmsSwitch(parfile);
    if (geofile) GeometrySwitch(geofile);
    else FatalError(GEOM_NSPEC_FTL);

    /*  Alloc memory for CPhotons  */
    if ((CPhotons =
	(cphoton *) malloc(NR_OF_CPHOTONS * sizeof(cphoton))) == NULL)
	 FatalError(CPHS_ALLOC_FTL, NR_OF_CPHOTONS);
    else Log(CPHS_ALLOC_LOG, NR_OF_CPHOTONS);

    /*  Write signature and START_OF_RUN at the beginning of rflfile  */
    /*  '\0' for backward compatibility  */
    fseek(rflfile, 0L, SEEK_SET);
    fprintf(rflfile, "%s %s", QUOTE(PROGRAM), QUOTE(VERSION));
    fputc(0, rflfile);
    fwrite(FLAG_START_OF_RUN, SIZE_OF_FLAGS, 1, rflfile);

    /*  "Splashscreen"  */
    Message(RFL__START_MSG, QUOTE(PROGRAM), QUOTE(VERSION));
}   /*  end of init  */
