#include "medisp.h"
/*
 * Erase the message line.
 * This is a special routine because
 * the message line is not considered to be
 * part of the virtual screen. It always works
 * immediately; the terminal buffer is flushed
 * via a call to the flusher.
 */
mlerase()
{
	movecursor(23, 0);
	ansieeol();
	mpresf = FALSE;
}

/*
 * Ask a yes or no question in
 * the message line. Return either TRUE,
 * FALSE, or ABORT. The ABORT status is returned
 * if the user bumps out of the question with
 * a ^G. Used any time a confirmation is
 * required.
 */
mlyesno(prompt)
char	*prompt;
{
	register int	s;
	char	buf[64];

	strcpy(buf, prompt);
	strcat(buf, " [y/n]? ");
	s = mlreply(buf, buf, sizeof(buf));
	if ( s == ABORT ) return (ABORT);
	if ( s != FALSE && ( buf[0] == 'y' || buf[0] == 'Y' ))
		return ( 1 );
	return ( 0 );
}

/*
 * Write a prompt into the message
 * line, then read back a response. Keep
 * track of the physical position of the cursor.
 * If we are in a keyboard macro throw the prompt
 * away, and return the remembered response. This
 * lets macros run at full speed. The reply is
 * always terminated by a carriage return. Handle
 * erase, kill, and abort keys.
 */
mlreply(prompt, buf, nbuf)
char	*prompt;
char	*buf;
{
	register int	cpos;
	register int	c;

	cpos = 0;
	mlwrite(prompt);
	for (;;)
	{	switch ( c = getstroke())
		{
		case 0x0D:			/* Return, end of line	*/
			buf[cpos++] = 0;
			conout( '\r' );
			ttcol = 0;
			if (buf[0] == 0)
				return (FALSE);
			return (TRUE);

		case 0x07:			/* Bell, abort		*/
			conout( '^' );
			conout( 'G' );
			ttcol += 2;
			ctrlg();
			return (ABORT);

		case 0x7F:			/* Rubout, erase	*/
		case 0x08:			/* Backspace, erase	*/
			if (cpos != 0)
			{	crtbs();
				if (buf[--cpos] < 0x20)
				{	crtbs();
				}
			}
			break;
#ifdef NEVER
		case 0x15:			/* C-U, kill		*/
			while (cpos != 0)
			{	crtbs();
				if (buf[--cpos] < 0x20)
				{	crtbs();
				}
			}
			break;
#endif
		default:
			if (cpos < nbuf-1)
			{	buf[cpos++] = c;
				if (c < ' ')
				{	conout( '^' );
					++ttcol;
					c ^= 0x40;
				}
				conout( c );
				++ttcol;
			}
		}
	}
}
crtbs()
{	conout( '\b' );
	conout( ' '  );
	conout( '\b' );
	--ttcol;
}
conout( c )
{	bios( 4, c );
}
/*
 * Write a message into the message
 * line. Keep track of the physical cursor
 * position. A small class of printf like format
 * items is handled. Assumes the stack grows
 * down; this assumption is made by the "++"
 * in the argument scan loop. Set the "message
 * line" flag TRUE.
 */
mlwrite(fmt, arg)
char	*fmt;
{
	register int	c;
	register char	*ap;

	movecursor(23, 0);
	ap = (char *) &arg;
	while ((c = *fmt++) != 0)
	{	if (c != '%') goto out_it;
		c = *fmt++;
		switch (c)
		{	case 'd':
				mlputi(*(int *)ap, 10);
				ap += sizeof(int);
				break;

#ifdef NEVER
			case 'o':
				mlputi(*(int *)ap,  8);
				ap += sizeof(int);
				break;

			case 'x':
				mlputi(*(int *)ap, 16);
				ap += sizeof(int);
				break;

			case 'D':
				mlputli(*(long *)ap, 10);
				ap += sizeof(long);
				break;
#endif
			case 's':
				mlputs(*(char **)ap);
				ap += sizeof(char *);
				break;

			default:
out_it:				conout( c );
				++ttcol;
		}
	}
	ansieeol();
	mpresf = TRUE;
}

/*
 * Write out a string.
 * Update the physical cursor position.
 * This assumes that the characters in the
 * string all have width "1"; if this is
 * not the case things will get screwed up
 * a little.
 */
mlputs(s)
char	*s;
{
	register int	c;

	while ((c = *s++) != 0)
	{	conout( c );
		++ttcol;
	}
}

/*
 * Write out an integer, in
 * the specified radix. Update the physical
 * cursor position. This will not handle any
 * negative numbers; maybe it should.
 */
mlputi(i, r)
{
	register int	q;
	static char hexdigits[] = "0123456789ABCDEF";

	if (i < 0)
	{	i = -i;
		conout( '-');
	}
	q = i/r;
	if (q != 0) mlputi(q, r);
	conout( hexdigits[i%r]);
	++ttcol;
}
#ifdef NEVER
/*
 * do the same except as a long integer.
 */
mlputli(l, r)
long l;
{
	register long q;

	if (l < 0)
	{	l = -l;
		conout( '-');
	}
	q = l/r;
	if (q != 0) mlputli(q, r);
	conout( (int)(l%r)+'0');
	++ttcol;
}
#endif

