/* main.c - main editor code
 */

#include <string.h>
#include "terminal.h"
#include "editor.h"
#include "hook.h"

extern void ed_redraw__title(char *);
extern void ed_redraw__header(char *);
extern void ed_redraw__body(void);

extern long ed__block_line;
extern int menuview_exitup;


/* Edit "file", starting with the cursor at the end of line "pos". The top
 * line will show "title", the next a row of blue tildes (~), and if "header"
 * is non-zero this is what the next few lines will contain.
 *
 * Options are read from environment variable $EDITOR_OPTIONS and stored back
 * there afterwards.
 *
 * Returns 0 on success, 1 if the edit was aborted, or -1 on error.
 */
int ed_main(char *file, long pos, char *title, char *header)
{
	int finished = 0;
	int ctrl_o = 0;
	int oes;
	int c;

	ed__killbuf = 0;
	ed__newkill = 1;
	ed__block_line = -1;

	if (!header)
		header = "";
	if (ed_load(file))
		return (-1);		    /* load file into memory */

	ed_loadopts();			    /* read editor options */

	t_clear();			    /* clear screen */
	t_goto(0, t_rows - 1);		    /* clear bottom line too, just in case */
	t_clrtoeol();

	ed_redraw__title(title);
	ed_redraw__header(header);

	pos -= (t_rows - (ed__start_line + 2)) / 2 - 1;
	if (pos < 1)
		pos = 1;

	ed__topline = pos - 1;
	ed__curline = pos - 1;
	ed__curcol = 0;
	ed__curchar = 0;
	if ((pos < 2) && (ed__array[0])
	    && (!strncmp(ed__array[0], "Subject:", 8)))
		ed__curchar = strlen(ed__array[0]);
	ed__leftchar = 0;
	if (ed__curchar >= t_cols)
		ed__leftchar = ed__curchar;
	ed__redraw = 0;

	ed_redraw__body();

	while (!finished) {		    /* main loop */

		if (ed__redraw) {	    /* redraw whole screen if necessary */
			ed_redraw(title, header);
			ed__redraw = 0;
		}

		c = t_getchar(1);	    /* read keypress */

		bbs_hook(HOOK_KEY_PRESSED, 0, &c);

		if (menuview_exitup)
			finished = 2;	    /* external abort */

		t_checksize();		    /* check for terminal resize */

		if (ed__redraw) {
			ed_redraw(title, header);
			ed__redraw = 0;
		}

		if (!ctrl_o) {		    /* ^O not pressed previously */

			switch (c) {
			case 12:
				ed__redraw = 1;
				break;	    /* ^L = redraw screen */
			case KEY_LEFT:
			case 2:
				ed__op_left();
				break;	    /* ^B = left */
			case KEY_RIGHT:
			case 6:
				ed__op_right();
				break;	    /* ^F = right */
			case KEY_UP:
			case 16:
				ed__op_up();
				break;	    /* ^P = up */
			case KEY_DOWN:
			case 14:
				ed__op_down();
				break;	    /* ^N = down */
			case KEY_HOME:
			case 1:
				ed__op_home();
				break;	    /* ^A = home */
			case KEY_END:
			case 5:
				ed__op_end();
				break;	    /* ^E = end */
			case 23:
				ed__op_prevword();
				break;	    /* ^W = previous word */
			case 20:
				ed__op_nextword();
				break;	    /* ^T = next word */
			case KEY_PPAGE:
			case 21:	    /* ^U or */
			case 26:
				ed__op_prevscreen();
				break;	    /* ^Z = previous screen */
			case KEY_NPAGE:
			case 22:
				ed__op_nextscreen();
				break;	    /* ^V = next screen */
			case 127:	    /* ^? or */
			case 8:
				ed__op_del_left();
				break;	    /* ^H = delete left */
			case KEY_DC:
			case 4:
				ed__op_del_right();
				break;	    /* ^D = delete right */
			case 15:
				ctrl_o = 1;
				break;	    /* ^O = select options */
			case 24:
				ed__op_cutline();
				break;	    /* ^X = cut line */
			case 25:
				ed__op_paste();
				break;	    /* ^Y = paste */
			case 11:
				ed__op_cutforw();
				break;	    /* ^K = cut forwards */
			case 0:
			case 3:
			case -1:
				bbs_hook(HOOK_CHECK_MSGS, 0, 0);
				break;	    /* no key pressed */
			default:
				finished = ed__op_key(c);
				break;	    /* other key pressed */
			}

			if ((c != 24) && (c != 11))
				ed__newkill = 1;

		} else {		    /* ^O pressed previously */

			ctrl_o = 0;
			oes = ed__showhelp;
			ed__showhelp = 0;

			switch (c) {
			case 12:	    /* ^L = redraw screen */
				ed__redraw = 1;
				ctrl_o = 1;
				ed__showhelp = 1;
				break;
			case 15:
			case 'o':
			case 'O':
				ed__op_insert();
				break;	    /* ^O O = toggle insert mode */
			case 1:
			case 'a':
			case 'A':
				ed__op_indent();
				break;	    /* ^O A = toggle autoindent */
			case 23:
			case 'w':
			case 'W':
				ed__op_togwrap();
				break;	    /* ^O W = toggle word wrap */
			case 18:
			case 'r':
			case 'R':
				ed__op_margin();
				break;	    /* ^O R = set right margin */
			case 10:
			case 'j':
			case 'J':
				ed__op_wrap(0);
				break;	    /* ^O J = rejustify text */
			case 21:
			case 26:	    /* ^O ^U, ^Z, or */
			case KEY_UP:	    /* ^O UP, or */
			case KEY_PPAGE:    /* ^O PAGE UP, or */
			case 16:
				ed__op_top();
				break;	    /* ^O ^P = top of file */
			case 5:
			case 22:	    /* ^O ^E, ^V, or */
			case KEY_DOWN:	    /* ^O DOWN, or */
			case KEY_NPAGE:    /* ^O PAGE DOWN, or */
			case 14:
				ed__op_bottom();
				break;	    /* ^O ^N = bottom of file */
			case 7:
			case 'g':
			case 'G':
				ed__op_goto();
				break;	    /* ^O G = go to line */
			case 13:
			case 'm':
			case 'M':
				ed__op_mark();
				break;	    /* ^O M = mark block */
			case 2:
			case 'b':
			case 'B':
				ed__op_block();
				break;	    /* ^O B = use block */
			case ' ':
				finished = 1;
				break;	    /* ^O SPACE = save & exit */
			case 17:
			case 'q':
			case 'Q':
				finished = 2;
				break;	    /* ^O Q = quit edit */
			case 6:
			case 'f':
			case 'F':
				ed__op_find();
				break;	    /* ^O F = find text */
			case 'd':
			case 'D':
				ed__op_datestamp();
				break;	    /* ^O D = insert datestamp */
			case 0:
			case -1:	    /* no key pressed */
				if (!oes) { /* ...display help */
					ed__showhelp = 1;
					ed__redraw = 1;
				} else
					ed__showhelp = 1;
				ctrl_o = 1;
				break;
			default:
				break;	    /* unknown ^O key */
			}

			if ((!ed__showhelp) && (oes))
				ed__redraw = 1;
		}
	}

	t_goto(0, t_rows - 1);

	ed_saveopts();			    /* store editor options */

	if (finished == 1)
		ed_save(file);		    /* only save if not aborted */

	ed_exit();			    /* free memory */

	return (finished - 1);
}

/* EOF */
