/****** MENUTIL.C - the menu program utilities for Perfect Text Mangler

	(C) 1982, 1983 Perfect Software, Inc.

	01/26/82	Version 1.00 by Barry A. Dobyns

***********************************************************************/

#include "menu.gbl"
#define SEARCH_FIRST	17		/* BDOS calls */
#define SEARCH_NEXT	18
#define BASE	0

/*
Direct(drive)				/* do a directory */
char	drive;
{
#ifdef LATTICE
	char	dmapos;		/* value returned by search calls */
	char	first_time;	/* used in search routine */
	char	tmpfn[20];		/* temp filename buffer */
	char	fcb[36];
	int	cdisk;		/* current disk drive */
	int	colno;		/* column count */
	int	i;

	drive = ToUpper(drive);
	TClrWind();
	if(drive<'A' || drive>'P'){
		puts("\007Illegal Drive name\n");
		puts("<Type any character to continue>");
		TGetKb();
		return;
	}
	cdisk = bdos(25,0);	/* save current drive */
	bdos(14,drive-'A');
	printf("Directory for Drive %c:\n\n", drive);

	setfcb(fcb,"*.*");
	colno = 1;
	first_time = TRUE;
	while (1) {
		dmapos = bdos(first_time ? SEARCH_FIRST : SEARCH_NEXT,fcb);
		if (dmapos == 255) break;
		first_time = FALSE;
		hackname(tmpfn,(BASE + 0x80 + dmapos * 32));
		puts(tmpfn);
		for (i = strlen(tmpfn); i < 15; i++) putchar(' ');
		if ((colno += 15) > TMaxCol()-15)
		{
			putchar('\n');
			colno =1;
		}
	}
	bdos(14,cdisk);		/* reset to previous drive */
#endif LATTICE
	puts("\n\nHit any key to return to menu: ");
	TGetKb();
	return(1);		/* yes, redisplay needed */
}


char	*
hackname(dest,source)
char *dest, *source;
{
	int i,j;

	j = 0;

	for (i = 1; i < 9; i++)
	{
		if (source[i] == ' ') break;
		dest[j++] = source[i];
	}
	if (source[9] != ' ')
		dest[j++] = '.';

	for (i = 9; i < 12; i++)
	{
		if (source[i] == ' ') break;
		dest[j++] = source[i];
	}
	dest[j] = '\0';
	return dest;
}
*/

char	*
Copyright()
{
	return("Written and directed by Barry A. Dobyns.");
}

GetLineArg()
{
	int chrcnt, argcnt, curarg;

	for(curarg = 0; curarg < MAXARGS; curarg++)
		arglist[curarg]= 0;

	argcnt = curarg = 0;
	for(chrcnt = 0; chrcnt < LINMAX && linebuf[chrcnt]; chrcnt++){
		if(arglist[curarg] && !isspace(linebuf[chrcnt]))
			continue;
		else if(!isspace(linebuf[chrcnt])){
			arglist[curarg] = &linebuf[chrcnt];
			argcnt++;
		} else if(arglist[curarg]){
			linebuf[chrcnt] = '\0';
			curarg++;
		}
	}
	return(argcnt);
} /* end of GetLineArg */

#ifdef YINYANG
GetLine0()
{
	int cnt;

	for (cnt = 0; cnt < MAXARGS; ++cnt) {
		arglist[cnt]=0;
		for (tmp = 0; tmp < ARGLEN; ++tmp)
			strargs[cnt][tmp] = '\0';
	}

	sscanf(linebuf,
	"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s ",
	strargs[0], strargs[1], strargs[2], strargs[3],
	strargs[4], strargs[5], strargs[6], strargs[7],
	strargs[8], strargs[9], strargs[10], strargs[11],
	strargs[12], strargs[13], strargs[14], strargs[15],
	strargs[16], strargs[17], strargs[18], strargs[19]);
}/* end of GetLine0 */

GetLine1()
{
	for (cnt = 1; cnt < MAXARGS; ++cnt) {
		arglist[cnt]=0;
		for (tmp = 0; tmp < ARGLEN; ++tmp)
			strargs[cnt][tmp] = '\0';
	}

	sscanf(linebuf,
	"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s ",
	strargs[1], strargs[2], strargs[3],
	strargs[4], strargs[5], strargs[6], strargs[7],
	strargs[8], strargs[9], strargs[10], strargs[11],
	strargs[12], strargs[13], strargs[14], strargs[15],
	strargs[16], strargs[17], strargs[18], strargs[19]);
} /* end of GetLine1() */
#endif YINYANG

dspargs(loc)
int loc;
{
	int cnt;
	cnt = 0;
	TSetPoint(loc,0);
	TForce();
	do {
		printf("%s ",arglist[cnt]);
		cnt++;
	} while((cnt < MAXARGS) &&
	    (arglist[cnt] != 0) && (*arglist[cnt] != '\0'));
	fflush(stdout);
	TCLEOL();
	putchar('\n');
	fflush(stdout);
} /* end of dspargs() */


