/****
 graftemp.c by Andrew Huang <bunnie@mit.edu> 
 ****/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>

#define IS ==
#define AINT !=
#define AND &&
#define OR ||

#define LOGNAME      "/var/adm/templog"
#define NUMREC       72

/* print month day year hour tempinside tempoutside */

typedef struct recordType {
  int day;
  int month;
  int year;
  int hour;
  float inside;
  float outside;
  struct recordType *next;
  int invalid;
} r;

typedef struct recordType record;


record *head;

void readentry(FILE *infile, record *rec)
{ /* readentry */
  /* locals */

  /* body */
/* print month day year hour tempinside tempoutside */
  fscanf(infile, "%d %d %d %d %f %f", &(rec->month), &(rec->day), &(rec->year), &(rec->hour), &(rec->inside), &(rec->outside) );
  fgetc(infile); /* eat the LF */

} /* readentry */


void createlist(FILE *infile, record **head)
{ /* createlist */
  /* locals */
  unsigned i;
  record   *cur;
  record   *temp;
  record   *grip;
  int lasthour;
  int lastday;
  int lastmonth;
  unsigned good;
  unsigned unsync;
  unsigned resync;

  /* body */
  cur = (record *) malloc(sizeof( record ) );
  cur->invalid = 1;
  cur->next = NULL;
  grip = cur;

  for( i = 0; i < (NUMREC - 1); i ++ ) {
    temp = (record *) malloc( sizeof( record ) );
    temp->invalid = 1;
    temp->next = NULL;
    cur->next = temp;
    cur = cur->next;
  } /* for */
  cur->next = grip;  /* circularize the list */
    
    
  readentry(infile, grip); /* get first record */
  lasthour = grip->hour;
  lastday = grip->day;
  lastmonth = grip->month;
  if( (grip->inside > 200.0) OR (grip->outside > 200.0)  OR (grip->outside < -100) OR (grip->outside < -100) )  /* added lower limit code 5/25/97 */
    grip->invalid = 1;
  else
    grip->invalid = 0;

  cur = grip->next;

  temp = (record *) malloc( sizeof( record ) );
  temp->invalid = 1;
  temp->next = NULL;
  
  resync = 0;
  unsync = 0;
  do {
    temp->day = cur->day;    /* pointless code...I made a booboo */
    temp->month = cur->month; /* too lazy to delete it */
    temp->year = cur->year;
    temp->hour = cur->hour;
    temp->inside = cur->inside;
    temp->outside = cur->outside;
    temp->next = cur->next;
    temp->invalid = cur->invalid;
    if( !resync )
      readentry(infile, cur);
    if(!feof(infile)) {
      cur->invalid = 1;
      if( (cur->inside > 200.0) OR (cur->outside > 200.0) OR (cur->inside < -100) OR (cur->outside < -100)) /* lower threshold added 5/25/97 */
	cur->invalid = 1;
      else
	cur->invalid = 0;

/*      printf("hour: %d, lasthour: %d\n", cur->hour, lasthour ); */
      good = 0;
      if( (lasthour AINT 23) AND !resync ) {
	if( cur->hour IS (lasthour + 1) ) {
	  lasthour = cur->hour;
	  cur = cur->next; /* descend down list */
	  good = 1;
	} /* if */
	else if( cur->hour IS lasthour ) {
/*	  printf("repeat\n"); */
	  good = 1;
	} /* else if */
      } /* if */
      else if( (cur->hour IS 0) AND !resync ) {  /* handle hour wrap-around case */
	lasthour = cur->hour;
	cur = cur->next;
	good = 1;
      } /* else if */
      else if( (cur->hour IS lasthour) AND !resync ) {
/*	printf("repeat\n"); */
	good = 1;
      } /* else if */
    } /* if */
    else {
      cur->day = temp->day;
      cur->month = temp->month;
      cur->year = temp->year;
      cur->hour = temp->hour;
      cur->inside = temp->inside;
      cur->outside = temp->outside;
      cur->next = temp->next;
      cur->invalid = temp->invalid;
    } /* else */

    if( (good IS 0) ) {
      lasthour = (lasthour + 1) % 24;  /* mod 24 bug fixed 5/25 */
      if( !resync )
	unsync = cur->hour;
      resync = unsync - lasthour;
/*      printf("unsync %d\n", unsync); */
      cur->invalid = 1;
      cur = cur->next;
    } /* if */
  } while( !feof(infile) );
  /*cur->invalid = 1;*/  /* questionable line */
  *head = cur;

} /* createlist */

