/*    averages.c
 * program to compute average cost per gallon and miles per gallon from
 *   Superbase exported autolog file
 *    By Joel Swank 8/30/88 
 *      Version 1.1
 */
/*
   Reads a datafile of gasoline purchases of the following format:
   Individual fields separated by commas.
   * date - character format (MMM DD YYYY)
   * odometer reading - 999999.9
   * price per gallon - $9.999
   * Total cost of purchase - $9999.99
   * gallons - 999.9
   * place and brand of gas - character

   Execute from cli.
   >averages -?           ; to get options list

*/

#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <exec/types.h>
#define STDIN 0   /* file descriptor for stdin */

char linebuf[100];

/* year selection criteria */
int yr = -1;
int eyr = -1;
int syr = -1;

/* Min and Max saveareas   */
float maxtank;
float maxcost = 0;
float maxpr = 0;
float maxgal = 0;
float minpr =1e10;
char maxtdate[20];
char maxprdate[20];
char minprdate[20];
char maxcostdate[20];
char maxgaldate[20];
int maxflag = FALSE;

FILE *fdopen();

int fileflag = FALSE;

char date[20];

/***********************************************/
/*
/*	Main routine
/*
/***********************************************/

main(argc,argv)
int argc;
char *argv[];
{
   FILE *filep;
   int cnt;

   if (argc == 0) exit(0); /* can't handle workbench */


		/* get command line options */
	getcmd(argc, argv);

		/* get command line filenames */
	for (cnt=1; cnt < argc; cnt++)
	{	if (*argv[cnt] != '-')
		{
			if ((filep = fopen(argv[cnt], "r")) == NULL)
				fatal("can't open %s", argv[cnt]) ;

			printf("FILE: %s\n",argv[cnt]);
			dofile(filep);
			fclose(filep);
			fileflag = TRUE;
		}
	}

	if (!fileflag)  /* if no files given, use stdin */
	{
		filep = fdopen(STDIN, "r");
		dofile(filep);
		fclose(filep);
	}
}

/***********************************************/
/*
/*     do a file
/*
/***********************************************/



dofile(fp)
FILE *fp;
{
   char *pp, *tp;
   float firstod = 0, miles, od, atof();
   float lastod, prevod;
   float gallons, cost, price;
   float totgal = 0, totcost = 0;
   int count = 0;
   int year;

   maxtank = 0;
   maxcost = 0;
   maxpr = 0;
   maxgal = 0;
   minpr =1e10;

   while (NULL != fgets(linebuf,100,fp))
      {

	  pp = linebuf;

	  tp = date;
	  while (*(pp) != ',') *tp++ = *pp++;	/* save date */
	  *tp ='\0';

	  pp -= 4;
	  year = atoi(pp);	/* get year */
	  pp += 5;

	  /* eliminate undesired years */
	  if (yr != -1)	
	  	{
		if (year < yr) continue;
		if (year != yr) break;
		}

	  if (eyr != -1)	
	  	{
		if (year > eyr) break;
		}

	  if (syr != -1)	
	  	{
		if (year < syr) continue;
		}

	  od = atof(pp);	/* get odometer reading */

	  if (!firstod) firstod = od;
	  else {
	  	float t = od-prevod;
		if (t > maxtank) 
			{
			maxtank = t;
			strcpy(maxtdate,date);
			}
		}

	  lastod = od;

	  while (*(++pp) != ',') ;
	  while (*(++pp) != '$') ;
	  pp++;
	  price = atof(pp);		/* get price */

	  while (*(++pp) != ',') ;
	  while (*(++pp) != '$') ;
	  pp++;
	  cost = atof(pp);		/* get cost */

	  gallons = cost/price;
	  /* accumulate data */
	  if (count != 0)
	  	{
	 	totgal += gallons;
	 	totcost += cost;
		}

	  if (maxflag)
	  	{
		if (price > maxpr) { maxpr = price; strcpy(maxprdate,date); }
		if (price < minpr) { minpr = price; strcpy(minprdate,date); }
		if (gallons > maxgal) { maxgal = gallons; strcpy(maxgaldate,date); }
		if (cost > maxcost) { maxcost = cost; strcpy(maxcostdate,date); }
		}
	  count++;
	  prevod = od;
	  }

	  /* check for enuf data */
	  if (count < 2) 
	  	{
		printf("No Data\n");
		return;
		}
	  /* print results */
	  miles = lastod-firstod;

	  printf("%d transactions processed\n", count);
	  if (maxflag)
	  	{
	  	printf("Maximum distance between transactions= %-5.1f miles on %s\n",
		        maxtank, maxtdate);
	  	printf("Maximum gallons = %-5.1f on %s\n", maxgal, maxgaldate);
	  	printf("Maximum cost = $%-6.2f on %s\n", maxcost, maxcostdate);
	  	printf("Maximum gasoline price = $%-6.3f on %s\n", maxpr, maxprdate);
	  	printf("Minimum gasoline price = $%-6.3f on %s\n", minpr, minprdate);
		}
	  printf("Total Miles = %-8.1f\n", miles);
	  printf("Total Gallons = %-7.1f\n", totgal);
	  printf("Total Cost = $%-8.2f\n", totcost);
	  printf("Average Cost per Gallon = $%-6.4f\n", totcost/totgal);
	  printf("Average Miles per Gallon = %-5.2f\n", miles/totgal);
	  printf("Average Cost per Mile = %-5.2f cents\n", totcost/miles*100);
}




