#include <STDIO.H>
#include <CONIO.H>
#include <STRING.H>
#include <STDLIB.H>

char str_find[200];
char str_replace[200];
int str_find_lngth, str_replace_lngth;
char* files_to_delete[100];
int f_t_d;

char* temporary();

int main()
	{
	char ifilename_str[256];
	char ofilename_str[256];
	char* ifilename;	//pointer to input filename
	char* ofilename;	//pointer to output filename

	f_t_d = 0; //initiate files_to_delete counter to zero

	printf("\n This program replaces text in any files.");
	printf("\n For executable files, replace with same size text to avoid corruption.");

	printf("\n Enter name of input file: ");
	gets(ifilename_str);

	printf(" Enter name of output file: ");
	gets(ofilename_str);

	if (*ofilename_str == 0)
		strcpy (ofilename_str, ifilename_str);

	ifilename = ifilename_str;
	ofilename = temporary();	//creates a unique file name, stores in temp_file

	while (1)
		{ //this loop is for multiple replacements after this replacement
		char ch;

		FILE* ifile = fopen(ifilename, "rb");
		FILE* ofile = fopen(ofilename, "wb");

		if ( (ifile == NULL) || (ofile == NULL) )
			{
			printf("\n File I/O Error! Please check the filenames. "
												"\n Press a key to terminate...");
			getch();
			return 2;
			}

		printf("\n Enter string to find(max 200 chars): ");
		gets(str_find);
		str_find_lngth = strlen(str_find);
		printf(" Enter string to replace with(max 200 chars): ");
		gets(str_replace);
		str_replace_lngth = strlen(str_replace);

		printf("\n Are the strings in UNICODE format (Windows Programs may use this)? ");
		do
			ch = getch();
		while (ch !='y' && ch!='Y' && ch!='n' && ch!='N');
		putch(ch);

		printf("\n");

		if (ch=='y' || ch=='Y')	//UNICODE support
			{	//insert an additional zero after every character in both strings
			int i;
			char texttemp[200];
			char* a,* b;

			a = str_find; b = texttemp;
			for (i = 0; i < str_find_lngth; i++)
				{
				*(b++) = *(a++);
				*(b++) = 0;
				}
			str_find_lngth *= 2;
			a = texttemp; b = str_find;
			for(i=0; i<str_find_lngth; i++)
				*(b++) = *(a++);
			*b = 0;

			a = str_replace; b = texttemp;
			for (i = 0; i < str_replace_lngth; i++)
				{
				*(b++) = *(a++);
				*(b++) = 0;
				}
			str_replace_lngth *= 2;
			a = texttemp; b = str_replace;
			for(i=0; i<str_replace_lngth; i++)
				*(b++) = *(a++);
			*b = 0;
			}

		unsigned long int ifile_pos = 0;
		unsigned long int ofile_pos = 0;
		unsigned long int num_matches = 0;
		unsigned int index = 0;

		printf("\n Processing...");

		while(1)
			{
			ch = fgetc(ifile);
			if (feof(ifile)) break;

			ifile_pos++;
			gotoxy(15, wherey());
			printf("%lu", ifile_pos);

			if (ch==str_find[index])
				{
				index++;
				if (index == str_find_lngth)   //found one complete match
					{
					int i=0;
					while ( i<str_replace_lngth )
						{ fputc(str_replace[i++], ofile); ofile_pos++; }
					index = 0;  //start comparison from beginning in the next iteration
					num_matches++;
					}
				continue;
				}

			if (index != 0)
				{
				for (int i=0; i<index; i++)
					fputc(str_find[i], ofile);
				ofile_pos += index;
				index = 0;
				}

			fputc(ch, ofile);
			ofile_pos++;
			}

		fclose(ifile);
		fclose(ofile);

		printf("\n Read %lu bytes from %s", ifile_pos, ifilename);
		printf("\n Written %lu bytes to %s", ofile_pos, ofilename);
		printf("\n Number of matches found: %lu", num_matches);

		printf("\n\n Any more replacements for the same files?(Y/N)");
		do
			ch = getch();
		while (ch !='y' && ch!='Y' && ch!='n' && ch!='N');
		putch(ch);

		printf("\n");

		if (ch=='n' || ch=='N')
			break;

		ifilename = ofilename;
		ofilename = temporary();
		}

	printf("\n Now copying file %s to %s...", ofilename, ofilename_str);

	FILE* ifile = fopen(ofilename, "rb");
	FILE* ofile = fopen(ofilename_str, "wb");

	if ( (ifile == NULL) || (ofile == NULL) )
			{
			printf("\n File I/O Error! Please check the filenames. "
												"\n Press a key to terminate...");
			getch();
			return 2;
			}

	while(1)
		{
		char ch = fgetc(ifile);
		if (feof(ifile)) break;
		fputc(ch, ofile);
		}
	fclose(ifile);
	fclose(ofile);
	printf("done.");

	for (int i=0; i<f_t_d; i++)
		{
		printf("\n Deleting %s...", files_to_delete[i]);
		unlink(files_to_delete[i]);
		delete files_to_delete[i];
		printf("done.");
		}

	printf("\n\n Program successful!\n");

	return 0;
	}

char* temporary()
	{
	files_to_delete[f_t_d] = new char[20];

	tmpnam(files_to_delete[f_t_d]);

	f_t_d++;
	return files_to_delete[f_t_d-1];
	}