/*---------------------------------------------------------------------

  PWS16MAIN written by L. Granroth  08-24-88
			last modified by Bob Baines 11-17-90

  Versions - Two versions of program (now combined into one program)

   Client:
         to utilize DECnet-DOS Transparent Task-to-Task (TTT) capabilities
         and function as a "PWS16" client which displays Voyager PWS data
         requested from the PWS16_SERVER at IOWASP::.

   Processor Client:
         to process Voyager PWS data files directly.


  * IN DEVELOPMENT *

  08-26-88 converted to "Unix-like" i/o (necessary for TTT)  -ljg
  09-11-88 converted server and client to exchange 2-byte integers
           instead of "VAX R*2"  -ljg
  10-14-88 Client now requests device-specific number of time bins.
           Graphics routines in separate module.  -ljg
  07-26-89 Snapshot Feature Installed. Peaks and Averages data plotted.
           Functions in several separate modules.  External text file
           containing help added (keep with executable). -bb
  11-01-90 Change from client only program to one full version that
		   includes client version and a complete version (PC requires only
		   data files).  Uses config file to set various defaults.
		   Complete version reads in normal data files or compressed
		   data files (set-up in config file).  Uses colors for plotting
		   normal plots (scaling mode still uses only b/w shades).
		   Uses external BGI driver.

  ---------------------------------------------------------------------*/


#define MAIN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "pwstruct.h"
#include "proto.h"
#include "pwsglobl.h"


/* Global Vars shared with PWS16FNC module*/
 kmd_type *kmd;
 boolean setchan;
 boolean more;
 boolean Snapshot = FALSE;
 char *tp[MAXTOK];                  /* token pointer */
 int   ki[MAXTOK];                  /* keyword idx */
 int idx;

/* Internal Function Prototypes (functions specific only to this module) */
 void init(void);
 void process_params(int, char**);
 void snap_prep(void);
 int  pws16_control (void);           /* user interface and control routine */
 void pws16_help (void);              /* Display Help Menu */
 void cleanup(void);

/* Internal Global Vars */
 char output_dev[9] = "UNKNOWN";
 char node_loc[LLEN] = "\\\\t\\IOWASP\\PWSERVER\\PASSWORD\\\\#133";


void main (int argc, char *argv[])   /* PWS16MAIN */
{

 /* init vars, read config file, etc..... */
   define_commands();
   init();
   process_params(argc, argv);

 /* open communication - file pointer dependent on type of communication */
   pws16_begin();

 /* LOOP - process each command until done */
   while (pws16_control())  {

      /* request data and if goes okay get data and plot channel by channel */
      if (pws16_command()) {
	 label();
	 while (pws16_data())
	    plot();
      }
      else printf ("No data found for interval beginning: %2i %03i %02i%02i\n",
                    Cmd.year,Cmd.day,Cmd.hour,Cmd.minute);
   }

 /* close communication */
   pws16_end();

 /* do any cleaning up as is neccesary */
   cleanup();

}                        /* PWS16PC - PWS16 client */





/*---------------------------------------------------------------------

  INIT written by R. Baines 6/90.
  to handle various settings required for customizing the setup
  of combined version of program.  Also allows aliases, setting of
  screen colors and external bgi declarations.

  ---------------------------------------------------------------------*/