/***********************************************/
/*
/*  getcmd - get arguments from command line 
/*
/***********************************************/

getcmd(argc, argv)
register argc ;
register char	*argv[] ;
{
	register cnt ;
					/* get command options */
	for (cnt=1; cnt < argc; cnt++)
	{	if (*argv[cnt] == '-')
		{	switch(argv[cnt][1])
			{
			   case 's':
				syr = val_yr(&argv[cnt][2]) ;
				if (syr == -1)
					fatal("Bad -s value: %s", argv[cnt]) ;
				printf("Starting with data for year %4d\n",syr);
				break ;

			   case 'e':
				eyr = val_yr(&argv[cnt][2]) ;
				if (eyr == -1)
					fatal("Bad -e value: %s", argv[cnt]) ;
				printf("Eending with data for year %4d\n",eyr);
				break ;

			   case 'y':
				yr = val_yr(&argv[cnt][2]) ;
				if (yr == -1)
					fatal("Bad -y value: %s", argv[cnt]) ;
				printf("Extracting data for year %4d\n",yr);
				break ;

			   case 'm':
				maxflag = TRUE;
				break ;

			   case '?':					/* help option */
				 usage();
				 printf(" averages Ver 1.1 - calculate auto averages.\n");
				 printf(" Options:\n");
				 printf(" ynn  - for requested year only.\n");
				 printf(" snn  - year to start.\n");
				 printf(" enn  - year to end.\n");
				 printf(" m    - include max and min information.\n");
				 printf(" ?    - display this list.\n");
				exit(0);

			   default:
				 usage();
				 exit(0);
			}
		}
	}

}



usage()
{
printf("usage:averages [-snn] [-enn] [-ynn] [-m] [-?] [file ...]\n");
}



/*
 *  fatal - print standard error msg and halt process
 */
fatal(ptrn, data1, data2)
register char	*ptrn, *data1, *data2 ;
{
	printf("ERROR: ");
	printf(ptrn, data1, data2) ;
	putchar('\n');
	exit(1);
}

/*
 * val_yr : validate a year string gadget contents and return
 *          -1 if invalid or year if valid.
 */

val_yr(buffer)
char *buffer;
{
	int yr;
	char *bufp;
	bufp = buffer;
	while (*bufp != '\0')
		{
		if (!isdigit(*bufp)) return -1;
		bufp++;
		}
	yr = atoi(buffer);
	if (yr <100 && yr >= 0) return yr+1900;
	if (yr <2200 && yr >= 1900) return yr;
	return -1;
}

