#include <string.h>
#include <ctype.h>
#include "Dictionary.h"


/* Returns the size in bytes of file */
off_t Dictionary::file_size(char *filename)
{
     struct stat buf;

     if( stat(filename, &buf) < 0 ) {
	  perror("stat");
	  exit(1);
     }

     return buf.st_size;

}


/* This is called to check if the NINE letter word is valid */
bool Dictionary::valid_word(char *word)
{

     for( int i = 0 ; i < 9 ; i++ ) {
	  if( !islower(word[i]) )
	       return false;
     }

     /* Words ending in 's' */
     if( word[8] == 's' )
	  return false;

     return true; /* Word is valid */

}

/* Constructor */
Dictionary::Dictionary(char *filename)
{

     if( (this->fp = fopen(filename, "r")) == NULL ) {
	  perror("fopen");
	  exit(1);
     }
     
     srand( time(NULL) );
     filesize = file_size(filename);

}


/* Destructor */
Dictionary::~Dictionary()
{

     fclose(this->fp);

}


/* Seek till the start of the next line */
off_t Dictionary::next_line(void)
{
     int c;

     /* Seek till end of line */
     while( (c = fgetc(this->fp)) && c != '\n' )
	  ;

}


/* Return a random 9 letter word from the Dictionary file */
char *Dictionary::random_word(void)
{
  char buf[MAXLINE];
  off_t pos;

  pos = random()%this->filesize;

  fseek(this->fp, pos, SEEK_SET);
  next_line();

  while( pos < this->filesize ) {
    fgets(buf, MAXLINE, this->fp);
    if( strlen(buf) == 10 ) { /* \n adds 1 to the length */
	 buf[9] = '\0'; /* Remove at the end \n */
	 if( valid_word(buf) ) {
	      return strdup(buf);
	 } else {
	      //printf("SKIPPED %s\n", buf);
	 }
    }
  }

  return NULL;

}


/* Binary search for word in dictionary */
bool Dictionary::isaword(char *word)
{
     char buf[80];
     int low, high, mid;
     int cmp;

     low = 0;
     high = filesize - 1;

     while( low <= high ) {
	  mid = (low + high)/2;
	  //printf("Using offset of %d\n", mid);
	  fseek(this->fp, mid, SEEK_SET);
	  next_line();
	  fgets(buf, 80, fp);
	  CHOP(buf);
	  cmp = strcasecmp(word, buf);

	  if( cmp < 0 ) {
	       //printf("%s < %s\n", word, buf);
	       high = mid - 1;
	  } else if( cmp > 0 ) {
	       //printf("%s < %s\n", word, buf);
	       low = mid + 1;
	  } else
	       return true; /* MATCH! */
     }

     return false;

}