void init(void)
{
   FILE *fp;
   char line[LLEN], *command, *parameter, *p1, *p2;
   int i;

 /* create arrays dynamically because it static would make executable BIG */
   for (i=0; i<NUM_CHAN; i++) {
	  if(!(iavg[i] = (int *) calloc(900, sizeof(int)))) error(7);
	  if(!(ipks[i] = (int *) calloc(900, sizeof(int)))) error(7);
   }

 /* Fill Up Data_Paths with null strings */
   Data_Path[V1][0] = '\0';
   Data_Path[V2][0] = '\0';

 /* Set default values for Extentsion and input type. */   
   strcpy(Extension, "dat");
   strcpy(ZExtension, "daz");
   findinput("SERVER");


 /* PREPARE to READ CONFIG FILE ...*/


 /* open file, if unable to use built in settings */
   if (!(fp = fopen("pws16pc.cfg", "r+t")))
      return;

 /* process config file line by line -- see config file for example */
   while (fgets(line, LLEN, fp))
   {
	  if ((line[0] == ';') || (line[0]=='\n'))
		 continue;

      command = strtok(line, "=");
      strupr(command);
      parameter = strtok(0, ".");

      if (strcmp(command, "NODE_LOC")==0)

         strcpy(node_loc, parameter);

	   else if (strcmp(command, "OUTPUT_DEV") == 0)

		  strcpy(output_dev, parameter);

		else if (strcmp(command, "CAL_PATH") == 0)

		   strcpy(Cal_Path, parameter);

		 else if (strcmp(command, "V1DATA_PATH") == 0)

			strcpy(Data_Path[V1], parameter);

		  else if (strcmp(command, "V2DATA_PATH") == 0)

			 strcpy(Data_Path[V2], parameter);

		   else if (strcmp(command, "BGI_PATH") == 0)

			  strcpy(BGI_Path, parameter);

			 else if (strcmp(command, "INPUT") == 0)

				findinput(parameter);

			  else if (strcmp(command, "COLOR") == 0) {

				 Lcolor = atoi(strtok(parameter, ","));
				 Acolor = atoi(strtok(0, ","));
				 Pcolor = atoi(strtok(0, ","));
				 Gcolor = atoi(strtok(0, ","));
				 Bcolor = atoi(strtok(0, ","));
				 ColorsSet = TRUE;
				 }

			   else if (strcmp(command, "ALIAS")==0) {

				  p1 = parameter;
				  p2 = strchr(p1, ',');
				  *p2 = '\0';
				  kmdadd(p1, ++p2);
				  }

				else if (strcmp(command, "EXT")==0)

				   strcpy(Extension, parameter);

				 else if (strcmp(command, "ZEXT")==0)

					strcpy(ZExtension, parameter);

				  else if (strcmp(command, "EXT_BGI")==0) {

					 p1 = parameter;
					 p2 = strchr(p1, ',');
					 *p2 = '\0';
					 externalBGI(p1, ++p2);
					 }
   }

 /* sort commands (includes built in commands and aliases added) so
	can do binary search.											  */
   qsort(kmd, LastKey, sizeof(kmd[0]), kmdcmp);

 /* close config file*/
   fclose(fp);

}


/*---------------------------------------------------------------------

  PROCESS_PARAMS written by R. Baines
	to handle configuring settings as you run program from command
	line.  This may be obselete with the creation of read_cfg.

  ---------------------------------------------------------------------*/

void process_params(int count, char *param[])
{

 /* if there is a parameter process it */
   if (count > 1)
	  if (strcmp(strlwr(param[1]),"-v")==0)
		 strcpy(output_dev, param[2]);
	  else if (strcmp(strlwr(param[1]), "-n") == 0)
		 strcpy(node_loc, param[2]);

 /* if there is a second parameter process it */
   if (count > 3)
	  if (strcmp(strlwr(param[3]), "-v") == 0)
		 strcpy(output_dev, param[4]);
	  else if (strcmp(strlwr(param[3]), "-n") == 0)
		 strcpy(node_loc, param[4]);
}


/*---------------------------------------------------------------------

  PWS16_CONTROL written by L. Granroth  08-26-88
  to handle the user interface, set up the network command structure,
  and pass the data request to the network routine servicing the
  PWS16PC program.  Nonzero is returned for normal status and zero is
  returned when program termination is requested.

  Forget survey and fp options for now.

  ---------------------------------------------------------------------*/

