#include "raw_proto.h"
#include "psplot.h"

/* main *****************************************************************
* INPUT:    argc    count of inputs on command line                     *
*           argv    array of input strings the name of file with        *
*                   the processing parameters should be specified.      *
*                   mumparms is the original file.  The 'u' specifies   *
*                   that a filename is provided at the end of the file  *
*                   defining the data file/tape from which to read data *
* PURPOSE:                                                              *
* This program is used to do preliminary processing of Arecibo POWRD    *
* and POWRE record types, MRACF records are used to determine ending    *
* time stamps where appropriate                                         * 
* ORIGIN:                                                               *
* based on code supplied by Wes Swartz and Clark Miller                 *
* CHANGES:                                                              *
* 96/11/12  Used for looking at AO header info                          *
************************************************************************/
void main(int argc, char **argv)
{
  AOInputParms ip;                  /* input parameters structure           */
  int frp;                          /* input tape/file                      */
  DateTime startdt, stopdt;         /* start and stop processing times      */
  DateTime currdt;
  long int start, stop, curr;       /* start,stop,curr times in seconds     */
  RawAOHeader ah;                   /* Current raw data header              */
  char *buf;                        /* raw data input buffer                */
  char *data;                       /* pointer to beginning of data in buf  */
  char *pdata;                      /* pointer to proc data buffer          */
  float *pden,*sden;                /* float array of data values           */
  long int rec_read, rec_written;   /* records read and records written     */
  long int i,j;                     /* Generic counters                     */
  float *avar;                      /* Generic test array for floats        */
  float fmax_val;                   /* Max value variable                   */
  float noise_val;                  /* noise level                          */
  int *iGray;                       /* grayscale array                      */
  char *ttxt;                       /* temporary text buffer for sprintf    */
  float rtd;                        /* radians to degrees conversion factor */
  AOProcHeader *ph;                 /* Processed data header                */
  int fwp;                          /* write file pointer                   */
  int fcd = 0;                      /* created file ?                       */
  char wfile[30];                   /* output file aodat[mode].[dmy].[hmst] */
  
  /* allocation of memory */
  buf = (char *) malloc(MAX_CUPRI_BYTES*sizeof(char));
  pdata = (char *) malloc(MAX_CUPRI_BYTES*sizeof(float));
  avar = (float *) malloc(MAX_CUPRI_BYTES*sizeof(float));
  pden = (float *) malloc(MAX_CUPRI_BYTES*sizeof(float));
  iGray = (int *) malloc(10*sizeof(int));
  ttxt = (char *) malloc(120*sizeof(char));
  
  /* initializing variables */
  rtd = 57.295779214;
  data = &buf[CUPRI_VOS_HEADER_SIZE];
  ph = (AOProcHeader *) pdata;
  sden = (float *) (pdata + sizeof(AOProcHeader));
  for(i=0;i<10;i++)
  {
    /* set up gray scale */
    iGray[i] = 90 - i * 10;
  }
  
#ifdef THINK_C
  /* the following call is needed for the Mac to provide an I/O window to input
   * parameters that would normally be entered on the command line in
   * other systems.
   */
  
  argc = ccommand(&argv);
#endif /* THINK_C */
  
  ip = get_ao_input_parms(argv[1]);
  
#ifdef DEBUG_MAIN
  printf("rawao_main: main: start: %s\nstop: %s\nmode: %ld\nraw file: %s\n",
	 ip.start_str,ip.end_str,ip.pm,ip.file);
#endif /* DEBUG_MAIN */
  
  if((frp = open(ip.file,O_RDONLY)) == -1)
    printf_exit("rawao_main: main: can't open read file\n",(long int)ip.file);
  
  /* convert input times */
  startdt = get_input_time(ip.start_str);
  stopdt = get_input_time(ip.end_str);
  
  /* convert start and stop times to seconds to use in search
   * and processing loops.
   */
  
  start = seconds(&startdt);
  stop = seconds(&stopdt);
  
#ifdef DEBUG_MAIN
  printf("start %ld stop %ld\n",start,stop);
#endif /* DEBUG_MAIN */
  
  /* loop through raw records until arrive at start time */
  printf("rawao_main: main: Finding start location.\n");
  curr = 0;
  
  while(curr<start)
  {
    static long int last_dift = 0;
    long int eofloops = 0;
    long int li_dift;
    
    /* get current time from raw record */
    ah = get_rawao_record(frp,buf,data);
    while(ah.h.nwords2 == -1 && eofloops < 6)
    {
      if(eofloops == 5)
	printf_exit("rawao_main: main: Record Read Error, EOF detected\n",0);
      
      eofloops++;
      printf("Attempting to reread after encountering tape error\n");
      ah = get_rawao_record(frp,buf,data);
    }
    currdt = decode_ao_time(ah.hdr);
    curr = seconds(&currdt);
    
    li_dift = start - curr;
    if(!(li_dift%100) && li_dift != last_dift)
    {
      printf("%ld seconds remaining.\n",li_dift);
      last_dift = li_dift;
    }
  }

  rec_read = rec_written = 0;
  while(curr<stop)
  {
    long int d_cnt;      /* float data count read                       */
    if(rec_read)         /* dont read first record since we already did */
    {
      ah = get_rawao_record(frp,buf,data);
      if(ah.h.nwords2 == -1)
	printf_exit("rawao_main: main: Record Read Error, EOF detected\n",0);
      currdt = decode_ao_time(ah.hdr);
      curr = seconds(&currdt);
    }
    
    /* depending upon processing mode, skip undesired records */
    switch(ip.pm)
    {
    case 1: /* powrd & powre raw plot */
    case 5: /* powrd & powre range plot */
    case 6: /* powrd & powre write to file */
      if(!((ah.h.progname[4] == 'D') || (ah.h.progname[4] == 'E')))
      {
	continue;
      }
      printf("POWRD or POWRE record encountered.\n");
      break;
      
    case 2: /* powrd only */
      if(ah.h.progname[4] != 'D')
      {
	continue;
      }
      printf("POWRD record encountered.\n");
      break;
      
    case 3: /* powre only */
      if(ah.h.progname[4] != 'E')
      {
	continue;
      }
      printf("POWRE record encountered.\n");
      break;
      
    case 4: /* mracf only */
      if(ah.h.progname[4] != 'F')
      {
	continue;
      }
      printf("MRACF record encountered.\n");
      break;
      
    default: /* just break out */
      printf_exit("rawao_main:main: Error in processing mode",0);
    }
    
    /* convert data buffer to floats in range series */
    d_cnt = convert_ao_data(data,&ah.h,pden);
    
    ah.h.n_sig_smp = ah.h.si1/ah.h.gatewidth;
    ah.h.n_nx_smp = ah.h.si2/ah.h.gatewidth;
    ah.h.n_tx_smp = (ah.h.nwords2 - 112)/2 - ah.h.n_sig_smp - ah.h.n_nx_smp;
    ah.h.ngates = ah.h.n_tx_smp + ah.h.n_sig_smp + ah.h.n_nx_smp;
    
    printf("tx: %5ld sig: %5ld nx %5ld\n",
	   ah.h.n_tx_smp,ah.h.n_sig_smp,ah.h.n_nx_smp);
    
    if(ip.pm == 1)
    {
      fmax_val = 0;
      
      for(i=0;i<d_cnt;i++)
      {
	avar[i] = i;
	if(i >= ah.h.n_tx_smp && pden[i] > fmax_val) fmax_val = pden[i];
      }
      
      PSSetBoundingBox(.25,.25,7.25,10.25,1);
      PSNewPlot(1);
      PSGraphInit();
      PSGrayPatMap(iGray, 10);
      PSSetColorMode(0);
      
      PSAddFont("label","Times","Roman",14);
      PSAddFont("title","Times","BoldItalic",-20);
      PSAddFont("range","Times","Roman",-16);
      
      PSSetTicLen(.06);
      
      PSSetOrigin(1.1,1.1,0.);
      
      PSLinearAxis("L",0,ah.h.ngates,6.,8.0,10,0.,100,10);
      PSLabelAxis("L", "%4.0f", "label",-1, 0., 200);
      sprintf(ttxt,"Data Bin Number (%ld max)",ah.h.ngates);
      PSTitle("L",ttxt,"range",-1);
      
      PSLinearAxis("R",0,ah.h.ngates,6.,8.0,10,0.,100,10);
      
      PSLinearAxis("B",0,1.0,6.,8.0,10,0.,.1,10);
      PSLabelAxis("B", "%3.1f", "label",-1, 0., .2);
      sprintf(ttxt,"Signal plus Noise (%2.1e max)",fmax_val);
      PSTitle("B",ttxt,"range",-1);
      
      PSLinearAxis("T",0,1.0,6.,8.0,10,0.,.1,10);
      sprintf(ttxt,"Date:%ld/%02ld/%02ld Time:%02ld:%02ld:%02ld.%ld",
	      currdt.yr,currdt.mon,currdt.mday,
	      currdt.hr,currdt.min,currdt.sec,currdt.tsec);
      PSTitle("T",ttxt,"title",-1);
      sprintf(ttxt,"%s %s",ah.h.ident1,ah.h.progname);
      PSTitle("T",ttxt,"title",-1);
      
      PSSetClip("B,L",0,1.0,0,ah.h.ngates);
      
      for(i=0;i<d_cnt;i++)
      {
	pden[i] /= fmax_val;
      }
      PSPlotLine("B,L",pden,avar,d_cnt,10,0,-1);
      
      PSClosePlot();
    }
    
    if(ip.pm == 5)
    {
      fmax_val = 0;
      noise_val = 5e+20; /* random huge number */
      
      for(i=0;i<d_cnt;i++)
      {
	avar[i] = 0.15 * (ah.h.sd1 + ah.h.gatewidth * (i-1))
	  * cos(ah.h.start_zen/rtd);
	if(i >= ah.h.n_tx_smp && pden[i] > fmax_val)
	  fmax_val = pden[i];
	if(i >= ah.h.n_tx_smp + ah.h.n_sig_smp && pden[i] < noise_val)
	  noise_val = pden[i];
      }
      
      PSSetBoundingBox(.25,.25,7.25,10.25,1);
      PSNewPlot(1);
      PSGraphInit();
      PSGrayPatMap(iGray, 10);
      PSSetColorMode(0);
      
      PSAddFont("label","Times","Roman",14);
      PSAddFont("title","Times","BoldItalic",-20);
      PSAddFont("range","Times","Roman",-16);
      
      PSSetTicLen(.06);
      
      PSSetOrigin(1.1,1.1,0.);
      
      PSLinearAxis("L",avar[0],avar[ah.h.n_sig_smp-1],6.,8.0,10,0.,50,10);
      PSLabelAxis("L", "%4.0f", "label",-1, 0., 100);
      sprintf(ttxt,"Altitude (km, %.2f - %.2f)",avar[0],avar[ah.h.n_sig_smp-1]);
      PSTitle("L",ttxt,"range",-1);
      
      PSLinearAxis("R",avar[0],avar[ah.h.n_sig_smp-1],6.,8.0,10,0.,50,10);
      
      PSLinearAxis("B",0,1.0,6.,8.0,10,0.,.1,10);
      PSLabelAxis("B", "%3.1f", "label",-1, 0., .2);
      sprintf(ttxt,"Signal (%.1e max)",fmax_val);
      PSTitle("B",ttxt,"range",-1);
      
      PSLinearAxis("T",0,1.0,6.,8.0,10,0.,.1,10);
      sprintf(ttxt,"Date:%ld/%02ld/%02ld Time:%02ld:%02ld:%02ld.%ld",
	      currdt.yr,currdt.mon,currdt.mday,
	      currdt.hr,currdt.min,currdt.sec,currdt.tsec);
      PSTitle("T",ttxt,"title",-1);
      sprintf(ttxt,"%s %s",ah.h.ident1,ah.h.progname);
      PSTitle("T",ttxt,"title",-1);
      
      PSSetClip("B,L",0,1.0,avar[0],avar[ah.h.n_sig_smp-1]);
      
      for(i=ah.h.n_tx_smp;i<d_cnt-ah.h.n_nx_smp;i++)
      {
	pden[i] = (pden[i] - noise_val) * avar[i-ah.h.n_tx_smp]
	  * avar[i-ah.h.n_tx_smp];
	if(fmax_val < pden[i]) fmax_val = pden[i];
      }
      
      for(i=ah.h.n_tx_smp;i<d_cnt-ah.h.n_nx_smp;i++)
      {
	pden[i] /= fmax_val;
      }
      PSPlotLine("B,L",&pden[ah.h.n_tx_smp],avar,ah.h.n_sig_smp,10,0,-1);
      
      PSClosePlot();
    }
    
    /* dont bother writing record out if date is not properly defined. */
    if(ip.pm == 6 && ah.h.harris_date_time[0])
    {
      if(!fcd)
      {
	sprintf(wfile,"aodat1.%04ld.%06ld",
		ah.h.harris_date_time[0],ah.h.harris_date_time[1]);
	
#ifdef THINK_C
	if ((fwp = creat(wfile,O_BINARY)) == EOF)
#else /* must be MIPS */
	  if ((fwp = creat(wfile,PERMS)) == -1)
#endif /* THINK_C */
	    printf_exit("main: main: Unable to open output file\n",0);
	
	fcd = 1;
      }
      
      noise_val = 5e+20; /* random huge number */
      
      for(i=ah.h.n_tx_smp + ah.h.n_sig_smp;i<d_cnt;i++)
      {
	if(pden[i] < noise_val) noise_val = pden[i];
      }
      
      d_cnt -= ah.h.n_nx_smp;
      j=0;
      for(i=ah.h.n_tx_smp;i<d_cnt;i++,j++)
      {
	sden[j] = pden[i];
      }
      
      fix_procAOHdr(&ah, ph, rec_written, noise_val,1);
      dump_ao_moments(pdata, fwp);
      rec_written++;
    }
    
    rec_read++;
  }
}
