#include "rm.h"
#include <xfbuf.h>
#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <process.h>

/*
	Message text display.


display_text()
	Display the in-memory text in the window 'body'. This
	assume LF terminated lines, NUL characters are ignored, and
	SUB marks the end of the file. Global var 'origin' is the
	number of the first line in the window.

text_motion()
	Handles basic cursor motion, up, down, page-up, page-down,
	hone and end. 
*/

void display_text() {
int i,d;
char *cp;

	w_pos(&body,0,0);				/* start at top */
	cp= textptr;					/* ptr to text */
	while (1) {
		if (*cp == CR) {			/* EOL marker */
			for (i= body.cols - body.col; i--;)
				w_char(&body,' ');	/* endfill w/spaces */
			body.col= 0;

		} else if (*cp == LF) {			/* next line... */
			w_char(&body,LF);
			if (body.line == 0) break;	/* it wrapped */

		} else if (*cp == SUB) {		/* end of file */
			for (i= body.cols - body.col; i--;)
				w_char(&body,' ');	/* endfill w/spaces */
			body.col= 0;
			while ((body.col < body.cols - 1) || (body.line < body.lines - 1))
				w_char(&body,176);	/* fill rest of window */
			break;

		} else {
			w_char(&body,*cp);		/* display it */

			/* This detects when writing a character in the
			last cell on the last line wraps to the start of
			the first line. (w_char() wraps rather than scrolls.) */

			if (body.col == 0) if (body.line == 0) break;
		}
		++cp;
	}
}

/* Do text display motion. This consists of positioning the text display
pointer up and down through the in-memory text, using LFs as the EOL
marker. */

void text_motion(key)
char key;	/* IBM keyboard char */
{
char *cp;
int d,i;

	switch (key) {
		/* HOME is simple. */
		case KEY_HOME:
			textptr= mem; break;

		/* END moves to the end of the file minus (body.lines - 1)
		lines. */
		case KEY_END:
			while (*textptr != SUB) ++textptr;
			for (i= body.lines - 1; textptr > mem && i;) {
				if (*--textptr == LF) --i;
			}
			break;

		/* DOWN moves the origin down one line. */
		case KEY_DN:			/* scroll up */
			d= 1; goto down;	/* down one line */

		/* PAGE DOWN moves down (body.lines - 1) lines down. If
		we reach the bottom, scroll up (always display one line.) */
		case KEY_PGDN:
			d= body.lines - 2;
down:			while (*textptr != SUB) {
				if (*textptr++ == LF) if (--d == 0) break;
			}
			if (*textptr == SUB) {		/* if EOF */
				d= 1;			/* go up one */
				goto up;
			}
			break;

		/* UP moves the origin up one line. */
		case KEY_UP:
			d= 1; goto up;

		/* PAGE UP moves up (body.lines - 2) lines. */
		case KEY_PGUP:
			d= body.lines - 2;
up:			--textptr;
			while (textptr > mem) {
				if (*--textptr == LF) if (--d == 0) break;
			}
			++textptr;
			break;
	}
	display_text();
}
