/* proj3stage3.c  P. Conrad CISC105  Fall 2005 */

/* Example to follow for stage 3 of project 3;
   illustrates reading data into array of structs */

#include <stdio.h>
#include <string.h> /* for strtok, strncpy */
#include <stdlib.h> /* for atof() */

#include "hiking.h"


#define FILENAME_LEN 128  /* maximum length of filename */
#define MAXLINE 1024 /* maximum length of input line in file */

#define MAX_HIKING_TRAILS 10  /* no more than 10 hiking trails */

/* function prototypes */

char readOneChar(void);
void printPrompt(void);

int  readFileIntoArrayOfStructs(struct Hiking_S *trails);
                               /* or could use trails[] */

void printHelp(void);

/* Ask about this "const" in lecture */

void printValues (const struct Hiking_S trails[], const int count); 
                       /* or could use *trails */

/***************** MAIN PROGRAM **************/


int main(void)
{
  /* declare variables */

  struct Hiking_S trails[MAX_HIKING_TRAILS]; /* array of structs */


  int numTrails = 0;  

  char c; /* menu option */
  
  /* main menu */

  printPrompt();
  c = readOneChar();
  while (c!='q' && c!='Q')  /* while user didn't select quit */
    {
      switch(c)
	{
	case 'h':
	case 'H':
	  printHelp();
	  break;

	case 'r':
	case 'R':
	  /* read one line from the file and store the result
	     into the array of structs */
	  
	  numTrails = readFileIntoArrayOfStructs(trails);

	  break;
	    
	case 'p':
	case 'P': /* print out the trails */

	  printValues(trails, numTrails);
	  break;
	    
	default:
	  printf("I don't understand the option: %c\n",c);
	  break;
	  
	}
      printPrompt();
      c = readOneChar();

    } /* end while */

  printf("Thanks for using this program.\n");
  printf("Bye now.\n");

}


void printHelp(void)
{
  printf("\n");
  printf(" h: help\n");
  printf(" p: print values\n");
  printf(" q: quit\n");
  printf(" r: read values\n");
  printf("\n");

}

void printPrompt(void)
{
  printf("Enter option (type h for help): ");
}

char readOneChar(void)
{
  char c;
  fflush(stdin);
  scanf("%c",&c);
  return c;
}


/* Pass in an array of structs, and return the number of structs read */

int  readFileIntoArrayOfStructs(struct Hiking_S *trails)
{
  
  char filename[FILENAME_LEN];
  char inputLine[MAXLINE];
  FILE *infile;

  char *result; /* for result of fgets */


  /* all of these pointers are for use with strtok(),
     to find the locations of each field on a line of input from the file 

     Lines in the example file hikingData.txt have the format: 

     South Kaibab,Grand Canyon NP,6.3,AZ,1
     
     (Note: change this comment to reflect YOUR example data file!)
  */

  char *namePtr;
  char *locationPtr;
  char *lengthPtr;
  char *statePtr;
  char *numTimesHikedPtr;

  int count; /* number of records that were read from the file */

  printf("Please enter a filename: ");
  fflush(stdin);
  scanf("%s",filename);
  
  infile = fopen(filename, "r");

  /* check whether file opened properly */

  if (infile == NULL)
    {
      perror(filename);
      fprintf(stderr,"Can't open %s\n", filename);
      fclose(infile); /* close the input file */
      return 0; /* we return 0 as the number of trails, 
		   so no need to blank out any fields */
    }

  count = 0;

  /* read until end of file  */ 

  result = fgets(inputLine, MAXLINE, infile);
  
  while (result != NULL)
    {
      
      /* The following code was not in your project 2 example file,
	 but is very important! Otherwise we can blow past the end of
	 our array, and trash the computer's memory, and eventually
	 cause a segmentation fault 

         Try running this program on the file tooMuchHikingData.txt
         which has more than MAX_HIKING_TRAILS (10) lines in it. */

      if (count == MAX_HIKING_TRAILS)
	{
	  fprintf(stderr,"You have more than %d lines in your file\n",
		  MAX_HIKING_TRAILS);
	  fprintf(stderr,"This program can only handle up to %d lines\n",
		  MAX_HIKING_TRAILS);
	  fprintf(stderr,"Ask a programmer to change MAX_HIKING_TRAILS"
		  " and recompile\n");
	  fclose(infile);
	  return count;
	}

      /* divide up the string at the commas;
	 requires #include <string.h>.  Ask about this in lecture */
      
      namePtr          = strtok(inputLine,",");
      locationPtr      = strtok(NULL,",");
      lengthPtr        = strtok(NULL,",");
      statePtr         = strtok(NULL,",");
      numTimesHikedPtr = strtok(NULL,",");
      
      
      /* store the results in the arrays first, THEN increment count*/
      /* always do it in THAT order! */
      
      strncpy(trails[count].name,    namePtr,    HIKING_TRAIL_NAME_LEN);
      strncpy(trails[count].location,locationPtr,HIKING_TRAIL_LOCATION_LEN);
      strncpy(trails[count].state,   statePtr,   HIKING_TRAIL_STATE_LEN);
      
      trails[count].lengthInMiles = atof(lengthPtr);
      trails[count].numTimesHiked = atoi(numTimesHikedPtr);

      count++;

      /* try to read the next line of data */
      result = fgets(inputLine, MAXLINE, infile);
    }
     

  printf("Data read successfully from file\n");
  
  /* close the input file */
  
  fclose(infile);
  
  /* return the number of lines that you read */

  return count; /* this is the number of trails read */
  
}



void printValues (const struct Hiking_S trails[], const int count)
{
  int i;
  for (i=0; i<count; i++)
    {
      printf("\n");
      printf("  hiking trail name: %s\n",trails[i].name);
      printf("           location: %s\n",trails[i].location);
      printf("    length in miles: %6.1lf miles\n",trails[i].lengthInMiles);
      printf("              state: %s miles\n",trails[i].state);
      printf("              hiked: %d %s\n",trails[i].numTimesHiked,
	     (trails[i].numTimesHiked == 1) ? "time" : "times");
      printf("\n");
    }
}




