/***********************************************************************/
/*                                                                     */
/*                               JUDGE                                 */
/*               A Word Challenge Adjudication Program                 */
/*                                                                     */
/*                             M\Cooper                                */
/*                            PO Box 237                               */
/*                    St. David,  AZ 85630-0237                        */
/*                    -------------------------                        */
/*                     thegrendel@theriver.com                         */
/*             http://personal.riverusers.com/~thegrendel              */
/*                                                                     */
/***********************************************************************/


#include "srch.h"
#include <ctype.h>
#include <time.h>
#include <sys/stat.h>
#include <conio.h>

#define DOS


/*********************************/

#define ARGCOUNT 2
#define BAD_ARGS 2
#define DELAY1 500
#define FILE_ERROR 10
#define MAXFILENAMELEN 40
#define MAXNAMELEN 100
#define TEMPBUFLEN 30
#define INCREMENT 1
#define SPACE ' '
#define LINE_LEN 80

#define CR() printf( "\n" )

#define PRINTMSG(X) strcpy(tempstr,X);\
center(tempstr);\
printf(tempstr)


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( void );
char *strlwr ( char *wordxx );
void clearscreen( void );
void opening_screen( void );
void center( char *str_to_be_centered );

void main( int argc, char **argv )
{

   char searchfile [MAXFILENAMELEN],
        words [MAXNAMELEN] = "XXX",
        tempstr [LINE_LEN],
        Separator [] = "-------------------------------",
        exit_msg1 [] = "Thank you for using the =Judge= program.",
        exit_msg2 [] =
        "A record of this session has been saved in the file JUDGE.LOG!";

   FILE *logfile;

      if( argc < ARGCOUNT )
          strcpy( searchfile, "word.lst" );

      logfile = fopen( "judge.log", "a" );

       opening_screen();
         
       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 );
             }

          }

      fprintf( logfile, "%s", Separator);
      fprintf( logfile, "\n\n" );
      fclose( logfile );

      clearscreen();
      CR(); CR(); CR(); CR();
      PRINTMSG(exit_msg1);
      CR(); CR(); CR();
      PRINTMSG(exit_msg2);      
      CR(); CR(); CR(); CR(); CR(); CR(); CR(); CR(); CR();


}

/****************************************************/

int judge1( char *words, char *filename, FILE *lgfile )
{

#ifndef DOS
FILE *prn;
#endif

   char *timeofday,
         messagec [MAXNAMELEN],
         messagef [MAXNAMELEN],
         resp [MAXNAMELEN] = "*";
   SWITCH PRINTER = OFF;



      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()
{
      clrscr();

      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 */

}

void opening_screen()
{
   char progname [] = "WORD JUDGE",
        descr [] = "- a computerized word game arbitrator -",
        pkey_msg [] = "Press a key to continue ",
        name [] = "M\\Cooper",
        address1 [] = "PO Box 237",
        address2 [] = "St. David, AZ 85630",
        Email [] = "thegrendel@theriver.com",
        url [] = "http://personal.riverusers.com/~thegrendel/",
        bar [] = "==========",
        underline [] = "--------",
        tempstr [ LINE_LEN ];


      clearscreen();

      CR(); CR();

      PRINTMSG(bar);
      CR();

      PRINTMSG(progname);
      CR();

      PRINTMSG(bar);
      CR(); CR();

      PRINTMSG(descr);
      CR(); CR(); CR(); CR();

      PRINTMSG(name);
      CR();
      PRINTMSG(underline);
      CR();
      PRINTMSG(address1);
      CR();
      PRINTMSG(address2);
      CR();
      PRINTMSG(Email);
      CR();
      PRINTMSG(url);

      CR(); CR(); CR(); CR(); CR(); CR(); CR();
     
      PRINTMSG(pkey_msg);

      getch();
     
      clearscreen();

      return;
      
}

void center( char *str )
{
   int padding;
   char st [ LINE_LEN + INCREMENT ];

	 padding = LINE_LEN / 2 - strlen( str ) / 2;
	 memset( st, SPACE, padding );
	 *( st + padding ) = NULL;  //Terminate string
	 strcat( st, str );
	 strcpy( str, st );

	 return;
}
