#include "srch.h"
#include <ctype.h>
#include <time.h>
#include <sys/stat.h>

/************MSDOG?***************/
#undef DOS
/*********************************/

#ifdef DOS

#include <conio.h>
#define PRINTER stdprn
#define CLEARSCREEN "cls"

#endif


#ifndef DOS

#define CLEARSCREEN "clear"

#endif
/*********************************/

#define ARGCOUNT 2
#define BAD_ARGS 2
#define DELAY1 500
#define FILE_ERROR 10
#define MAXFILENAMELEN 40
#define MAXNAMELEN 100
#define TEMPBUFLEN 30

typedef enum { OFF, ON } SWITCH;
typedef enum { FALSE, TRUE } Boolean;
 
Rflag lookup2( char *, char * );
Boolean isvalid( char *word_set, char *filename );
long filesize( char *file_name );
Rflag b_search( char *s_word, FILE *fp, long lft, long rt );
Rflag l_search( char *sh_word, FILE *fp );
int judge1( char *word, char *filenam, FILE *logfile );
char *get_timeofday();
char *strlwr ( char *wordxx );
void clearscreen();


void main( int argc, char **argv )
{

   char searchfile [MAXFILENAMELEN],
        words [MAXNAMELEN] = "XXX";
   FILE *logfile;

      if( argc < ARGCOUNT )
          strcpy( searchfile, "word.lst" );

      logfile = fopen( "judge.log", "a" );

       clearscreen();       
         
       while( isalpha( *words ) )
          {
          printf( "---Enter word(s) to check---\n" );
          printf( "  just  <ENTER> to exit  \n\n" ); 
          gets( words );
          if( isalpha( *words ) )
             {
             strlwr( words );
             judge1( words, searchfile, logfile );
             }

          }

      fclose( logfile );
        
}

/****************************************************/

int judge1( char *words, char *filename, FILE *lgfile )
{

#ifndef DOS
FILE *prn;
#endif

   char *timeofday,
         messagec [MAXNAMELEN],
         messagef [MAXNAMELEN],
         resp [MAXNAMELEN] = "*";
   SWITCH PRINTER = OFF;

#ifndef DOS
prn = fopen( "/dev/lp1", "w" );
#endif



      if( isvalid( words, filename ) )
         {
         sprintf( messagec, "==========VALID=========\n" );
         sprintf( messagef, "%s VALID\n", words );
         }
      else
         {
         sprintf( messagec, "========NOT FOUND=======\n" );
         sprintf( messagef, "%s NOT FOUND\n", words );
         }

      timeofday = get_timeofday();


      fprintf( lgfile, "%s", messagef );
      fprintf( lgfile, "%s\n\n", timeofday );


      printf( "\n%s", messagec ); 
      printf( "%s\n\n\n\n", timeofday );
      printf( "<P>rint or <ENTER> to continue... " );
      gets( resp );
      if( *resp == 'P' || *resp == 'p' )
          PRINTER = ON;
      printf( "\n\n" );


/**********************PRINTOUT*************************/
#ifdef DOS
      if( PRINTER == ON )
        {
        fprintf( stdprn, "%s", messagef );
        fprintf( stdprn, "%s", timeofday );
        }

#else

      if( PRINTER == ON )
         {
         fprintf( prn, "%s", messagef );
         fprintf( prn, "%s\n\n", timeofday );
         }
      fclose( prn );

#endif
/*********************************************************/

      clearscreen();

      return;

}



Rflag b_search( char *search_word, FILE *fp, long left, long right )
{
   int result;
   long middle;
   char discard [MAX_WLEN + 1],
        working [MAX_WLEN + 1],
        target [MAX_WLEN];
	Rflag bflag = FAIL;
	
      strcpy( working, search_word );
      strcat( working, "\n" ); 

		while( right - left > MAX_SPAN )
			{
			middle = ( left + right ) / 2;
			fseek( fp, middle, SEEK_SET );
			fgets( discard, MAX_WLEN + 1, fp );
			fgets( target, MAX_WLEN, fp );

			result = strcmp( working, target );

         if( !result )
            { bflag = SUCCESS; break; }

         if( result < 0 )
            right = middle;
         
         else
            if( result > 0 )
               left = middle;
         
            else
               {
               puts( "Error in strcmp() in BINARY SEARCH !" );
					exit( COMPARISON_ERROR );
					}
			}
         
      if( !bflag )
         bflag = l_search( search_word, fp );

      return( bflag );

}


Rflag l_search( char *search_word, FILE *fp )
{                                          
	long backstep;
	int test,
		 i;
	char target [MAX_WLEN],
		  work [MAX_WLEN + 1],
		  CR_str [] = "\n";
	Rflag flag = FAIL;


		if( ( backstep = ftell( fp ) ) > 2 * MAX_SPAN )
			backstep = -1L * ( 2 * MAX_SPAN );
		else
			backstep = -1L * backstep;

		fseek( fp, backstep, SEEK_CUR );

		strcpy( work, search_word );
		strcat( work, CR_str );

		for( i = 0; i <= MAXTESTS; i++ )
			{
			if( !( fgets( target, MAX_WLEN, fp ) ) ) break;
			

			test = strcmp( work, target );
			if( test < 0 && i > 0 )
				break;  
			if( !test )
				{ flag = SUCCESS; break; }
			}

		return ( flag );
}

Rflag lookup2( char *tstword, char *filename )
{
	FILE *fptr;
	long file_end;
   const long file_begin = 0L;   
   Rflag rflag;

	
      file_end = filesize( filename );
	
      if( NULL == ( fptr = fopen( filename, "r" ) ) )
         exit( FILE_ERROR );

		rflag =  b_search( tstword, fptr, file_begin, file_end );

		fclose( fptr );
		
      return( rflag );

}






long filesize( char *filename )
{

   int filehandle;
   long fsize;
   FILE *fp;
   struct stat fstatistics;
     
      fp = fopen( filename, "r" );
      filehandle = fileno( fp );      

      if( !fstat( filehandle, &fstatistics ) )
	fsize = fstatistics.st_size;
      else
        fsize = -1L;

      fclose( fp );
       
      return( fsize );
 }


char *get_timeofday()
{
   time_t tim;
   char *timstr;

      tim = time( NULL );
      timstr = ctime( &tim );


      return( timstr );

}


char *strlwr ( char *wd )
{

   char *wptr;

      wptr = wd;

      while( *wptr )
         {
         *wptr = tolower( *wptr );
         wptr++;
         }

      return( wd );

}


void clearscreen()
{
      system( CLEARSCREEN );

      return;
}

Boolean isvalid( char *wordset, char *filename )
{

   char word_buf [MAXNAMELEN],
        w_temp [TEMPBUFLEN],
        *wp,
        *wtp;

      strcpy( word_buf, wordset );
      wp = word_buf;
      wtp = w_temp;
      /* initialize pointer to words storage */


 while( *wp != 0 )
        {
         while( isalpha( *wp ) )
             *wtp++ = *wp++;
         *wtp = 0;    
         if( !lookup2( w_temp, filename ) )
              return( FALSE );   /* A word doesn't check: crash! */
         wtp = w_temp; /* reinitialize pointer */
         while( !isalpha( *wp ) && *wp != 0 )
            wp++;
         }






      return( TRUE ); /* All words check */

}

