/*
 * Mainline 
 */
#include	"no_macro.h"
#include	"no_dprompt.h"
#include	"no_startup.h"
#include	"no_dir.h"

#include	"def.h"
#include	"buffer.h"
#include	"window.h"
#ifndef NO_MACRO
#include	"macro.h"
#endif

#ifdef	ANSI
#include <stdlib.h>
#endif

int             thisflag;	/* Flags, this command		 */
int             lastflag;	/* Flags, last command		 */
int             curgoal;	/* Goal column			 */
struct buffer  *curbp;		/* Current buffer		 */
struct window  *curwp;		/* Current window		 */
struct buffer  *bheadp;		/* BUFFER listhead		 */
struct window  *wheadp = NULL;	/* WINDOW listhead		 */
char            pat[NPAT];	/* Pattern			 */
#ifndef NO_DPROMPT
extern char     prompt[], *promptp;	/* delayed prompting		 */
#endif

static VOID edinit 
PROTO((void));

#ifndef NO_PROTO
VOID main
PROTO((int, char **));
#endif

VOID
main(argc, argv)
	int             argc;
	char          **argv;
{
#ifndef NO_STARTUP
	char           *startupfile();
#endif
	char           *cp;
	VOID            vtinit(), makename(), eerase();
	struct buffer  *findbuffer();

#ifdef SYSINIT
	SYSINIT;		/* system dependent.	 */
#endif
	vtinit();		/* Virtual terminal.	 */
#ifndef NO_DIR
	dirinit();		/* Get current directory */
#endif
	edinit();		/* Buffers, windows.	 */
	ttykeymapinit();	/* Symbols, bindings.	 */
	/*
	 * doing update() before reading files causes the error messages from
	 * the file I/O show up on the screen.	(and also an extra display of
	 * the mode line if there are files specified on the command line.) 
	 */
	update();
#ifndef NO_STARTUP		/* User startup file.	 */
	if ((cp = startupfile()) != NULL)
		(VOID) load(cp);
#endif
	while (--argc > 0) {
		cp = adjustname(*++argv);
		curbp = findbuffer(cp);
		(VOID) showbuffer(curbp, curwp, 0);
		(VOID) readin(cp);
	}
	thisflag = 0;		/* Fake last flags.	 */
	/*
	 * Note: A second version of this loop basically occurs in runmacro
	 * (mg/macro.c). If you change this loop, you should double-check
	 * that loop to see if the changes need to be reflected therein, as
	 * well. 
	 */
	for (;;) {
#ifndef NO_DPROMPT
		*(promptp = prompt) = '\0';
#endif
		if (epresf == ERASE)
			eerase();
		else if (epresf)
			epresf = ERASE;
		update();
		lastflag = thisflag;
		thisflag = 0;
		switch (doin()) {
		case TRUE:
			break;
		case ABORT:
			ewprintf("Quit");	/* and fall through	 */
		case FALSE:
		default:
			ttbeep();
#ifndef NO_MACRO
			if (macrodef)
				restore_macro();
			macrodef = FALSE;
#endif
		}
	}
}

/*
 * Initialize default buffer and window. Also fix the kbdmacro.
 */
static          VOID
edinit()
{
	register struct buffer *bp;
	register struct window *wp;
#ifndef	NO_MACRO
	extern struct macro	kbdmacro;

	kbdmacro.m_name = "";	/* If only everyone had ANSI compilers */
#endif
	bheadp = NULL;
	bp = bfind("*scratch*", TRUE);	/* Text buffer.		 */
	wp = (struct window *) malloc(sizeof(struct window));	/* Initial window.	 */
	if (bp == NULL || wp == NULL)
		panic("edinit");
	curbp = bp;		/* Current ones.	 */
	wheadp = wp;
	curwp = wp;
	wp->w_wndp = NULL;	/* Initialize window.	 */
	wp->w_bufp = bp;
	bp->b_nwnd = 1;		/* Displayed.		 */
	wp->w_linep = wp->w_dotp = bp->b_linep;
	wp->w_doto = 0;
	wp->w_markp = NULL;
	wp->w_marko = 0;
	wp->w_toprow = 0;
	wp->w_ntrows = nrow - 2;/* 2 = mode, echo.	 */
	wp->w_force = 0;
	wp->w_flag = WFMODE | WFHARD;	/* Full.		 */
}

/*
 * Quit command. If an argument, always quit. Otherwise confirm if a buffer
 * has been changed and not written out. Normally bound to "C-X C-C". 
 */
/* ARGSUSED */
quit(f, n)
{
	register int    s;
	VOID            vttidy();

	if ((s = anycb(FALSE)) == ABORT)
		return ABORT;
	if (s == FALSE
	    || eyesno("Some modified buffers exist, really exit") == TRUE) {
		vttidy();
#ifdef	SYSCLEANUP
		SYSCLEANUP;
#endif
		exit(GOOD);
	}
	return TRUE;
}

/*
 * User abort. Should be called by any input routine that sees a C-g to abort
 * whatever C-g is aborting these days. Currently does nothing. 
 */
/* ARGSUSED */
ctrlg(f, n)
{
	return ABORT;
}
