#include <puppy.h>
#include <pupmem.h>
#include <ascii.h>

/*
	Puppy's Main Section. 

This handles one caller then returns. This source contains the
command prompt and the message base commands below it.

*/

puppy() {
char *cp;

	limit= pup.nlimit;
	klimit= pup.klimit;			/* set limits */

	clr_clk();				/* start counting */
	lmtstate= 0;				/* initialize the warning msg */
	*name= NUL;				/* dont know their name */

	set_abort(0);				/* set carrier loss trap */
	if (was_abort()) {			/* return to main */
		printf("\r\n\r\n");
		closemsg();			/* close the message base, */
		putsys();			/* write system file */
		close_up();			/* close aborted files */
		return(0);			/* not TSYNC */
	}
	openmsg();			/* open message base, */

	mconflush();			/* flush interrupt buffers */
	cmdflush();			/* flush command buffers */

	nulls= 0;			/* no nulls, */
	width= 80; rows= 25;		/* std. screen */
	column= line= 0;		/* sync up "more" stuff, */
	mprintf("\r\nPup says: \"Hello!\"\r\n");
	hello(1);			/* first time stuff, */
	quote();			/* do a quotation */
	mprintf("\r\nYou are caller #%,lu\r\n\r\n",++pup.callers);

/* Now execute commands forever. */

	topic= -1;			/* default to all topics */
	msgnbr= 1;			/* first time through */

	while (1) {
		cp= getarg("Command: M)essages H)ello! D)ownload U)pload B)ye (?=help): ");
		switch (tolower(*cp)) {
			case 'm': msg_base(); break;
			case 'h': hello(0); break;
			case 'd': download(); break;
			case 'u': upload(); break;
			case 'b': goodbye(); break;
			case '?': dspfile("main.hlp"); break;
			case NUL: break;
			default:
				mprintf("eh?\r\n");
				cmdflush();
				break;
		}
	}
}

/* Just say Hello. */

hello(a)
int a;
{
struct _time t;
char hour,ampm;

	userset();			/* set screen width, */
	if (! a) a= ask("Want to see the \"Hello\" display again");
	if (a) dspfile("welcome.pup");

	gtod(&t);			/* get time, */
	mprintf("It is now: %d-%d-%d",t.day,t.month,t.year);

	hour= t.hour % 12; if (!hour) hour= 12;
	mprintf(", %d:%02d",hour,t.minute);
	if (t.hour >= 12) mputs("pm\r\n"); else mputs("am\r\n");

	mprintf("You have been on for %d minutes, %d left\r\n",minutes,limit - minutes);
}

/* Get user screen settings, etc */

userset() {
int n;

	n= atoi(getarg("How wide is your screen? (CR=80): "));
	if ((n >= 20) && (n <= 80)) width= n;
	else width= 80;

	n= atoi(getarg("How many lines on your screen? (CR=24): "));
	if ((n >= 4) && (n <= 66)) rows= n;
	else rows= 24;

	pause= ask("Pause every page");
}

/* Me, I disconnect from you. */

goodbye() {

	if (ask("Want to disconnect now")) logoff(0,1);
}

/*
	Message Base commands

*/

msg_base() {
char *cp;
FLAG again;
int n;

	while (1) {
		mputs("\r\n");
		if (ismsg(msgnbr,topic)) {		/* (msgnbr set elsewere) */
			listhdr(msgnbr);		/* display current message */
			n= line;			/* remember current line */
			again= ques("Read it? ");	/* ask the question, */
			mputs("\r");
			if (again) {			/* if it was Yes, */
				line= n;		/* keep header on screen */
				listmsg(msgnbr);	/* maybe read it */
			}
		}
		do {
			again= 0;			/* command error flag */
			cp= getarg("S)tart-Where T)opic F)ind E)nter Q)uit (?=help CR=Next-Msg): ");
			switch (tolower(*cp)) {
				case 't': topic= gettopic("What topic(s) you wanna see? (A=ALL)\r\n"); break;
				case 's': setmsg(); break;
				case NUL: nxtnbr(); break;
				case 'q': return;

				case 'f': again= !mfind(); break;
	
				case '?': again= 1; dspfile("message.hlp"); break;
				case 'e': again= 1; msend(); break;
				default: again= 1; mprintf("eh?\r\n"); break;
			}
		} while (again);
	}
}

/* Select a specific message. Message numbers run: 0 non-existent, 
1 is the top, 2 is "1 down from the top", etc. */

setmsg() {
char *cp;
int n;

	cp= getarg("Start how far down: (T=TOP) #");
	if (! *cp) return;			/* nothing entered */

	n= 0;					/* assume its garbage */
	if (tolower(*cp) == 't') n= 1;		/* T == top */
	else n= atoi(cp) + 1;			/* else a number, */

	if (n && ismsg(n,-1)) msgnbr= n;	/* check if a valid msg */
	else mprintf("\r\nNO SUCH MESSAGE\r\n");
}

/* Pick the next message number that exists and is in the right topic.
It sets 0 if the bottom of the pile is reached, and prevents 0 from 
"wrapping around" to 1. */

nxtnbr() {

	if (msgnbr) {
		while (++msgnbr < highmsg()) {
			if (ismsg(msgnbr,topic)) return(msgnbr);
		}
		msgnbr= 0;
	}
	mprintf("\r\nBOTTOM OF THE PILE\r\n");
	return(0);
}

