/*

zadatak: 14.
ime programa: veze
resenje: Srdjan Vesic (085/2000)


Program se poziva sa: veze kljucna_rec tekst_u_kom_se_pretrazuje
Npr: veze kocka seminarski.txt
Rezultat rada programa je datoteka svzad014.html.


VAZNO          ukoliko na direktorijumu na kom se nalazi "Quickc"
UPOZORENJE:    imate datoteku koja se zove "svzad014.html", njen sadrzaj ce
			   posle izvrsavanja ovog programa biti unisten!


Ako zelite da Vasa kljucna rec bude pronadjena i kada se pojavi unutar
druge reci (npr. "kockast") nakon sto aktivirate program, izaberite trazenje
unutar reci. Ako ne odgovorite sa 'd', podrazumeva se da ne zelite trazenje
unutar reci, i Vasa rec ce biti pronadjena samo ako je razdvojena separatorima
od okolnih reci. (npr. "To je bila prava kocka.") Separatori su:
<blanko>  \n  \t  .  ,  !  ?  :  '  "  -
(Znak ";" nije racunat kao separator da biste mogli da nalazite reci
kao sto je "pra&sx;ina".)


*/

#include <stdio.h>
#define MAXKLJUCNAREC 100  /* maksimalna dozvoljena duzina klucne reci */
#define MAXTRENUTNAREC 1000  /* maksimalna dozvoljena duzina reci u tekstu */
#define MAXTRENUTNAREC1 1000 /* granica za niz u koji se "pakuje" deo po deo
						   datoteke; mora da bude veci od MAXKLJUCNAREC */
typedef enum {false, true} boolean;

int rednibroj = 0;         /* broji koliko puta se pojavila kljucna rec */
boolean opciono;           /* ako je true, naci ce se kljucna rec cak
								  iako je unutar neke niske;
							  ako je false, kljucna rec ce se naci samo
								   ako je razdvojena separatorima */
int duzinakljucnereci;

char kljucnarec[MAXKLJUCNAREC + 1];  /* niz koji sadrzi klucnu rec */

void Vezivanje (FILE* ulaz, FILE* izlaz);
void OpcVezivanje(FILE* ulaz, FILE* izlaz);
boolean JednakiStringovi (char* s1, char* s2);
boolean Separator (int c);


main (int argc, char* argv[]) {

	int c;
	char opc;
	char stop;

	FILE* ulaz;
	FILE* izlaz;


	 /* provera (da li su tacno 3 argumenta u komandnoj liniji) */
	if (argc != 3) {
		fprintf(stderr, "\nNepravilno pozvan program!\n");
		fprintf(stderr, "Posetite: www.matf.bg.ac.yu/nastavno/dvitas/nastava/op/zadaci/zadaci.html");
		return 0;
	}

	   /* provera (da li je duzina kljucne reci manja ili jednaka dozvojenoj) */

	duzinakljucnereci = strlen(argv[1]);
	if (duzinakljucnereci > MAXKLJUCNAREC) {
		fprintf (stderr, "\nPredugacka kljucna rec! Povecaj MAXKLJUCNAREC.");
		return 0;
	}
	printf("\nZelite li da se trazi i unutar reci? (d = da, ostalo = ne)\n");
	scanf("%c", &opc);

	if (opc == 'd') {
		opciono = true;
	}
	else {
		opciono = false;
	}


	/* punimo niz kljucnarec:  */
	for (c = 0; (argv[1][c] != '\0') && (c < MAXKLJUCNAREC); c++) {
		kljucnarec[c] = argv[1][c];
	}
	kljucnarec[c] = '\0';


	/* otvaranje datoteka:  */

	if ((ulaz = fopen(argv[2], "r")) == NULL) {
		fprintf (stderr, "\nNemoguce otvoriti datoteku %s!", argv[2]);
	}

	if ((izlaz = fopen("svzad014.html", "w")) == NULL) {
		fprintf (stderr, "\nNemoguce otvoriti datoteku svzad014.html!");
	}

	if (opciono) {
		OpcVezivanje(ulaz, izlaz);
	}
	else {
		Vezivanje(ulaz, izlaz);
	}
	if(rednibroj == 0) {
		fprintf(stderr, "\nKljucna rec koju ste naveli se ne pojavljuje u datoteci koju pretrazujete.");
	}
	else {
		fprintf(stderr, "\nKljucna rec se pojavila %d put%s.",
				rednibroj, (((rednibroj % 10) == 1) && ( (rednibroj % 100) != 11 )) ? "" : "a");
	}
	fprintf (izlaz, "<a href = \"mailto: mr00085@alas.matf.bg.ac.yu\"> Kliknite ovde ako zelite da posaljete poruku autoru programa. </a>");
	if (fclose(izlaz) == EOF) {
		fprintf (stderr, "\nNemoguce zatvoriti datoteku svzad014.html!");
	}
	if (fclose(ulaz) == EOF) {
		fprintf (stderr, "\nNemoguce zatvoriti datoteku %s!", argv[2]);
	}
}