void findextreme(record *head, float *max, float *min)
{ /* findextreme */
  /* locals */

  int done = 0;
  float lmax;
  float lmin;
  float cmax;
  float cmin;
  record *cur;
  int   i = 0;

  /* body */
  cmax = -100;
  cmin = 200;
  lmax = -101;
  lmin = 201;
  cur = head;
  
  do {
    if( cur->invalid IS 0 ) {
      if( cur->inside > cmax )
	cmax = cur->inside;
      if( cur->outside > cmax )
	cmax = cur->outside;
      if( cur->inside < cmin )
	cmin = cur->inside;
      if( cur->outside < cmin )
	cmin = cur->outside;
    } /* if cur->invalid IS 0 */

    /* printf("iter %f %f \n", cmax, cmin); */
    
    if( (i % NUMREC) IS 0 ) {
      if( (cmin IS lmin) AND (cmax IS lmax) ) {
	done = 1;
      } /* if */
      else {
	lmin = cmin;
	lmax = cmax;
      } /* else */
    } /* if */
    i++;
    cur = cur->next;
    
  } while( done IS 0 );
    
  *max = cmax;
  *min = cmin;

} /* findextreme */
	
  
#define ROWS 24
#define COLS 80

void main()
{ /* main */
  /* locals */
  FILE *infile;
  record *cur;
  int    i, j;
  float  max,min;
  float  stepsize;
  float  tick;
  int    printed;

  /* body */
  infile = fopen(LOGNAME, "r");
  
  createlist( infile, &cur );
#if 0
  for(i = 0; i < NUMREC; i++ ) {
    printf("%d %d %d %d %f %f %d\n", cur->month, cur->day, cur->year, cur->hour, cur->inside, cur->outside, cur->invalid);
    cur = cur->next;
  } /* for */
#endif
  findextreme(cur, &max, &min);
  /* printf( "%f %f\n", max, min ); */
  
  stepsize = ((max + 5) - (min -5)) / (ROWS - 4);

/*  printf("Temperature in degrees F\n"); */
  tick = max + 5;
  for(i = 0; i < (ROWS - 4); i++ ) {
    printf("%2.0f |", tick);  /* head each row with temp */
    for(j = 0; j < NUMREC; j++ ) {
      printed = 0;
      if( cur->invalid AINT 0 ) {
	putchar('*');
	printed = 1;
      } /* if */	
      if( (cur->outside < tick) AND (cur->outside >= (tick - stepsize)) ) {
	if( printed IS 0)
	  putchar('o');
	printed = 1;
      } /* if */
      if( (cur->inside < tick) AND (cur->inside >= (tick - stepsize)) ) {
	if( printed IS 0)
	  putchar('.');
	printed = 1;
      } /* if */
      if( printed IS 0 ) {
	putchar(' ');
	printed = 1;
      } /* if */
      cur = cur->next;
    } /* for */
    putchar('\n');
    tick = tick - stepsize;
  } /* for */

  printf("Hour");

  for(j = 0; j < NUMREC; j ++) {
    if( (j % 3 ) IS 0 ) {
      if(cur->invalid IS 0)
	printf("%-2d ", cur->hour );
      else
	printf("*  ");
    } /* if */
    cur = cur->next;
  } /* for */

  printf("\nDay ");

  for(j = 0; j < NUMREC; j ++) {
    if( (j % 3 ) IS 0 ) {
      if(cur->invalid IS 0)
	printf("%-2d ", cur->day );
      else
	printf("*  ");
    } /* if */
    cur = cur->next;
  } /* for */
  putchar('\n');

  printf("* = invalid entry | o = outside temp | . = inside temp\n");
} /* main */


