/*====================================================================
 *
 * TXF string exchange module
 *
 *====================================================================
 *                                   copyright(C) 1992-1994 T.Nakatani
 *====================================================================
 */
#include "txf.h"

void prepare_exchange(char far **tmpbuf)
{
	int i = 0, j;
	int maxlen = 0, chrattr = CT_ANK;
	char far *form = NULL;

	for (i = 0; i < exflg; i++) {
		form = farmalloc(far_strlen(exold[i]) + 1);
		if (form == NULL) {
			errexit("out of memory(old)");
		}
		far_strcpy(form, exold[i]);
		/* free(exold[i]); */
		exold[i] = ftrans(form);
		farfree(form);
		if (maxlen < far_strlen(exold[i])) {
			maxlen = far_strlen(exold[i]);
		}
		exattr[i] = farmalloc(far_strlen(exold[i]) + 1);
		if (exattr[i] == NULL) {
			errexit("out of memory(ex_attr)");
		}
		for (j = 0; *(exold[i] + j) != NUL; j++) {
			chrattr = chkctype(*(exold[i] + j), chrattr);
			*(exattr[i] + j) = chrattr;
		}
		if (exnew[i] != NULL) {
			form = farmalloc(far_strlen(exnew[i]) + 1);
			if (form == NULL) {
				errexit("Heap Error at(new)");
			}
			far_strcpy(form, exnew[i]);
			/* free(exnew[i]); */
			exnew[i] = ftrans(form);
			farfree(form);
		}
	}
	*tmpbuf = farcalloc(maxlen + 2, 1);
	if (*tmpbuf == NULL) {
		errexit("Heap Error at(new2)");
	}

	for (j = 0; j < exflg; j++) {
		exptr[j] = exold[j];
		exattrptr[j] = exattr[j];
	}
}

void exchange()
{				/* oldšnew	*/
	int i = 0, j, dmy;
	int sameflg = -1, diff = 0, chrattr = CT_ANK;
	unsigned long int extime = 0, ix, iy;
	char far *rptr;
	char far *tmpbuf;

	prepare_exchange(&tmpbuf);

	rptr = buffileopen(8);

	i = 0;
	ix = 1;
	iy = 1;
	chrattr = CT_ANK;
	while (remainbyte()) {
		sameflg = -1;
		while (sameflg == -1) {
			if (remainbyte()) {
				rptr = readnext(1);
			}
			else {
				break;
			}
			if (ix == 1L) {
				if (chktouch(rptr, iy)) {
					while (*rptr != LF) {
						_dos_write(outputh, rptr, 1, &dmy);
						if (!remainbyte()) break;
						rptr = readnext(1);
					}
					if (*rptr == LF) {
						_dos_write(outputh, rptr, 1, &dmy);
						ix = 1;
						iy++;
					}
					continue;
				}
			}
			chrattr = chkctype(*rptr, chrattr);
			diff = 0;
			for (j = 0; j < exflg; j++) {
				if ((*rptr == *(exptr[j])) && (chrattr == *(exattrptr[j]))) {
					exptr[j] += 1;
					exattrptr[j] += 1;
					if (*exptr[j] == NUL) {
						sameflg = j;
					}
				}
				else {
					if (exold[j] != exptr[j]) {
						exptr[j] = exold[j];
						exattrptr[j] = exattr[j];
					}
					diff ++;
				}
			}
			if (sameflg == -1) {
				if (diff < exflg) { 
					*(tmpbuf+i) = *rptr;
					i++;
					*(tmpbuf+i) = NUL;
				}
				else {
					if (i > 0) {
						_dos_write(outputh, tmpbuf, i, &dmy);
					}
					_dos_write(outputh, rptr, 1, &dmy);
					i = 0;
				}
			}

			if (*rptr == LF) {
				ix = 1L;
				iy++;
				quote = 0;
			}
			else {
				ix++;
			}

		}
		if (sameflg != -1) {

			if ( i - (far_strlen(exold[sameflg]) - 1) > 0) {
				_dos_write(outputh, tmpbuf,
						i - (far_strlen(exold[sameflg]) - 1), &dmy);
			}

			if (exnew[sameflg] != NUL) {
				_dos_write(outputh, exnew[sameflg], far_strlen(exnew[sameflg]), &dmy);
			}
			exptr[sameflg] = exold[sameflg];
			exattrptr[sameflg] = exattr[sameflg];
			i = 0;
			extime++;
			if (viewmode > 1) fprintf(stderr, "%ld\r", extime);
		}
		else if (i > 0) {
			_dos_write(outputh, tmpbuf, i, &dmy);
		}
		i = 0;
	}
	if (viewmode>0) {
		fprintf(stderr, "%ldtime(s) exchanged!\n", extime);
	}

	bufclose();
	farfree(tmpbuf);
	for (j = 0; j < exflg; j++) {
		farfree(exattr[j]);
	}
}

void exchangedriver()
{
	if (viewmode > 1)
		fprintf(stderr, "TXF Super exchange module.(Parallel)\n");

	if (exold[0] != NULL) {
		exchange();
	}
}
