/**************************************************************************/
/*                                                                        */
/*                             SEARCH UTILITY                             */     
/*                                                                        */
/*                                 M\Cooper                               */
/*                                PO Box 237                              */
/*                            St. David, AZ 85630-0237                    */
/*                        -------------------------------                 */
/*                            thegrendel@theriver.com                     */
/*                  http://personal.riverusers.com/~thegrendel            */
/*                                                                        */
/**************************************************************************/


#include "srch.h"
/* srch.h contains all include files, some prototypes, etc. */

#define ARGCOUNT 2
#define BAD_ARGS 2
#define BUZZ 60
#define DELAY1 500
#define FILE_ERROR 10
#define MAXFILENAMELEN 40
#define FALSE 0
#define TRUE 1



Rflag lookup2( char *, char * );
int bzz( void );
//Other prototypes found in srch.h

void main( int argc, char **argv )
{
   char searchfile [MAXFILENAMELEN];

      if( argc < ARGCOUNT )
          {
          puts( "\nFormat: search word [filename]" );
          exit( BAD_ARGS );
          }
       else
          if( argc == ARGCOUNT )
             strcpy( searchfile, "word.lst" );
          else
              strcpy( searchfile, *(argv + 2) );


      if( lookup2( *(argv + 1), searchfile ) )
         printf( "\7\7\7%s found!", *(argv + 1) );
      else
         if( bzz() )
            printf( "%s NOT found.", *(argv + 1) );
        

}

/**********************************************************************/

int bzz()
{
      sound( BUZZ );
      delay( DELAY1 );
      nosound();
      
      return( TRUE );
}

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" );   //Because fgets() reads CR's

		while( right - left > MAX_SPAN )
			{
			middle = ( left + right ) / 2;
			fseek( fp, middle, SEEK_SET );
			fgets( discard, MAX_WLEN + 1, fp ); //Throw away partial(?) string.
			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 ); //Error in strcmp() !
					}
			}
         
      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 to file begin.
		else
			backstep = -1L * backstep;

		fseek( fp, backstep, SEEK_CUR );

		strcpy( work, search_word );  //Make working copy.
		strcat( work, CR_str );       //Because fgets() reads CR's

		for( i = 0; i <= MAXTESTS; i++ )
			{
			if( !( fgets( target, MAX_WLEN, fp ) ) ) break; //EOF!
			

			test = strcmp( work, target );
			if( test < 0 && i > 0 )
				break;   //Passed possible match
			if( !test )
				{ flag = SUCCESS; break; }
			}

		return ( flag );
}

Rflag lookup2( char *tstword, char *filename )
{
	FILE *fptr;
	long file_end; //Byte count of eof [length of file]
   const long file_begin = 0L;   
   Rflag rflag;

      if( NULL == ( fptr = fopen( filename, "r" ) ) )
         exit( FILE_ERROR );

		file_end = filelength( fileno( fptr ) );

		rflag =  b_search( tstword, fptr, file_begin, file_end );
                    //  ^^^^Preserves filepos in call!

		fclose( fptr );

      return( rflag );

}

