#include "fidoterm.h"
#include "mem.h"
#include <filexfer.h>

/*
	Various FidoTerm menu & screen functions

char *input(prompt,message)
char inputc(prompt,message);
	Displays a prompt and message on the command line, unhighlighted.
	The prompt is left justified with the cursor after it; the message
	is right justified. This returns a pointer to inputted text, or
	a single character.

ask(q)
	Display the question, get Y or N for an answer, return true if Y.

askesc(q)
	Display the question, get Y or N for an answer, return true if Y.
	If ESCape is hit, then it asks to abort the script.

msg(s)
	Display a formatted message on the command line, highlighted. Will
	accept standard printf() type inputs. After 30 seconds this message
	is replaced with the standard banner.

cmdpoll()
	Performs the background command line maintenance such as putting 
	up the standard banner when a message times out. Should be called
	often.

dspline(s)
	Just outputs the line to the bottom line of the screen.

gchar()
	Returns one character from the keyboard. 

getstr()
	Input a line of text with local editing. Returns a pointer to
	the inputted text.
*/

char *getstr();

static char cmd_line[SS + 1];			/* last cmd line message */
static char msgflg = 0;

static int last_par = -1;			/* for onscreen parity */
static char last_sec = -1;			/* for onscreen clock */
static char last_prot = -1;			/* for onscreen protocol */
static unsigned last_rate = -1;			/* last-set baud rate */
static int last_savfile = 12345;		/* capture file handle */


/* Display a prompt, prompt message, and input a command. The prompt goes
on the left edge of the bottom line, the message on the right edge; the cursor
is placed right after the prompt string. */

char *input(prompt,message)
char *prompt,*message;
{
char *cp;

	inpsetup(prompt,message);		/* present the question, */
	cp= getstr();				/* input some text */
	cmd_timer= -200L;			/* clear it soon */
	return(skip_delim(cp));			/* return the text */
}

/* Character input. */

inputc(prompt,message)
char *prompt,*message;
{
char c;

	inpsetup(prompt,message);		/* ask the question, */
	c= gchar();				/* get the response, */
	cmd_timer= -200L;			/* clear it soon */
	return(tolower(c));			/* return the character */
}

/* Setup for input. */

inpsetup(prompt,message)
char *prompt,*message;
{
int i,l;
char buff[SS];

	msgflg= 1;				/* disable clock */
	w_unhighlight(&status);			/* restore attributes */
	sprintf(buff,"\001%s",message);		/* right-justified message */
	w_fill(&status,buff); 			/* clear and write */
	w_pos(&status,0,0);			/* at start of line */
	w_printf(&status,"%s: ",prompt);	/* display prompt */
}

/* Ask a Yes or No question. */

ask(q)
char *q;
{
char c;
char ques[SS];

	strcpy(ques,q);				/* add a question mark */
	strcat(ques,"?");
	while (1) {
		c= inputc("ANSWER Y,N",ques);	/* accept only Y or N */
		if (c == 'n') return(0);
		if (c == 'y') return(1);
	}
}

/* Ask a Yes or No question; ESCape asks to abort the script. */

askesc(q)
char *q;
{
char c;
char ques[SS];

	strcpy(ques,q);				/* add a question mark */
	strcat(ques,"?");
	while (1) {
		c= inputc("ANSWER Y,N",ques);	/* accept only Y or N */
		if (c == 'n') return(0);
		if (c == 'y') return(1);
		script_abort(c);		/* check script abort */
	}
}

/* Display the default banner; all this does is set the command-line timer
very short so that it will be displayed normally. */

signon() {
	cmd_timer= -200L;			/* make it display banner soon */
	msgflg= 1;				/* arm it */
}

/* Display a message on the screen, make it go away in 30 seconds. If
the given string is blank, simply re-display the previous message. */

msg(s)
char *s;
{
char buff[SS];

	if (*s) {
		_spr(buff,&s);				/* format it, */
		strcpy(cmd_line,buff);			/* remember it, */
	}
	w_unhighlight(&status);				/* restore window attribs */
	dspline(cmd_line);				/* display it */
	cmd_timer= -10000L;				/* clear it in 20 secs */
	msgflg= 1;					/* start it */
}

/* Displays the standard banner when the command line message timer goes
out. */