int pws16_control (void)
{

  static struct old_params old =
    {0,0,0,0,0,0,0,0,0L,0L};       /* keep track of previous parameters*/

  static char *delim="\t =,:/";      /* input token delimiters */
  static char *endtok="endtok";

  char  card[LLEN];                    /* input command "card" */
  int i,j,numtok;
  char *p;

 /* reset variables */
   setchan=FALSE;
   Cmin=Cmd.chan[0];
   Cmax=Cmd.chan[Cmd.nchan-1];

 /* read data cards */
   do
   {
	 more = FALSE;
	 printf ("> ");
	 if (!gets(card))
	 {
	   if (feof(stdin))
		 return(FALSE);

	   strcpy (card,"HELP");
	 }

   /* semicolon is a line terminator */
	 if (p=strchr(card,';'))
		p[0]='\0'; 
	 strupr (card);
	 printf ("> %s\n",card);

   /* Copy Card so can display on graphic screen later */
	 strcpy(Cmdline, card);

   /* tokenize data card */
	 i=0;
	 tp[i]=strtok(card,delim);
	 while ((i<MAXTOK) && (tp[++i]=strtok(0,delim))) ;

   /* set up values in arrays to begin processing of arrays */
	 numtok = (tp[0]) ? i : 0;
	 tp[numtok] = endtok;
	 ki[numtok] = TRUE;

	 for (idx=numtok-1;idx>=0;idx--)           /* check against keyword table */
	 {
		ki[idx] = 0;
		for (j=1;j<LastKey;j++)
		{
		   if (!strcmp(kmd[j].keyword,tp[idx]))
		   {
			/* if one of the commands in card is RESET, then do reset now */
			  if (strcmp("RESET", tp[idx])==0)
				 cmd_reset();

			  ki[idx]=j;
			  break;
		   }
		}
	 }

  /* assign values in data card order */
	 for (idx=0;idx<numtok;idx++)
	 {
		if (kmd[ki[idx]].fnc())
		   return(FALSE);

		if (!(ki[idx+1]))
		   idx++;
	 }

	 if (Cmd.spacecraft < 0)
	 {
		puts ("Please specify SPACECRAFT=");
		more = 1;
	 }

	 if (Cmd.year < 0)
	 {
	   puts ("Please specify YEAR=");
	   more = 1;
	 }

	 if (Cmd.day < 0)
	 {
	   puts ("Please specify DAY=");
	   more = 1;
	 }

   } while (more);

 /* update channel selection if necessary */
   if (setchan)
   {
	  for (i=0; ((i<NUM_CHAN) && (Cn[i]>0)) ;i++)
		 Cmd.chan[i]=Cn[i];
	  Cmd.nchan=i;
	  for (;i<NUM_CHAN;i++)
		 Cmd.chan[i]=0;
	  Cmin = Cn[0];
	  Cmax = Cn[Cmd.nchan-1];

   }

 /* make sure an output device has been selected */
   if (Cmd.numbin == 0)
	  if (!(Cmd.numbin=pws16_device(output_dev)))
		 return (FALSE);

 /* compare against previous units, spacecraft, and time parameters */
   if (!memcmp(&Cmd.numbin,&old.numbin,24))
	  Cmd.replot = TRUE;
   else
   {
	  Cmd.replot = FALSE;
	  memcpy (&old.numbin,&Cmd.numbin,24);
   }

   return(TRUE);

} /* pws16_control */


/* ----------------------------------------------------------------

   CLEANUP  written by R. Baines  07-26-89
   frees dynamic variables to play it safe and close any open files,
   there shouldn't be any.
   ---------------------------------------------------------------- */

void cleanup (void)
{
  int i;

  puts ("Program closing.");

  if (iavg[0])
	  for (i=0; i<NUM_CHAN; i++)
	  {
		  free(iavg[i]);
		  free(ipks[i]);
	  }

  fcloseall();
}


/* ---------------------------------------------------------------

   SNAP_PREP  written by R. Baines  07-26-89
   changes settings in cmd so will work with snapshot module.
   called from pws16_snap_label().
   --------------------------------------------------------------- */

void snap_prep(void)
{
  int i;

  Cmd.numbin = 1;
  Cmd.nchan = NUM_CHAN;
  Cmd.fp = FALSE;
  Cmd.fg = FALSE;
  Cmd.fgonly = FALSE;
  for (i=0; i<NUM_CHAN; i++)
    Cmd.chan[i] = i+1;

} /* snap_prep */