GoToIt(ptr)
char *ptr[MAXARGS];
{
	int cnt;
	char line[129];
	char adrive[30];

	strcpy(adrive,"A:");		/* set up to try on a: also */
	strcat(adrive,ptr[0]);		/* if the logged drive fails */

	TClrWind();			/* clear */
	TSetPoint(TMaxRow()-2,0);	/* and go to the bottom */
	TFini();			/* of the screen */

	line[0]=0;			/* initialize it */

	for(cnt = 0; cnt < MAXARGS; cnt++)
		if (*ptr[cnt] == '\0')
			ptr[cnt] = 0;

	for(cnt=1; (cnt < MAXARGS) && ptr[cnt] ; cnt++) {
		strcat(line,ptr[cnt]);
		strcat(line," ");
	}

	if(strlen(line) + strlen(adrive) > 127)
		NError(ptr[0],line);

	execl(ptr[0],line,0);		/* try both */
	execl(adrive,line,0);		/* logged and a: */
	LError(ptr[0],line);		/* failed */
} /*end of GoToIt() */

LError(com,arg)
char *com, *arg;
{
	TClrWind();
	TDisStr(0,0,"I Cannot execute this command string: ");
	TBell();
	TDisStr(2,0,com);
	TPrntStr(" ");
	TPrntStr(arg);
	TDisStr(4,0,"One of us must have made an error, so let's try again.");
	TDisStr(5,0,"Either the program you wish to execute is unavailable,");
	TDisStr(6,0,"or it is not on either the current drive or on the A:");
	TDisStr(7,0,"device. ");
	TDisStr(9,0,"<Type anything to continue>");
	TGetKb();
	TClrWind();
	puts("... Restarting Menu ...");
	exec("menu", (cur_doc == NULL ? "" : cur_doc));
				/* get a fresh menu in case this one got
				   munged somehow. this is safer than just
				   jumping back to the head of the TPA */
} /* end of LError() */

/*
**	Program initialization:
**	interpret the command line and init the buffer
*/
setup(argc, argv)
int	argc;
char	*argv[];
{
	if(argc > 1)
		cur_doc = argv[1];
	else
		cur_doc = NULL;
	TermInit();			/* Set up terminal */
}

ArgBotch()
{
	TDisStr((TMaxRow()-3),0,
	"Sorry, you can only specify this option once.");
	TDisStr((TMaxRow()-2),0, "<Type any character to continue>");
	TCLEOW();
	TGetKb();
}

ArgChk(ptr)
char *ptr;
{
	int cnt;

	for(cnt = 0; cnt <= nxtarg; cnt++){
		/*		echo(arglist[cnt]);
				TGetKb();
				echo(ptr);
				TGetKb();		*/
		if(!strcmp(arglist[cnt], ptr)){
			TDisStr((TMaxRow()-3),0,
			"This option cannot be used in conjunction with ");
			TPrntStr(ptr);
			TDisStr((TMaxRow()-2),0,
			"<Type any character to continue>");
			TCLEOW();
			TGetKb();
			return(TRUE);
		}
	}
	return(FALSE);
}

NError(com,arg)
char *com, *arg;
{
	TClrWind();
	TDisStr(0,0, "Perfect Writer Version ");
	TPrntStr(VERSION);
	TDisStr(1,0, "(C) 1982, 1983 Perfect Software, Inc.");
	TBell();
	TDisStr(3,(TMaxCol()/3),"<<<<<WARNING>>>>>");
	TDisStr(4,0,
	"You have specified more arguments or options than this menu system");
	TDisStr(5,0,
	"can deal with. If you really need to specify this many arguments or");
	TDisStr(6,0,
"options it will be advantageous for you to learn to execute programs from");
	TDisStr(7,0,
"the operating system rather than this menu. It will also be faster to");
	TDisStr(8,0,
"do so.  You should refer to the manual for instructions on how to use");
	TDisStr(9,0,
	"the components of Perfect Writer without this menu component.");
	TDisStr(11,0,"<This is the command line I cannot deal with:>");
	TDisStr(13,0,com);
	TPrntStr(" ");
	TPrntStr(arg);
	TDisStr((TMaxRow()-3),0,
	"<Type any character to continue>");
	TBell();
	TGetKb();
	TClrWind();
	puts("... Restarting Menu ...");
	/* just to make sure, we never know... ... */
	exec("menu", (cur_doc == NULL ? "" : cur_doc));
} /* end of NError(com,arg) */

ArgExists(ptr)
char *ptr;
{
	int cnt;

	for(cnt = 0; cnt <= nxtarg; cnt++){
		/*		echo(arglist[cnt]);
				TGetKb();
				echo(ptr);
				TGetKb();		*/
		if(!strcmp(arglist[cnt], ptr)){
			TDisStr((TMaxRow()-3),0,
			"You have already specified this option: ");
			TPrntStr(ptr);
			TDisStr((TMaxRow()-2),0,
			"<Type any character to continue>");
			TCLEOW();
			TGetKb();
			return(TRUE);
		}
	}
	return(FALSE);
}

ArgDgtChk(ptr)
char *ptr;
{
	for(; *ptr != '\0'; ptr++)
		if(!isdigit(*ptr)){
			TDisStr((TMaxRow()-3),0,
			"You must specify a number for this option ");
			TDisStr((TMaxRow()-2),0,
			"<Type any character to continue>");
			TCLEOW();
			TGetKb();
			return(FALSE);
		}
	return(TRUE);
}

