#include <stdio.h>
#include "dict.h"

#define sgn(x) ((x)<0 ? -1 : ((x)>0 ? 1 : 0))

char to[16];
char from[16];
int deep1,deep2;
char opt;
int interactive=1;

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

	if (argc>1) {
		interactive=0;
	}
	loaddict();

	if (interactive) printf("loaded dictionary.\n");

	if (interactive) {
		prompt();
		while (EOF!=scanf("%s %s",from,to)) {
			processwords();
			prompt();
		}
	} else {
		for (arg=1; arg+1<argc; arg+=2) {
			if (arg>1) printf("\n");
			strcpy(from,argv[arg]);
			strcpy(to,argv[arg+1]);
			processwords();
		}
	}
}

processwords()
{
	if (from[1])
		opt=' ';
	else
		opt=from[0];

	switch (opt) {
		case 'a':	AddWord(to,0);
	break;	case 'r':	RemoveWord(to,0);
	break;	default:	finddoublet();
	}
}

prompt(){printf("<from> <to> = ");}

char word[2][16384][8];
int	windex;
int	wset;
int	fulldepth;
int	found;

finddoublet()
{
	int wcount,w;

	wset=0;
	windex=0;
	found=0;

	strcpy(word[wset][windex++],to);

	if (opt!='+')
		cleardata(0);

	fulldepth=0;
	while (windex && !found) {
		fulldepth++;
		wset=1-wset;
		wcount=windex;
		windex=0;
		for (w=0; w<wcount; w++) {
			calcdata(word[1-wset][w],0,0,0);
		}
		if (interactive) printf("%d words found at depth %d.\n",windex,fulldepth);
		if (found) {
			if (interactive) printf("These included %s, found on this path:\n",from);

			windex=0;
			strcpy(word[wset][windex++],from);

			if (interactive)
				printf("%s ",from);
			else
				printf("%s\n",from);

			while (fulldepth) {
				fulldepth--;
				wset=1-wset;
/*
				wcount=windex;
*/
				wcount=1;

				windex=0;
				for (w=0; w<wcount; w++) {
					seekdata(word[1-wset][w],0,0,0);
				}
				if (windex) {
					windex=1;
					for (w=0; w<windex; w++) {
						if (interactive) {
							printf("%s ",word[wset][w]);
						} else {
							printf("%s\n",word[wset][w]);
						}
					}
				}
			}
			printf("%s\n",to);
		}
	}

	if (!found && interactive) {
		printf("At depth %d, %s reaches:\n",fulldepth-1,to);
		for (w=0; w<wcount; w++) {
			printf("%s ",word[1-wset][w]);
		}
		printf("\n\n");
		printf("Words unreachable from %s:\n",to);
		seeklone(to,0,0);
		printf("\n");
	}
}

char	traceword[9];

int calcdata(text,node,depth,chindex)

char text[];
long node;
int depth;
int chindex;
{
	int Last;
	long arc;
	char ch,l;

	ch=text[chindex];
	if (!ch) return;

	do {
		Last=IsLastArc(node);
		l=Letter(node);
		arc=Arc(node);

		if (l!=ch) depth++;

		traceword[chindex]=l;
		traceword[chindex+1]=0;

		if (depth==1 && !text[chindex+1] && IsWord(node) && Data(node)==0) {
			strcpy(word[wset][windex++],traceword);
			if (!strcmp(traceword,from)) found=1;
			SetData(node,fulldepth);
		}

		if (arc && depth<2) {
			calcdata(text,arc,depth,chindex+1);
		}

		if (l!=ch) depth--;

		node++;
	} while (!Last);
}
int seekdata(text,node,depth,chindex)

char text[];
long node;
int depth;
int chindex;
{
	int Last;
	long arc;
	int data;
	char ch,l;

	ch=text[chindex];
	if (!ch) return;

	do {
		Last=IsLastArc(node);
		l=Letter(node);
		arc=Arc(node);
		data=Data(node);

		if (l!=ch) depth++;

		traceword[chindex]=l;
		traceword[chindex+1]=0;

		if (depth==1 && IsWord(node) && !text[chindex+1]) {
			if (data==fulldepth) {
				strcpy(word[wset][windex++],traceword);
			}
		}
		if (arc && depth<2) {
			seekdata(text,arc,depth,chindex+1);
		}

		if (l!=ch) depth--;

		node++;
	} while (!Last);
}

int seeklone(text,node,chindex)

char text[];
long node;
int chindex;
{
	int Last;
	long arc;

	if (!text[chindex]) return;

	do {
		Last=IsLastArc(node);
		arc=Arc(node);

		traceword[chindex]=Letter(node);
		traceword[chindex+1]=0;

		if (Data(node)==0 && IsWord(node) && !text[chindex+1]) {
			printf("%s ",traceword);
		}
		if (arc) {
			seeklone(text,arc,chindex+1);
		}

		node++;
	} while (!Last);
}

