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

#define ARGCOUNT 2
#define BAD_ARGS 2
#define DELAY1 500
#define FILE_ERROR 10
#define MAXFILENAMELEN 40

Rflag lookup2( char *, char * );
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 );

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%s found!\n", *(argv + 1) );
      else
         printf( "%s NOT found.\n", *(argv + 1) );
        
}


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 );
 }