void Vezivanje(FILE* ulaz, FILE* izlaz) {
	static int c = 0; /* trenutno ucitani znak */
	static int i = 0;  /* brojac */
	char trenutnarec[MAXTRENUTNAREC + 1];      /* trenutno ucitana rec */
	while(c != EOF) {
		c = getc(ulaz);
		if (Separator(c)) {
			trenutnarec[i] = '\0';
			if (JednakiStringovi (trenutnarec, "<body>")) {
					  fprintf(izlaz, "<body vlink = \"ff0000\" alink = \"ff0000\">%c", c);
				i = 0;
			}
			else if (JednakiStringovi (trenutnarec, kljucnarec)) {
				fprintf(izlaz, "<a name =\"%d\" href = #%d>%s%c</a>", rednibroj, rednibroj + 1, trenutnarec, c);
				rednibroj++;
				i = 0;
			}
			else {
				fprintf(izlaz, "%s%c", trenutnarec, c);
				i = 0;
			}
		}
		else {      /* ako nije separator */
			if (i < MAXTRENUTNAREC) {
				trenutnarec[i] = c;
				i++;
			}
			else {
				fprintf (stderr, "\nPredugacka rec! Povecaj MAXTRENUTNAREC!");
				exit (1);
			}
		}
	}
}


boolean JednakiStringovi (char* s1, char* s2) {
	int brojac;
	for(brojac = 0; s1[brojac] != '\0' && s2[brojac] != '\0'; brojac++) {
		if(s1[brojac] != s2[brojac]){
			return false;
		}
	}
	return (s1[brojac] == '\0' && s2[brojac] == '\0');
}





/*  vraca: true, ako je c jedan od: ' ' '\n' itd.
		  false, inace                              */

boolean Separator (int c) {
	 int i;
	 char niz[] = " \n\t.,!?:'\"-";

	 for (i = 0; niz[i] != '\0'; i++)
		if (c == niz[i]) return true;
	 return false;
}





void OpcVezivanje(FILE* ulaz, FILE* izlaz)  {
	int l;
	static int c = 0; /* trenutno ucitani znak */
	static int i = 0;  /* brojac */
	char trenutnarec[MAXTRENUTNAREC1 + 1];     /* trenutno ucitani niz karaktera */
	boolean menjao = false;

	/* punimo trenutnarec iz datoteke: */
	while (1) {
		for (i = 0; (c != EOF) && (i < MAXTRENUTNAREC1); i++) {
			trenutnarec[i] = (c = getc(ulaz));
		}
		i--;
		if (i >= MAXTRENUTNAREC) {
		}
		else {
			trenutnarec[i] = -1;
		}

		i = 0;
		while (i < duzinakljucnereci) {
			if (trenutnarec[i] == -1) {
				trenutnarec[i] = '\0';
				fprintf (izlaz, "%s", trenutnarec);
			}
			i++;
		}

		/* glavni deo */
		for (i = 0; (i <= (MAXTRENUTNAREC1 - duzinakljucnereci)) &&
						  trenutnarec[i + duzinakljucnereci] != -1; i++) {

			if (Poredi ("<body>", trenutnarec, i, 6)) {
												/* 6 je duzina niske: <body> */
				fprintf (izlaz, "<body vlink = \"ff0000\" alink = \"ff0000\">");
				i += 5;           /* 6 - 1 */
				menjao = true;
			}

			else if ((menjao) && (Poredi (kljucnarec, trenutnarec, i, duzinakljucnereci))) {
			   fprintf(izlaz, "<a name =\"%d\" href = #%d>%s</a>", rednibroj, rednibroj + 1, kljucnarec);
				rednibroj++;
				for (l = 0; l < duzinakljucnereci; l++) {
					if (trenutnarec[i + l] == -1) {
						trenutnarec[i + l] = '\0';
								   fprintf (izlaz, "%s", trenutnarec);
						return;
					}
				}
				i += duzinakljucnereci - 1;
			}
			else {
				fprintf(izlaz, "%c", trenutnarec[i]);
			}
		}

		if (c == EOF) {
			if (Poredi (kljucnarec, trenutnarec, i, duzinakljucnereci)) {
				fprintf(izlaz, "<a name =\"%d\" href = #%d>%s</a>", rednibroj, rednibroj + 1, kljucnarec);
				rednibroj++;
				return;
			 }
			else {
				 for (l = 0; l < duzinakljucnereci; l++) {
					 fprintf (izlaz, "%c", trenutnarec[i + l]);
				 }
				 return;
			 }
		}
		else {
			for (l = 0; i + l < MAXTRENUTNAREC1; l++) {
				trenutnarec[l] = trenutnarec[i + l];
			}
		}
	}
}




/* uzima dva stringa; poredjenje se vrsi na sledeci nacin:
   poredi se od 0-tog do (koliko-1)-vog karaktera iz prvog stringa sa
			 od odakle-og do (odakle+koliko-1)-vog karaktera iz drugog

   vraca: true, ako su jednaki
		  false, ako nisu                               */

boolean Poredi (char* prvi, char* drugi, int odakle, int koliko)  {
	int brojac;
	for (brojac = 0; brojac < koliko; brojac++) {
		if (prvi[brojac] != drugi[odakle + brojac]) {
			return false;
		}
	}
	return true;

}