/*
 * STEVIE - Simply Try this Editor for VI Enthusiasts
 *
 * Code Contributions By : Tim Thompson           twitch!tjt
 *                         Tony Andrews           onecom!wldrdg!tony 
 *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
 */

#include "stevie.h"

/*
 * updateNextscreen() 
 *
 * Based on the current value of Topchar, transfer a screenfull of stuff from
 * Filemem to Nextscreen, and update Botchar. 
 */

void
updateNextscreen()
{
    int             row, col;
    register char  *screenp = Nextscreen;
    LPTR            memp;
    LPTR            save;	/* save pos. in case line won't fit */
    register char  *endscreen;
    char           *nextrow;
    char            extra[16];
    int             nextra = 0;
    char            c;
    int             n;
    int             done;
    int             srow;	/* starting row of the current line */

    MustRedrawLine = FALSE;
    MustRedrawScreen = TRUE;

    save = memp = *Topchar;

    /* The number of rows shown is Rows-1. */
    /* The last line is the status/command line. */
    endscreen = &screenp[(Rows - 1) * Columns];

    srow = done = row = col = 0;
    while (screenp < endscreen && !done) {

	/* Get the next character to put on the screen. */

	/*
	 * The 'extra' array contains the extra stuff that is inserted to
	 * represent special characters (tabs, and other non-printable stuff.
	 * The order in the 'extra' array is reversed. 
	 */

	if (nextra > 0)
	    c = extra[--nextra];
	else {
	    c = gchar(&memp);
	    if (inc(&memp) == -1)
		done = 1;
	    /*
	     * when getting a character from the file, we may have to turn it
	     * into something else on the way to putting it into
	     * 'Nextscreen'. 
	     */
	    if (c == TAB && !P(P_LS)) {
		strcpy(extra, "        ");
		/* tab amount depends on current column */
		nextra = ((P(P_TS) - 1) - col % P(P_TS));
		c = ' ';
	    } else if (c == NUL && P(P_LS)) {
		extra[0] = NUL;
		nextra = 1;
		c = '$';
	    } else if ((n = chars[c].ch_size) > 1) {
		char           *p;
		nextra = 0;
		p = chars[c].ch_str;
		/* copy 'ch-str'ing into 'extra' in reverse */
		while (n > 1)
		    extra[nextra++] = p[--n];
		c = p[0];
	    }
	}

	if (c == NUL) {
	    srow = ++row;
	    /*
	     * Save this position in case the next line won't fit on the
	     * screen completely. 
	     */
	    save = memp;
	    /* get pointer to start of next row */
	    nextrow = &Nextscreen[row * Columns];
	    /* blank out the rest of this row */
	    while (screenp != nextrow)
		*screenp++ = ' ';
	    col = 0;
	    continue;
	}
	if (col >= Columns) {
	    row++;
	    col = 0;
	}
	/* store the character in Nextscreen */
	*screenp++ = c;
	col++;
    }
    /*
     * If we didn't hit the end of the file, and we didn't finish the last
     * line we were working on, then the line didn't fit. 
     */
    if (!done && c != NUL) {
	/*
	 * Clear the rest of the screen and mark the unused lines. 
	 */
	screenp = &Nextscreen[srow * Columns];
	while (screenp < endscreen)
	    *screenp++ = ' ';
	for (; srow < (Rows - 1); srow++)
	    Nextscreen[srow * Columns] = '@';
	*Botchar = save;
	return;
    }
    /* make sure the rest of the screen is blank */
    while (screenp < endscreen)
	*screenp++ = ' ';
    /* put '~'s on rows that aren't part of the file. */
    if (col != 0)
	row++;
    while (row < Rows) {
	Nextscreen[row * Columns] = '~';
	row++;
    }
    if (done)			/* we hit the end of the file */
	*Botchar = *Fileend;
    else
	*Botchar = memp;
}
