// Nick Cash
// Hmwk 1
// 810:114 - Fall 07

// Same defines as the normal program
//#define _FILE_OFFSET_BITS 64
//#define _LARGE_FILE_SUPPORT

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME_SIZE 32
#define TEL_SIZE 15
#define FNAME 128
#define BUF_SIZE 128

// Same structures as the normal program
struct Rec
{
  char nameLast[NAME_SIZE];
  char nameFirst[NAME_SIZE];
  char Tel[TEL_SIZE];
};

struct INDX
{
  char nameLast[NAME_SIZE];
  char nameFirst[NAME_SIZE];
  fpos_t offset;
};

// Function prototypes
void find_index_entry( INDX *ptr  );
Rec *read_entry_rec( const fpos_t *pos);

// This is where it all begins...
int main ( void )
{
  INDX data; // user inputs data
  Rec *entry; // our entry when we've recieved it

  printf( "\n\nEnter 'quit' for the last name to quit the program.\n\n" );
  
  // loop until we break
  while ( true )
  {
    // intiailize each loop
    data.offset = -1;

    printf( "\nPlease enter the last name: " );

    if ( fgets(data.nameLast, NAME_SIZE, stdin) == NULL ) // end of input
     return EXIT_FAILURE;
    else
      data.nameLast[strlen(data.nameLast)-1]='\0';

    // if the first word we read is quit then return successfully
    if ( !strcmp(data.nameLast,"quit") )
      break;
      
    printf( "\nPlease enter the first name: " );

    if ( fgets(data.nameFirst, NAME_SIZE, stdin) == NULL ) // end of input
     return EXIT_FAILURE;
    else
      data.nameFirst[strlen(data.nameFirst)-1]='\0';

    printf( "\n\nSearching...\n\n" );
    
    // search index
    find_index_entry( &data  );
    
    // did we find them? check the offset
    if ( data.offset == -1 )
     printf( "\n\nNo one was found under '%s %s'.\n", data.nameFirst, data.nameLast );
    else
    {
      // grab entry from db
      if ( (entry = read_entry_rec(&data.offset) ) == NULL )
      {
        printf( "\n\nFailed to lookup entry.\n\n" );
        continue;
      }
      
      printf( "\n\nFound!\n----------\n%s,%s -> %s\n----------\n", entry->nameFirst,entry->nameLast, entry->Tel);
      
      // get rid of data
      free(entry);
      entry = NULL;
    }
  } // end while
  
  printf( "\n\nThank you, good bye!\n\n" );
}

// seeks to a specified spot in the file given to read and return
// an allocated rec structure
Rec *read_entry_rec( const fpos_t *pos)
{
   Rec *ptr = NULL;
   FILE *f = fopen( "output.txt", "r" ); // open output file containing the records

   // check for bad file pointer
   if ( !f )
    return NULL;

   // set the position and check for bad return
   if ( fsetpos(f, pos) != 0 )
    return false;

   // set for read, give the pointer some data
   ptr = (Rec*)malloc(sizeof(Rec));

   // read the record from the file
   fread(ptr, sizeof(struct Rec), 1, f);

   // close file
   fclose(f);

   return ptr;
}

// Find a name in the index file
// Inputs: index file, pointer to an index struct to put the offset into
void find_index_entry( INDX *ptr  )
{
   INDX temp;          // used to load data
   bool found = false; // our loop termination flag
   FILE *index_file = fopen( "index", "r" );

   // check for bad file pointer
   if ( !index_file )
    return;

   // read the from the file
   while ( !found )
   {
      // get data, check for errors and end of file
      if ( fread(&temp, sizeof(struct INDX), 1, index_file) == 0 )
       return;
      
      // compare names
      if ( !strcmp(ptr->nameLast, temp.nameLast) && !strcmp(ptr->nameFirst, temp.nameFirst) )
      {
        ptr->offset = temp.offset;
        found = true;
      }
   }
   
   fclose(index_file); // shut the index file
}