
#include <stdio.h>
#include <stdlib.h>

#define MAXFILESIZE 200000
#define MAXTEXTURESIZE 20000

char buf[ MAXFILESIZE ];
char texture[ MAXTEXTURESIZE ];
char newTexture[ MAXTEXTURESIZE ];

// This program will replace any binary string with any other arbitrary string. 
// Compile with  
// cc binaryReplacer.c -o binaryReplacer


int main(int argc, char* argv[])
{
   char c ;
   int filesize = 0, texturesize = 0, replacementTexturesize = 0;
   int justMatchP = 0;
   FILE* bob,* output;

   int i;

   if ( argc < 5 )
   {
      printf("Usage: binaryReplacer inFile outFile textureIn textureOut\n");
      exit( -1 );
   }

   if ( strcmp( argv[ 2 ], "-match" ) == 0 )
   {
      justMatchP = 1;
   } 

   printf("Replacing all instances of %s in file %s \n  with %s, writing results to %s\n", argv[ 3 ], argv[ 1 ], argv[ 4 ], argv[ 2 ] );

   // Grab infile
   bob = fopen( argv[1], "r" );
   if ( bob == NULL ) {
      perror( "Can't open input file...");
      exit( -1 );
   }
   printf("Getting input file.\n");
   while ( ( c = fread( &buf[ filesize ], 1, 1, bob ) ) != 0 )
   {
      filesize++;
      if ( MAXFILESIZE < filesize )
      {
	 printf("File too big for my pathetic brain!\n");
	 exit( -1 );
      }
   }
   fclose( bob );

   // Prepare the outfile
   if ( justMatchP == 0 )
   {
      output = fopen( argv[2], "w+" );
   }

   // Grab the string
   bob = fopen( argv[3], "r" );
   if ( bob == NULL ) {
      perror( "Can't open texture file...");
      exit ( - 1 );
   }

   printf("Getting texture file.\n");
   while ( ( c = fread( &texture[ texturesize ], 1, 1, bob ) ) != 0 )
   {
      texturesize++;
      if ( MAXFILESIZE < texturesize )
      {
	 printf("File too big for my pathetic brain!\n");
	 exit( -1 );
      }
   }
   fclose( bob );

   // Get the output texture
   if ( !justMatchP )
   {

      printf("Getting output texture file.\n");

      bob = fopen( argv[4], "r" );
      if ( bob == NULL ) {
	 perror( "Can't open replacement file...");
	 exit ( -1 );
      }
      while ( ( c = fread( &newTexture[ replacementTexturesize ], 1, 1, bob ) ) != 0 )
      {
	 replacementTexturesize++;
	 if ( MAXFILESIZE < replacementTexturesize )
	 {
	    printf("File too big for my pathetic brain!\n");
	    exit( -1 );     
	 }
      }
      fclose( bob );
   }

   printf("filesize = %d, texturesize = %d\n", filesize, texturesize );

   if ( filesize < texturesize )
   {
      printf("ERROR: Texture is larger than file!\n");
      exit( -1 );
   }

   if ( replacementTexturesize != texturesize )
   {
      printf("ERROR: Textures are mismatched in size! Old %d, new %d\n", texturesize, replacementTexturesize );
      exit( -1 );
   }


   // Now, the world's least-efficient search
   for ( i = ( filesize - texturesize ); i >=0; i-- )
   {
      int j, matchP = 1;


      for ( j = 0; j < texturesize; j++ )
      {
         if ( buf[ i + j ] != texture[ j ] )
         {
            matchP = 0;
            break;
         }
      }
      if ( matchP )
      {
         printf("Texture match at position %d\n", i );
	 if ( !justMatchP )
	 {
	    for ( j = 0; j < texturesize; j++ )
	    {
	       buf[ i + j ] = newTexture[ j ];
	    }
	 }
      }
   }

   if ( !justMatchP )
   {
      printf("Wrote out %d chars.\n", fwrite( buf, 1, filesize, output ));
   }

   fclose( output );
}