char	*
Page()
{
	return("-page");
}

char	*
Port()
{
	return("-port");
}

char	*
Pause()
{
	return("-pause");
}

char	*
Typewriter()
{
	return("-typewriter");
}

#ifdef YINYANG
Text()
{
	return("-text");
}
#endif

char	*
Dev()
{
	return("-dev");
}

char	*
Alph(letter)
char letter;
{
	/* this returns a string based on the argument
			the string is suitable for use by execl */

	switch(tolower(letter)){
	case 'a': 
		return("-a");
	case 'b': 
		return("-b");
	case 'c': 
		return("-c");
	case 'd': 
		return("-d");
	case 'e': 
		return("-e");
	case 'f': 
		return("-f");
	case 'g': 
		return("-g");
	case 'h': 
		return("-h");
	case 'i': 
		return("-i");
	case 'j': 
		return("-j");
	case 'k': 
		return("-k");
	case 'l': 
		return("-l");
	case 'm': 
		return("-m");
	case 'n': 
		return("-n");
	case 'o': 
		return("-o");
	case 'p': 
		return("-p");
	case 'q': 
		return("-q");
	case 'r': 
		return("-r");
	case 's': 
		return("-s");
	case 't': 
		return("-t");
	case 'u': 
		return("-u");
	case 'v': 
		return("-v");
	case 'w': 
		return("-w");
	case 'x': 
		return("-x");
	case 'y': 
		return("-y");
	case 'z': 
		return("-z");
	default:	
		return(0);
	} /* end of switch(letter) */
}	/* end of Alph() */

GetArg(mesg,term,str,len)	/* input a string argument */
char *mesg, term, *str;
int len;
{
	char stemp[LINMAX], inpt, *nstr, tcol;

	TDisStr(TMaxRow()-2,0,mesg);
	TCLEOL();
	tcol=TGetCol();
	TForce();
	nstr=stemp;
	while ((inpt=TGetKb())!=term) {
		if (inpt==BELL) {
			ClrEcho();
			return(FALSE);
		}
		if (nstr-stemp>=len-1 && inpt!=DEL && inpt!=BS) {
			nstr=RubOut(stemp,nstr,tcol);
			TBell();
		}
		switch (inpt) {
		case CR:
			TPrntStr("<NL>");
			*nstr++=NL;
			break;
		case BS:
		case DEL:
			if (nstr>stemp) nstr=RubOut(stemp,nstr,tcol);
			break;
		case '\21':			/* ^Q */
			inpt=TGetKb();
		default:
			TPrntChar(inpt);
			*nstr++=inpt;
			break;
		}
		TForce();
	}
	if (nstr!=stemp) {
		*nstr='\0';
		strcpy(str,stemp);
	}
	else NLPrnt(str);
	TSetPoint(TMaxRow()-1,0);
	TForce();
	return(TRUE);
}

ClrEcho()				/* Clear the echo line */
{
	int trow, tcol;

	trow=TGetRow();
	tcol=TGetCol();
	TSetPoint(TMaxRow()-2,0);
	TCLEOL();
	TSetPoint(trow,tcol);
	TForce();
}

char	*
RubOut(ostr,str,tcol)	/* delete a character for getarg */
char *str, *ostr, tcol;
{
	*--str='\0';
	TSetPoint(TGetRow(),tcol);
	NLPrnt(ostr);
	TCLEOL();
	TForce();
	return(str);
}

NLPrnt(str)			/* print a string with "<NL>"'s */
char *str;
{
	while (*str)
		if (*str!=NL) TPrntChar(*str++);
		else {
			TPrntStr("<NL>");
			++str;
		}
	TForce();
}

#ifdef YINYANG
Echo(mesg)			/* Say something useful in the echo line */
char *mesg;
{
	TSetPoint(TMaxRow()-1,0);
	TCLEOL();			/* clear whatever was there */
	TPrntStr(mesg);			/* display the message */
	TForce();
}

getchar()				/* for safety */
{
	return(TGetKb());
}
#endif YINYANG

Error(mesg)			/* Display an error message */
char *mesg;
{
	int trow, tcol;

	trow=TGetRow();
	tcol=TGetCol();			/* Display the message */
	TDisStr(TMaxRow()-1,TMaxCol()-10-strlen(mesg),mesg);	
	TBell();			/* Ring the terminal bell */
	TForce();			/* go to end of message */
	TCLEOL();			/* clear rest of line */
	KbWait();			/* wait for character(s) */
	if (BELL==TGetKb()) arg=0;   	/* snarf up one character */
	TSetPoint(trow,tcol);		/* return to old place */
	TForce();			/* force it */
}

KbWait(){
}

/* end of menutil.c - the menu program utilities for Perfect Text Mangler */

dfltext(fn, ext)			/* default fn's extension to ext */
char *fn, *ext;
{
	while(*fn) if(*fn++ == '.') return;
	*fn++ = '.';
	strcpy(fn, ext);
}
