/* --------------------
	vmail -- main.c

	Definitions of global variables, main switch.

	Copyright (C) J. Zobel, University of Melbourne, October 1987.
-------------------- */

#include "defs.h"

folder	folders = (folder) NULL, curflr, alternate = (folder) NULL;
item	curmail;
char 	*user, *pager = (char *) NULL, *editor = (char *) NULL,
		*mail_dir = (char *) NULL, *shell = (char *) NULL, *context;
bool	top_level = true, do_flush = true, comp_args = true, repl_args = true,
		forw_args = true;
int		lines, cols, y, folder_protect = FPROT;
jmp_buf	env;

#define HELP		37

char *help_scr[] = {
"       .                Re-execute last command (if one of acdDefirR)",
"                                   (on repeat, r does not prompt for folder)",
"       /<exp>           Search forwards for title with <exp> (/ to repeat)",
"       ?<exp>           Search backwards for title with <exp> (? to repeat)",
"       <space>          Show current mail item",
"       [n]<return>      Go forward one (or n) active page(s) of mail items",
"       [n]<backspace>   Go back one (or n) active page(s) of mail items",
"       ^L               Refresh",
"       !                Invoke shell",
"       |                Pipe current mail item into command",
"       ^                Go to first active page",
"       $                Go to last active page",
"       a                Answer current mail item (call to \"repl\")",
"       c                Compose new mail item (call to \"comp\")",
"       C                Go to folder chooser",
"       [n]d             Delete current (or next inclusive n) mail item(s)",
"       D                Delete current mail item, show next",
"       e                Edit current mail item",
"       f                Forward current mail item (call to \"forw\")",
"       F                List all folders",
"       g,G              Go to named (or alternate) folder",
"       h                Show this page",
"       [n]H             Go to top of page (or nth from top line)",
"       i                Incorporate new mail (call to \"inc\")",
"       [n]j or CTRL-N   Move cursor down one (or n) line(s)",
"       [n]k or CTRL-P   Move cursor up one (or n) line(s)",
"       [n]L             Go to bottom of page (or nth from bottom line)",
"       M                Go to middle of page",
"       [n]n             Go forward one (or n) folders, make new folder active",
"       [n]p             Go back one (or n) folders, make new folder active",
"       P                Print name of alternate folder",
"       q                Exit from vmail",
"       r,R              Refile item in named (or previous) folder",
"       s                Save current item in named file",
"       u                Undo most recent deletion (1 mail item only)",
"       v                Make current folder inactive",
"       z                Pack current folder"
};


#define USAGE	printf( \
"Usage: vmail [-inc] [-flush] [-comp] [-forw] [-ans] [+curfolder] folders ...\n"), \
				exit(1)