/* Make the user select a topic; return the bit fields set. */

gettopic(prompt)
char *prompt;		/* initial prompt */
{
int n;
char *cp;
WORD topic;

	while (1) {
		if (! isargs()) {
			mputs(prompt); 			/* say what */
			for (n= 0; n < 16; n++) {	/* list them all, */
				if (*pup.topic[n].name) 
					mprintf("#%d %-8s %s\r\n",n + 1,pup.topic[n].name,pup.topic[n].desc);
			}
		}
		topic= 0;				/* start with this */
		cp= getarg("Choose topic #");		/* ask for them, */
		while (*cp) {				/* check each one */
			if (tolower(*cp) == 'a') topic |= -1;
			n= atoi(cp);			/* ALL or a number */	
			if ((n > 0) && (n < 16)) {	/* if in range, */
				--n;
				if (*pup.topic[n].name) topic |= (1 << n);
			}
			cp= next_arg(cp);		/* ptr to next arg (if any) */
		}
		cmdflush();				/* pitch input line we just ate */
		if (topic) return(topic);		/* return 'em when we get 'em */
	}	
}

/* Search the message base for content. Return true if the thing was found. */

mfind() {
char pattern[SS];
struct _msg *m;

char *strfnd();

	while (1) {
		cpyarg(pattern,getarg("Find what? (CR=Quit, ?=Help): "));
		if (*pattern == '?') dspfile("find.hlp"); /* ? is help */
		else if (! *pattern) return(0);		/* just a CR */
		else break;				/* anything else */
	}
	mputs("Wait ... (Control-C to abort)\r\n");
	while (nxtnbr()) {				/* find a message, */
		pollkbd();				/* check the keyboard */
		if (abort) break;			/* allow stopping */
		m= getmsg(msgnbr);			/* get this msg */
		if (strfnd(m-> to,pattern)) return(1);	/* check each field */
		if (strfnd(m-> from,pattern)) return(1);
		if (strfnd(m-> subj,pattern)) return(1);
		loadmsg(msgnbr);			/* get the msg body, */
		if (strfnd(text,pattern)) return(1);	/* search that */
	}
	return(0);
}

/* Edit-message commands. Returns true if the message should be saved. */

msend() {
int lineno;		/* last used line number */
char *cp;
int i;
struct _msg *msg;	/* ptr to new message */

	msg= newmsg();				/* ptr to our new message */
	gtod(&msg-> time);			/* get the current time, */
	while (! *name) {			/* if we dont have the guys name */
		cmdflush();			/* sorry, no command-ahead */
		input("I didn't get your name: ",name,sizeof(msg-> from));
		if (! *name) mprintf("\r\nAHEM: ");
	}
	strcpy(msg-> from,name);		/* set From: */
	mprintf("FROM: %s\r\n",name);
	input("TO: ",msg-> to,sizeof(msg-> to));
	if (! *msg-> to) return;
	msg-> topic= gettopic("Choose a TOPIC:\r\n");
	input("TITLE: ",msg-> subj,sizeof(msg-> subj));
	if (! *msg-> subj) return;

	cp= text; i= pup.msgsize;		/* clear out the text buffer */
	while (i--) *cp++= NUL;

	mprintf("Enter your message,\r\nControl-C or Control-K to end\r\n");
	lineno= edit(0);			/* get some new text */

	while (1) {
		cp= "\r\nEdit: C)ancel A)dd L)ist I)ns D)el S)ave (?=help): ";
		cp= getarg(cp);
		switch (tolower(*cp)) { 
			case '?': dspfile("edit.hlp"); break;
			case NUL: break;
			case 'c': if (ask("Cancel this message")) return(0); break;
			case 'a': lineno= edit(lineno); break;
			case 'l': listhdr(highmsg());
				for (i= 0; i < lineno; i++) {
					msgline(i);
					if (abort) break;
				}
				break;

			case 'i':
				i= getlno("Insert before line #",lineno);
				if (i < 0) break;
				lineno= edit(i);
				break;

			case 'd':
				i= getlno("Delete line #",lineno);
				if (i < 0) break;
				lineno= del_line(i,lineno);
				break;

			case 's':
				mprintf("Saving new message\r\n");
				savemsg(lineno);
				++msgnbr;		/* new top means all shift down */
				return(1);

			default:
				mprintf("eh?\r\n");
				cmdflush();
				break;
		}
	} 
}

/* Display a message line. */

msgline(n)
int n;
{
char *s;

	s= &text[n * width];			/* s == ptr to line to display */
	mprintf("%2u: ",n + 1);			/* display line number, */
	while (*s && !abort) {			/* until done or Control-K */
		if (*s >= ' ') mconout(*s);	/* output them */
		++s;
	}
	mputs("\r\n");
}

/* Get a line number; return -1 if invalid number. */

getlno(ps,lim)
char *ps;
int lim;
{
char *cp;
int n;

	n= atoi(getarg(ps)) - 1;		/* get one, (garbage becomes -1) */
	if (n >= lim) {
		mprintf("Must be 1 to %d\r\n",lim);
		n= -1;
	}
	return(n);
}
