#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include<string.h>
#include <mikenet/simulator.h>

#include "simconfig.h"
#include "model.h"

#define REP 500

int seed=0;

FILE *finfo=NULL;

#define READING_ITERS 1000001

int start=1;

void get_name(char *tag, char *name)
{
  char *p;
  p=strstr(tag,"Word:");
  p+= 5;
  p=strtok(p," \t\n");
  strcpy(name,p);
}

int train()
{
  Example *ex;
  int i;
  Real dice,e;
  Real err=0.0,hear_err=0.0;
  Real gmag=0,hmag=0,omag=0,wmag;
  char fn[255];
  int save=1,count=1;
  int readcount=0;
  int hearcount=0;
  int saveCount= 50000;
  char wordname[255];
    

  for(i=start;i<=start+READING_ITERS;i++)
    {
      dice=mikenet_random();
      dice = 1.0;
      hearcount=1;
	  ex=get_random_example(reading_examples);
	  get_name(ex->name,wordname);
	  crbp_forward(reading,ex);
          crbp_compute_gradients(reading,ex);
          crbp_update_taos(reading);
	  crbp_apply_deltas(reading);
	  readcount++;
	  e=compute_error(reading,ex);
	  err += e;
	  fprintf(finfo,"%d %s \n",i,wordname);

      if (count==REP)
	{
	  fflush(finfo);
	  printf("read %d\t%f\t%f\n",i,
		 hear_err/(float)hearcount,
		 err/(float)readcount);
	  err=0.0;
	  hear_err=0.0;
	  hearcount=0;
	  readcount=0;
	  count=1;
	}
      else count++;
      
      if (count < 100000){
	saveCount = 10000;
	  }
      else{
	saveCount = 50000;
      }

      if (save==saveCount)
	{
	  sprintf(fn,"s%d_%d_weights",seed,i);
	  save_weights(reading,fn);
	  save=1;
	}
      else save++;
    }
  printf("readcount %d\n",readcount);
}

int main(int argc,char *argv[])
{
  int i;
  char loadWeights[255];
  char fn[255];
  char infoFile[255];
  char patFile[255];
  float epsilon=0.01;
  setbuf(stdout,NULL);

  loadWeights[0]=0;
  patFile[0]=0;
  infoFile[0]=0;
  announce_version();

  for(i=1;i<argc;i++)
    {
      printf("arg %s\n",argv[i]);
      if (strcmp(argv[i],"-seed")==0)
	{
	  seed=atoi(argv[i+1]);
	  i++;
	}
      else if (strcmp(argv[i],"-info")==0)
	{
	  strcpy(infoFile,argv[i+1]);
	  i++;
	}
      else if (strcmp(argv[i],"-pat")==0)
	{
	  strcpy(patFile,argv[i+1]);
	  i++;
	}
      else if (strcmp(argv[i],"-load")==0)
	{
	  strcpy(loadWeights,argv[i+1]);
	  i++;
	}
      else if (strcmp(argv[i],"-epsilon")==0)
	{
	  epsilon=atof(argv[i+1]);
	  i++;
	}
      else if (strcmp(argv[i],"-start")==0)
	{
	  start=atoi(argv[i+1]);
	  i++;
	}
      else
	{
	  fprintf(stderr,"unknown option: %s\n",argv[i]);
	  exit(-1);
	}
    }
  if (infoFile[0]==0)
    Error0("Need to specify info file with -info option");
  
  finfo=fopen(infoFile,"a");
  default_epsilon=epsilon;
  if (patFile[0]==0)
    Error0("Need to specify training file with -pat option");
  
  printf("seed %d\tpid %d epsilon %f\n",seed,getpid(),epsilon);
  system("date");
  system("hostname");
  mikenet_set_seed(seed);
  /* build a network, with SAMPLES number of time ticks */
  build_model();
  printf("start %d\n",start); 
  if (start==1)
    {
      sprintf(fn,"s%d_init_weights",seed);
      save_weights(reading,fn);
    }
  else 
    {
      load_weights(reading,loadWeights);
      printf("loaded weight file %s\n",loadWeights);
    }
  /* load in our example set */
  fprintf(stderr,"loading training file  %s\n",patFile);
  reading_examples=load_examples(patFile,SAMPLES);
  fprintf(stderr,"done\n");

  /*  train_prewire(); */
  train();
  sprintf(fn,"s%d_final_weights",seed);
  save_weights(reading,fn);
  printf("finished\n");
  fclose(finfo);
  system("date");
  return 0;
}