main(argc, argv)
	int		argc;
	char	*argv[];
{
	char	c, last = '\0', get_number(), flushin();
	int		count = 1,		/* accumulate count to give to command */
			pcount = 1;
	bool	flag = false;	/* used to check whether to reset count */
	int	lose;

	argc--, argv++;

	process_args(argc, argv);
#ifndef VERSION
#define VERSION	"(local version)"
#endif
	printf("vmail %s -- reading mail headers\n", VERSION);
	init(argc, argv);
	setjmp(env);		/* return point from interrupt */
	c = flushin();
	for(;;) {
		while(c == '.')
			if(last == '\0') {
				beep();
				c = flushin();
			} else {
				count = pcount;
				c = last;
			}
		switch(c) {
			case 27: 	/* espace sequence */
				lose = 0;

				c = flushin();
				if (c == '[') {
					c = flushin();
					switch(c) {
						case 'A':
							cursor_up(count);
							break;				
						case 'B':
							cursor_down(count);
							break;
						default:
							lose = 1;
						break;
					}
				}
				else
					lose = 1;
				if (lose) {
					fflush(stdin);
					addstatus("command unknown -- `h' for help", true);
				}
				break;
			case '|':	/* pipe mail to command */
				do_pipe();
				break;
			case '!':	/* call shell */
				call_shell();
				break;
			case '/':	/* search forwards */
				search(true);
				break;
			case '?':	/* search backwards */
				search(false);
				break;
			case '^':	/* first active page */
				goto_first_page();
				break;
			case '$':	/* last active page */
				goto_last_page();
				break;
			case '\n':	/* next folder */
			case '\r':	/* next folder */
				next_page(count, true);
				break;
			case ' ':	/* show current item */
				show_mail();
				break;
			case DEL:	/* previous folder */
			case '\b':	/* previous folder */
				prev_page(count, true);
				break;
			case 'a':	/* answer - call to repl */
				repl();
				break;
			case 'c':	/* compose - fork of comp */
				comp();
				break;
			case 'C':	/* go to folder chooser */
				choose();
				break;
			case 'd':	/* delete item */
				delete_item(count);
				break;
			case 'D':	/* delete item, show next */
				change_item(false);
				show_mail();
				break;
			case 'e':	/* edit current mail item */
				edit();
				break;
			case 'f':	/* forward - call to forw */
				forw();
				break;
			case 'F':	/* list all folders */
				list_folders();
				break;
			case 'g':	/* go to named folder */
				goto_folder(true);
				break;
			case 'G':	/* go to last-named folder */
				goto_folder(false);
				break;
			case 'h':	/* help */
				help();
				break;
			case 'H':	/* go to top of page */
				cursor_first(count);
				break;
			case 'i':	/* inc */
				inc();
				break;
			case 'j':	/* cursor down */
			case 14:
				cursor_down(count);
				break;
			case 'k':	/* cursor up */
			case 16:
				cursor_up(count);
				break;
			case CTRL_L: /* redraw */
				display_page();
				break;
			case 'L':	/* go to bottom of page */
				cursor_last(count);
				break;
			case 'M':	/* go to middle of page */
				cursor_middle();
				break;
			case 'n':	/* next folder - load if not there */
				goto_next_folder(count);
				break;
			case 'p':	/* prev folder - load if not there */
				goto_prev_folder(count);
				break;
			case 'P':	/* print name of last-named folder */
				show_folder();
				break;
			case 'q':	/* quit */
				to_normal();
				fix_mh();
				exit(0);
				break;
			case 'r':	/* move item to named folder */
				move_item(true);
				break;
			case 'R':	/* move item to previous folder */
				move_item(false);
				break;
			case 's':	/* save item in named file */
				save_item();
				break;
			case 'u':	/* undo */
				undo();
				break;
			case 'v':	/* make folder inactive */
				inactive();
				break;
			case 'z':	/* pack current folder */
				pack_folder();
				break;
			case '0':	/* start of count */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				c = get_number(c, &count);
				flag = true;
				break;
			default:
				addstatus("command unknown -- `h' for help", true);
				break;
		}
		switch(c) {
				/* repeatable commands */
			case 'r':	/* refile item in named folder */
				last = 'R';
				pcount = 1;
				break;
			case 'a':	/* reply - call to repl */
			case 'c':	/* compose - fork of comp */
			case 'd':	/* delete item */
			case 'D':	/* delete item, show next */
			case 'e':	/* edit current mail item */
			case 'f':	/* forward - call to forw */
			case 'i':	/* inc */
			case 'R':	/* refile to previous folder */
			case 'w':	/* write to file */
				last = c;
				pcount = count;
				break;
			default:
				break;
		}
		if(!flag) {
			c = flushin();
			count = 1;
		} else {
			flag = false;
		}
	}
}


/* --------------------
	Read a number from terminal.
-------------------- */
char
get_number(c, count)
	char	c;
	int		*count;
{
	*count = c - '0';
	while((c = getchar()) >= '0' && c <= '9')
		*count = *count * 10 + c - '0';
	return(c);
}


WINDOW *helpwin = (WINDOW *) NULL;

/* --------------------
	Display help messages on help screen.
-------------------- */
help()
{
	WINDOW	*newwin();
	int		i, j;

	if(helpwin == (WINDOW *) NULL)
		helpwin = newwin(0, 0, 0, 0);
	wclear(helpwin);
	for(j=i=0 ; i <= HELP ; i++, j++) {
		if((i+2) % lines == 0) {
			if(use_prompt(helpwin) == 'q')
				break;
			j=0;
			wclear(helpwin);
		}
		if(i >= HELP) {
			use_prompt(helpwin);
			break;
		}
		mvwaddstr(helpwin, j+1, 0, help_scr[i]);
	}
	display_page();
}


/* --------------------
	Process arguments, command-line or given in profile.
-------------------- */
void
process_args(argc, argv)
	int argc;
	char *argv[];
{
	for( ; argc > 0 ; argc--, argv++)
		if(!strcmp(argv[0], "-inc")) {	/* incorporate mail before starting */
			if(!vfork()) {
				execlp(INC, INC, 0);
				printf("Warning: can't execute %s\n", INC);
				exit(0);
			}
			wait(0);
			printf("\n");
		} else if(!strcmp(argv[0], "-flush"))	/* don't flush typeahead */
			do_flush = false;
		else if(!strcmp(argv[0], "-forw"))		/* no args to forw */
			forw_args = false;
		else if(!strcmp(argv[0], "-comp"))		/* no args to comp */
			comp_args = false;
		else if(!strcmp(argv[0], "-ans"))		/* no args to repl */
			repl_args = false;
		else if(*argv[0] == '-') {
			printf("%s: illegal option\n", argv[0]);
			USAGE;
		}
}