cmdpoll() {

	if (!isscript() && msgflg && (cmd_timer > 0L)) {
		msgflg= 0;				/* disable it */
/*		w_dim(&status);		*/		/* status line is dim */
		w_pos(&status,0,0);
		w_string(&status,"ESC for commands");
		w_clreol(&status);
		last_sec= last_rate= -1;		/* force redisplay */
	}
}

/* Display a string centered in the command line. */

dspline(s)
char *s;
{
int i,n,l;
char buff[SS];

	l= strlen(s);					/* how long it is, */
	if (l >= status.cols) l= status.cols - 1;	/* be real */
	n= (status.cols / 2) - (l / 2) - 1;
	w_pos(&status,0,0);
	w_clreol(&status);				/* clear status line */
	w_pos(&status,0,n);				/* position cursor */
	w_string(&status,s); 				/* write the msg */
}

/* Get a character from the keyboard. This performs pseudo-background
modem --> screen polling except during protocol. */

static gchar() {
char c;

	w_cursor(&status);			/* enable the cursor */
	while (1) {
		c= scriptcmd();			/* check script-command */
		if (! c) c= keyhit();		/* then keyboard */
		if (c && (c < 128)) break;	/* (got one) (ignore Fkeys here) */

		if (! bglockout) {
			put_console(get_modem()); /* echo characters */
			w_cursor(&status);	/* (re-)position cursor */
		}
	}
	return(c);
}

/* Get an input string; return NULL if error or empty line. Provide the
usual minimum editing capabilities. */

#define LINELEN 40
char line_buff[LINELEN + 1];			/* local input buffer */

char *getstr() {
int count;
int b,c;

	count= 0;
	while (1) {
		c= gchar();			/* get one character, */
		if (c == cmdchar) break;	/* end of line */
		if (c == CR) break;		/* end of line */

		switch (c) {
			case BS:
			case DEL:			/* delete character */
			case XOF:
				c= count ? 1 : 0;	/* chars to backspace */
backspace:;			while (c--) {
					--count;	/* one less char, */
					--status.col;
					w_char(&status,' ');
					--status.col;
				}
				break;

			case VT:
			case CAN:
			case ETX:
			case NAK:			/* delete line */
			case EM:
				c= count; goto backspace;

			default:				/* insert character */
				if (c < ' ') c= NUL;		/* no control chars */
				if (count >= LINELEN) c= NUL;	/* too many */
				if (! c) break;

				line_buff[count++]= c;		/* add new char */
				w_char(&status,c);
				break;
		}
	}
	line_buff[count]= NUL;		/* terminate buff, */
	return(line_buff);		/* return ptr to the line */
}

/* Display the clock in the lower right hand corner when the 
default banner is up. */

clkpoll() {
char h,m,s;
char *cp,buff[SS],buff2[SS];
char *protocolname();

	if (msgflg) return;				/* not if msg up */

	s= gtod3(6);					/* see if clock changed */
	if (s == last_sec) return;			/* nope */
	last_sec= s;					/* it did, remember new clock */

	m= gtod3(5);
	h= gtod3(4);

	w_pos(&status,0,70);				/* display clock */
	w_printf(&status,"%02d:%02d:%02d",h,m,s);

	w_pos(&status,0,79);				/* display clock */
	w_string(&status,(cd(cd_bit) ? "\030" : "\031"));	/* wimpy CD indicator */

	if ((last_par == parflg) && 
	    (last_rate == rate) && 
	    (last_prot == filemode) &&
	    (last_savfile == savfile))
		return;

	last_par= parflg; last_rate= rate; 
	last_prot= filemode; last_savfile= savfile;

	switch (parflg) {
		case NOPAR: h= 'N'; break;
		case ZERPAR: h= 'Z'; break;
		case ODDPAR: h= 'O'; break;
		case EVNPAR: h= 'E'; break;
	}
	buff2[0]= NUL;				/* where it goes */
	if (savfile != -1) {
		cp= captname;			/* ptr to name to display */
		strcpy(buff2," ù Capt:");
		if ((m= strlen(cp)) > 15) {	/* if too long */
			cp += (m - 16);		/* truncate to fit */
			strcat(buff2,"...");	/* indicate truncation */
		}
		strcat(buff2,cp);		/* name or partial name */
		strcat(buff2," ù ");
	}		
	sprintf(buff,"%s%,u ù %s ù %c ù ",
	    buff2,				/* capture info */
	    rate,				/* baud rate */
	    protocolname(filemode),		/* protocol name */
	    h					/* parity */
	);
	w_pos(&status,0,70 - strlen(buff));
	w_string(&status,buff);
}

