/*	$NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $	*/

/*-
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Christos Zoulas of Cornell University.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)refresh.c	8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $");
#endif
#endif /* not lint && not SCCSID */

/*
 * refresh.c: Lower level screen refreshing functions
 */
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>

#include "el.h"

private void	re_nextline(EditLine *);
private void	re_addc(EditLine *, Int);
private void	re_update_line(EditLine *, Char *, Char *, int);
private void	re_insert (EditLine *, Char *, int, int, Char *, int);
private void	re_delete(EditLine *, Char *, int, int, int);
private void	re_fastputc(EditLine *, Int);
private void	re_clear_eol(EditLine *, int, int, int);
private void	re__strncopy(Char *, Char *, size_t);
private void	re__copy_and_pad(Char *, const Char *, size_t);

#ifdef DEBUG_REFRESH
private void	re_printstr(EditLine *, const char *, char *, char *);
#define	__F el->el_errfile
#define	ELRE_ASSERT(a, b, c)	do 				\
				    if (/*CONSTCOND*/ a) {	\
					(void) fprintf b;	\
					c;			\
				    }				\
				while (/*CONSTCOND*/0)
#define	ELRE_DEBUG(a, b)	ELRE_ASSERT(a,b,;)

/* re_printstr():
 *	Print a string on the debugging pty
 */
private void
re_printstr(EditLine *el, const char *str, char *f, char *t)
{

	ELRE_DEBUG(1, (__F, "%s:\"", str));
	while (f < t)
		ELRE_DEBUG(1, (__F, "%c", *f++ & 0177));
	ELRE_DEBUG(1, (__F, "\"\r\n"));
}
#else
#define	ELRE_ASSERT(a, b, c)
#define	ELRE_DEBUG(a, b)
#endif

/* re_nextline():
 *	Move to the next line or scroll
 */
private void
re_nextline(EditLine *el)
{
	el->el_refresh.r_cursor.h = 0;	/* reset it. */

	/*
	 * If we would overflow (input is longer than terminal size),
	 * emulate scroll by dropping first line and shuffling the rest.
	 * We do this via pointer shuffling - it's safe in this case
	 * and we avoid memcpy().
	 */
	if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
		int i, lins = el->el_terminal.t_size.v;
		Char *firstline = el->el_vdisplay[0];

		for(i = 1; i < lins; i++)
			el->el_vdisplay[i - 1] = el->el_vdisplay[i];

		firstline[0] = '\0';		/* empty the string */	
		el->el_vdisplay[i - 1] = firstline;
	} else
		el->el_refresh.r_cursor.v++;

	ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v,
	    (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
	    el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
	    abort());
}

/* re_addc():
 *	Draw c, expanding tabs, control chars etc.
 */
private void
re_addc(EditLine *el, Int c)
{
	switch (ct_chr_class((Char)c)) {
	case CHTYPE_TAB:        /* expand the tab */
		for (;;) {
			re_putc(el, ' ', 1);
			if ((el->el_refresh.r_cursor.h & 07) == 0)
				break;			/* go until tab stop */
		}
		break;
	case CHTYPE_NL: {
		int oldv = el->el_refresh.r_cursor.v;
		re_putc(el, '\0', 0);			/* assure end of line */
		if (oldv == el->el_refresh.r_cursor.v)	/* XXX */
			re_nextline(el);
		break;
	}
	case CHTYPE_PRINT:
		re_putc(el, c, 1);
		break;
	default: {
		Char visbuf[VISUAL_WIDTH_MAX];
		ssize_t i, n =
		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
		for (i = 0; n-- > 0; ++i)
		    re_putc(el, visbuf[i], 1);
		break;
	}
	}
}


/* re_putc():
 *	Draw the character given
 */
protected void
re_putc(EditLine *el, Int c, int shift)
{
	int i, w = Width(c);
	ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c));

	while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
	    re_putc(el, ' ', 1);

	el->el_vdisplay[el->el_refresh.r_cursor.v]
	    [el->el_refresh.r_cursor.h] = c;
	/* assumes !shift is only used for single-column chars */
	i = w;
	while (--i > 0)
		el->el_vdisplay[el->el_refresh.r_cursor.v]
		    [el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;

	if (!shift)
		return;

	el->el_refresh.r_cursor.h += w;	/* advance to next place */
	if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
		/* assure end of line */
		el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
		    = '\0';
		re_nextline(el);
	}
}


/* re_refresh():
 *	draws the new virtual screen image from the current input
 *  	line, then goes line-by-line changing the real image to the new
 *	virtual image. The routine to re-draw a line can be replaced
 *	easily in hopes of a smarter one being placed there.
 */
protected void
re_refresh(EditLine *el)
{
	int i, rhdiff;
	Char *cp, *st;
	coord_t cur;
#ifdef notyet
	size_t termsz;
#endif

	ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%s:\r\n",
	    el->el_line.buffer));

	/* reset the Drawing cursor */
	el->el_refresh.r_cursor.h = 0;
	el->el_refresh.r_cursor.v = 0;

	/* temporarily draw rprompt to calculate its size */
	prompt_print(el, EL_RPROMPT);

	/* reset the Drawing cursor */
	el->el_refresh.r_cursor.h = 0;
	el->el_refresh.r_cursor.v = 0;

	if (el->el_line.cursor >= el->el_line.lastchar) {
		if (el->el_map.current == el->el_map.alt
		    && el->el_line.lastchar != el->el_line.buffer)
			el->el_line.cursor = el->el_line.lastchar - 1;
		else
			el->el_line.cursor = el->el_line.lastchar;
	}

	cur.h = -1;		/* set flag in case I'm not set */
	cur.v = 0;

	prompt_print(el, EL_PROMPT);

	/* draw the current input buffer */
#if notyet
	termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
	if (el->el_line.lastchar - el->el_line.buffer > termsz) {
		/*
		 * If line is longer than terminal, process only part
		 * of line which would influence display.
		 */
		size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;

		st = el->el_line.lastchar - rem
			- (termsz - (((rem / el->el_terminal.t_size.v) - 1)
					* el->el_terminal.t_size.v));
	} else
#endif
		st = el->el_line.buffer;

	for (cp = st; cp < el->el_line.lastchar; cp++) {
		if (cp == el->el_line.cursor) {
                        int w = Width(*cp);
			/* save for later */
			cur.h = el->el_refresh.r_cursor.h;
			cur.v = el->el_refresh.r_cursor.v;
                        /* handle being at a linebroken doublewidth char */
                        if (w > 1 && el->el_refresh.r_cursor.h + w >
			    el->el_terminal.t_size.h) {
				cur.h = 0;
				cur.v++;
                        }
		}
		re_addc(el, *cp);
	}

	if (cur.h == -1) {	/* if I haven't been set yet, I'm at the end */
		cur.h = el->el_refresh.r_cursor.h;
		cur.v = el->el_refresh.r_cursor.v;
	}
	rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
	    el->el_rprompt.p_pos.h;
	if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
	    !el->el_refresh.r_cursor.v && rhdiff > 1) {
		/*
		 * have a right-hand side prompt that will fit
		 * on the end of the first line with at least
		 * one character gap to the input buffer.
		 */
		while (--rhdiff > 0)	/* pad out with spaces */
			re_putc(el, ' ', 1);
		prompt_print(el, EL_RPROMPT);
	} else {
		el->el_rprompt.p_pos.h = 0;	/* flag "not using rprompt" */
		el->el_rprompt.p_pos.v = 0;
	}

	re_putc(el, '\0', 0);	/* make line ended with NUL, no cursor shift */

	el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;

	ELRE_DEBUG(1, (__F,
		"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
		el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
		el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0])));

	ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
	for (i = 0; i <= el->el_refresh.r_newcv; i++) {
		/* NOTE THAT re_update_line MAY CHANGE el_display[i] */
		re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);

		/*
		 * Copy the new line to be the current one, and pad out with
		 * spaces to the full width of the terminal so that if we try
		 * moving the cursor by writing the character that is at the
		 * end of the screen line, it won't be a NUL or some old
		 * leftover stuff.
		 */
		re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
		    (size_t) el->el_terminal.t_size.h);
	}
	ELRE_DEBUG(1, (__F,
	"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
	    el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i));

	if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
		for (; i <= el->el_refresh.r_oldcv; i++) {
			terminal_move_to_line(el, i);
			terminal_move_to_char(el, 0);
                        /* This Strlen should be safe even with MB_FILL_CHARs */
			terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH
			terminal_overwrite(el, "C\b", (size_t)2);
#endif /* DEBUG_REFRESH */
			el->el_display[i][0] = '\0';
		}

	el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
	ELRE_DEBUG(1, (__F,
	    "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
	    el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
	    cur.h, cur.v));
	terminal_move_to_line(el, cur.v);	/* go to where the cursor is */
	terminal_move_to_char(el, cur.h);
}


/* re_goto_bottom():
 *	 used to go to last used screen line
 */
protected void
re_goto_bottom(EditLine *el)
{

	terminal_move_to_line(el, el->el_refresh.r_oldcv);
	terminal__putc(el, '\n');
	re_clear_display(el);
	terminal__flush(el);
}


/* re_insert():
 *	insert num characters of s into d (in front of the character)
 *	at dat, maximum length of d is dlen
 */
private void
/*ARGSUSED*/
re_insert(EditLine *el __attribute__((__unused__)),
    Char *d, int dat, int dlen, Char *s, int num)
{
	Char *a, *b;

	if (num <= 0)
		return;
	if (num > dlen - dat)
		num = dlen - dat;

	ELRE_DEBUG(1,
	    (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
	    num, dat, dlen, ct_encode_string(d)));
	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));

	/* open up the space for num chars */
	if (num > 0) {
		b = d + dlen - 1;
		a = b - num;
		while (a >= &d[dat])
			*b-- = *a--;
		d[dlen] = '\0';	/* just in case */
	}

	ELRE_DEBUG(1, (__F,
		"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
		num, dat, dlen, ct_encode_string(d)));
	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));

	/* copy the characters */
	for (a = d + dat; (a < d + dlen) && (num > 0); num--)
		*a++ = *s++;

#ifdef notyet
        /* ct_encode_string() uses a static buffer, so we can't conveniently
         * encode both d & s here */
	ELRE_DEBUG(1,
	    (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
	    num, dat, dlen, d, s));
	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
#endif
}


/* re_delete():
 *	delete num characters d at dat, maximum length of d is dlen
 */
private void
/*ARGSUSED*/
re_delete(EditLine *el __attribute__((__unused__)),
    Char *d, int dat, int dlen, int num)
{
	Char *a, *b;

	if (num <= 0)
		return;
	if (dat + num >= dlen) {
		d[dat] = '\0';
		return;
	}
	ELRE_DEBUG(1,
	    (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
	    num, dat, dlen, ct_encode_string(d)));

	/* open up the space for num chars */
	if (num > 0) {
		b = d + dat;
		a = b + num;
		while (a < &d[dlen])
			*b++ = *a++;
		d[dlen] = '\0';	/* just in case */
	}
	ELRE_DEBUG(1,
	    (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
	    num, dat, dlen, ct_encode_string(d)));
}


/* re__strncopy():
 *	Like strncpy without padding.
 */
private void
re__strncopy(Char *a, Char *b, size_t n)
{

	while (n-- && *b)
		*a++ = *b++;
}

/* re_clear_eol():
 *	Find the number of characters we need to clear till the end of line
 *	in order to make sure that we have cleared the previous contents of
 *	the line. fx and sx is the number of characters inserted or deleted
 *	in the first or second diff, diff is the difference between the
 * 	number of characters between the new and old line.
 */
private void
re_clear_eol(EditLine *el, int fx, int sx, int diff)
{

	ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n",
	    sx, fx, diff));

	if (fx < 0)
		fx = -fx;
	if (sx < 0)
		sx = -sx;
	if (fx > diff)
		diff = fx;
	if (sx > diff)
		diff = sx;

	ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
	terminal_clear_EOL(el, diff);
}

/*****************************************************************
    re_update_line() is based on finding the middle difference of each line
    on the screen; vis:

			     /old first difference
	/beginning of line   |              /old last same       /old EOL
	v		     v              v                    v
old:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
new:	eddie> Oh, my little buggy says to me, as lurgid as
	^		     ^        ^			   ^
	\beginning of line   |        \new last same	   \new end of line
			     \new first difference

    all are character pointers for the sake of speed.  Special cases for
    no differences, as well as for end of line additions must be handled.
**************************************************************** */

/* Minimum at which doing an insert it "worth it".  This should be about
 * half the "cost" of going into insert mode, inserting a character, and
 * going back out.  This should really be calculated from the termcap
 * data...  For the moment, a good number for ANSI terminals.
 */
#define	MIN_END_KEEP	4

private void
re_update_line(EditLine *el, Char *old, Char *new, int i)
{
	Char *o, *n, *p, c;
	Char *ofd, *ols, *oe, *nfd, *nls, *ne;
	Char *osb, *ose, *nsb, *nse;
	int fx, sx;
	size_t len;

	/*
         * find first diff
         */
	for (o = old, n = new; *o && (*o == *n); o++, n++)
		continue;
	ofd = o;
	nfd = n;

	/*
         * Find the end of both old and new
         */
	while (*o)
		o++;
	/*
         * Remove any trailing blanks off of the end, being careful not to
         * back up past the beginning.
         */
	while (ofd < o) {
		if (o[-1] != ' ')
			break;
		o--;
	}
	oe = o;
	*oe = '\0';

	while (*n)
		n++;

	/* remove blanks from end of new */
	while (nfd < n) {
		if (n[-1] != ' ')
			break;
		n--;
	}
	ne = n;
	*ne = '\0';

	/*
         * if no diff, continue to next line of redraw
         */
	if (*ofd == '\0' && *nfd == '\0') {
		ELRE_DEBUG(1, (__F, "no difference.\r\n"));
		return;
	}
	/*
         * find last same pointer
         */
	while ((o > ofd) && (n > nfd) && (*--o == *--n))
		continue;
	ols = ++o;
	nls = ++n;

	/*
         * find same begining and same end
         */
	osb = ols;
	nsb = nls;
	ose = ols;
	nse = nls;

	/*
         * case 1: insert: scan from nfd to nls looking for *ofd
         */
	if (*ofd) {
		for (c = *ofd, n = nfd; n < nls; n++) {
			if (c == *n) {
				for (o = ofd, p = n;
				    p < nls && o < ols && *o == *p;
				    o++, p++)
					continue;
				/*
				 * if the new match is longer and it's worth
				 * keeping, then we take it
				 */
				if (((nse - nsb) < (p - n)) &&
				    (2 * (p - n) > n - nfd)) {
					nsb = n;
					nse = p;
					osb = ofd;
					ose = o;
				}
			}
		}
	}
	/*
         * case 2: delete: scan from ofd to ols looking for *nfd
         */
	if (*nfd) {
		for (c = *nfd, o = ofd; o < ols; o++) {
			if (c == *o) {
				for (n = nfd, p = o;
				    p < ols && n < nls && *p == *n;
				    p++, n++)
					continue;
				/*
				 * if the new match is longer and it's worth
				 * keeping, then we take it
				 */
				if (((ose - osb) < (p - o)) &&
				    (2 * (p - o) > o - ofd)) {
					nsb = nfd;
					nse = n;
					osb = o;
					ose = p;
				}
			}
		}
	}
	/*
         * Pragmatics I: If old trailing whitespace or not enough characters to
         * save to be worth it, then don't save the last same info.
         */
	if ((oe - ols) < MIN_END_KEEP) {
		ols = oe;
		nls = ne;
	}
	/*
         * Pragmatics II: if the terminal isn't smart enough, make the data
         * dumber so the smart update doesn't try anything fancy
         */

	/*
         * fx is the number of characters we need to insert/delete: in the
         * beginning to bring the two same begins together
         */
	fx = (int)((nsb - nfd) - (osb - ofd));
	/*
         * sx is the number of characters we need to insert/delete: in the
         * end to bring the two same last parts together
         */
	sx = (int)((nls - nse) - (ols - ose));

	if (!EL_CAN_INSERT) {
		if (fx > 0) {
			osb = ols;
			ose = ols;
			nsb = nls;
			nse = nls;
		}
		if (sx > 0) {
			ols = oe;
			nls = ne;
		}
		if ((ols - ofd) < (nls - nfd)) {
			ols = oe;
			nls = ne;
		}
	}
	if (!EL_CAN_DELETE) {
		if (fx < 0) {
			osb = ols;
			ose = ols;
			nsb = nls;
			nse = nls;
		}
		if (sx < 0) {
			ols = oe;
			nls = ne;
		}
		if ((ols - ofd) > (nls - nfd)) {
			ols = oe;
			nls = ne;
		}
	}
	/*
         * Pragmatics III: make sure the middle shifted pointers are correct if
         * they don't point to anything (we may have moved ols or nls).
         */
	/* if the change isn't worth it, don't bother */
	/* was: if (osb == ose) */
	if ((ose - osb) < MIN_END_KEEP) {
		osb = ols;
		ose = ols;
		nsb = nls;
		nse = nls;
	}
	/*
         * Now that we are done with pragmatics we recompute fx, sx
         */
	fx = (int)((nsb - nfd) - (osb - ofd));
	sx = (int)((nls - nse) - (ols - ose));

	ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
	ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
		ofd - old, osb - old, ose - old, ols - old, oe - old));
	ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
		nfd - new, nsb - new, nse - new, nls - new, ne - new));
	ELRE_DEBUG(1, (__F,
		"xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"));
	ELRE_DEBUG(1, (__F,
		"xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"));
#ifdef DEBUG_REFRESH
	re_printstr(el, "old- oe", old, oe);
	re_printstr(el, "new- ne", new, ne);
	re_printstr(el, "old-ofd", old, ofd);
	re_printstr(el, "new-nfd", new, nfd);
	re_printstr(el, "ofd-osb", ofd, osb);
	re_printstr(el, "nfd-nsb", nfd, nsb);
	re_printstr(el, "osb-ose", osb, ose);
	re_printstr(el, "nsb-nse", nsb, nse);
	re_printstr(el, "ose-ols", ose, ols);
	re_printstr(el, "nse-nls", nse, nls);
	re_printstr(el, "ols- oe", ols, oe);
	re_printstr(el, "nls- ne", nls, ne);
#endif /* DEBUG_REFRESH */

	/*
         * el_cursor.v to this line i MUST be in this routine so that if we
         * don't have to change the line, we don't move to it. el_cursor.h to
         * first diff char
         */
	terminal_move_to_line(el, i);

	/*
         * at this point we have something like this:
         *
         * /old                  /ofd    /osb               /ose    /ols     /oe
         * v.....................v       v..................v       v........v
         * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
         * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
         * ^.....................^     ^..................^       ^........^
         * \new                  \nfd  \nsb               \nse     \nls    \ne
         *
         * fx is the difference in length between the chars between nfd and
         * nsb, and the chars between ofd and osb, and is thus the number of
         * characters to delete if < 0 (new is shorter than old, as above),
         * or insert (new is longer than short).
         *
         * sx is the same for the second differences.
         */

	/*
         * if we have a net insert on the first difference, AND inserting the
         * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
         * character (which is ne if nls != ne, otherwise is nse) off the edge
	 * of the screen (el->el_terminal.t_size.h) else we do the deletes first
	 * so that we keep everything we need to.
         */

	/*
         * if the last same is the same like the end, there is no last same
         * part, otherwise we want to keep the last same part set p to the
         * last useful old character
         */
	p = (ols != oe) ? oe : ose;

	/*
         * if (There is a diffence in the beginning) && (we need to insert
         *   characters) && (the number of characters to insert is less than
         *   the term width)
	 *	We need to do an insert!
	 * else if (we need to delete characters)
	 *	We need to delete characters!
	 * else
	 *	No insert or delete
         */
	if ((nsb != nfd) && fx > 0 &&
	    ((p - old) + fx <= el->el_terminal.t_size.h)) {
		ELRE_DEBUG(1,
		    (__F, "first diff insert at %d...\r\n", nfd - new));
		/*
		 * Move to the first char to insert, where the first diff is.
		 */
		terminal_move_to_char(el, (int)(nfd - new));
		/*
		 * Check if we have stuff to keep at end
		 */
		if (nsb != ne) {
			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
			/*
		         * insert fx chars of new starting at nfd
		         */
			if (fx > 0) {
				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
				"ERROR: cannot insert in early first diff\n"));
				terminal_insertwrite(el, nfd, fx);
				re_insert(el, old, (int)(ofd - old),
				    el->el_terminal.t_size.h, nfd, fx);
			}
			/*
		         * write (nsb-nfd) - fx chars of new starting at
		         * (nfd + fx)
			 */
			len = (size_t) ((nsb - nfd) - fx);
			terminal_overwrite(el, (nfd + fx), len);
			re__strncopy(ofd + fx, nfd + fx, len);
		} else {
			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
			len = (size_t)(nsb - nfd);
			terminal_overwrite(el, nfd, len);
			re__strncopy(ofd, nfd, len);
			/*
		         * Done
		         */
			return;
		}
	} else if (fx < 0) {
		ELRE_DEBUG(1,
		    (__F, "first diff delete at %d...\r\n", ofd - old));
		/*
		 * move to the first char to delete where the first diff is
		 */
		terminal_move_to_char(el, (int)(ofd - old));
		/*
		 * Check if we have stuff to save
		 */
		if (osb != oe) {
			ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
			/*
		         * fx is less than zero *always* here but we check
		         * for code symmetry
		         */
			if (fx < 0) {
				ELRE_DEBUG(!EL_CAN_DELETE, (__F,
				    "ERROR: cannot delete in first diff\n"));
				terminal_deletechars(el, -fx);
				re_delete(el, old, (int)(ofd - old),
				    el->el_terminal.t_size.h, -fx);
			}
			/*
		         * write (nsb-nfd) chars of new starting at nfd
		         */
			len = (size_t) (nsb - nfd);
			terminal_overwrite(el, nfd, len);
			re__strncopy(ofd, nfd, len);

		} else {
			ELRE_DEBUG(1, (__F,
			    "but with nothing left to save\r\n"));
			/*
		         * write (nsb-nfd) chars of new starting at nfd
		         */
			terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
			re_clear_eol(el, fx, sx,
			    (int)((oe - old) - (ne - new)));
			/*
		         * Done
		         */
			return;
		}
	} else
		fx = 0;

	if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
		ELRE_DEBUG(1, (__F,
		    "second diff delete at %d...\r\n", (ose - old) + fx));
		/*
		 * Check if we have stuff to delete
		 */
		/*
		 * fx is the number of characters inserted (+) or deleted (-)
		 */

		terminal_move_to_char(el, (int)((ose - old) + fx));
		/*
		 * Check if we have stuff to save
		 */
		if (ols != oe) {
			ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
			/*
		         * Again a duplicate test.
		         */
			if (sx < 0) {
				ELRE_DEBUG(!EL_CAN_DELETE, (__F,
				    "ERROR: cannot delete in second diff\n"));
				terminal_deletechars(el, -sx);
			}
			/*
		         * write (nls-nse) chars of new starting at nse
		         */
			terminal_overwrite(el, nse, (size_t)(nls - nse));
		} else {
			ELRE_DEBUG(1, (__F,
			    "but with nothing left to save\r\n"));
			terminal_overwrite(el, nse, (size_t)(nls - nse));
			re_clear_eol(el, fx, sx,
			    (int)((oe - old) - (ne - new)));
		}
	}
	/*
         * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
         */
	if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
		ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
		    nfd - new));

		terminal_move_to_char(el, (int)(nfd - new));
		/*
		 * Check if we have stuff to keep at the end
		 */
		if (nsb != ne) {
			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
			/*
		         * We have to recalculate fx here because we set it
		         * to zero above as a flag saying that we hadn't done
		         * an early first insert.
		         */
			fx = (int)((nsb - nfd) - (osb - ofd));
			if (fx > 0) {
				/*
				 * insert fx chars of new starting at nfd
				 */
				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
				 "ERROR: cannot insert in late first diff\n"));
				terminal_insertwrite(el, nfd, fx);
				re_insert(el, old, (int)(ofd - old),
				    el->el_terminal.t_size.h, nfd, fx);
			}
			/*
		         * write (nsb-nfd) - fx chars of new starting at
		         * (nfd + fx)
			 */
			len = (size_t) ((nsb - nfd) - fx);
			terminal_overwrite(el, (nfd + fx), len);
			re__strncopy(ofd + fx, nfd + fx, len);
		} else {
			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
			len = (size_t) (nsb - nfd);
			terminal_overwrite(el, nfd, len);
			re__strncopy(ofd, nfd, len);
		}
	}
	/*
         * line is now NEW up to nse
         */
	if (sx >= 0) {
		ELRE_DEBUG(1, (__F,
		    "second diff insert at %d...\r\n", (int)(nse - new)));
		terminal_move_to_char(el, (int)(nse - new));
		if (ols != oe) {
			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
			if (sx > 0) {
				/* insert sx chars of new starting at nse */
				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
				    "ERROR: cannot insert in second diff\n"));
				terminal_insertwrite(el, nse, sx);
			}
			/*
		         * write (nls-nse) - sx chars of new starting at
			 * (nse + sx)
		         */
			terminal_overwrite(el, (nse + sx),
			    (size_t)((nls - nse) - sx));
		} else {
			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
			terminal_overwrite(el, nse, (size_t)(nls - nse));

			/*
	                 * No need to do a clear-to-end here because we were
	                 * doing a second insert, so we will have over
	                 * written all of the old string.
		         */
		}
	}
	ELRE_DEBUG(1, (__F, "done.\r\n"));
}


/* re__copy_and_pad():
 *	Copy string and pad with spaces
 */
private void
re__copy_and_pad(Char *dst, const Char *src, size_t width)
{
	size_t i;

	for (i = 0; i < width; i++) {
		if (*src == '\0')
			break;
		*dst++ = *src++;
	}

	for (; i < width; i++)
		*dst++ = ' ';

	*dst = '\0';
}


/* re_refresh_cursor():
 *	Move to the new cursor position
 */
protected void
re_refresh_cursor(EditLine *el)
{
	Char *cp;
	int h, v, th, w;

	if (el->el_line.cursor >= el->el_line.lastchar) {
		if (el->el_map.current == el->el_map.alt
		    && el->el_line.lastchar != el->el_line.buffer)
			el->el_line.cursor = el->el_line.lastchar - 1;
		else
			el->el_line.cursor = el->el_line.lastchar;
	}

	/* first we must find where the cursor is... */
	h = el->el_prompt.p_pos.h;
	v = el->el_prompt.p_pos.v;
	th = el->el_terminal.t_size.h;	/* optimize for speed */

	/* do input buffer to el->el_line.cursor */
	for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
                switch (ct_chr_class(*cp)) {
		case CHTYPE_NL:  /* handle newline in data part too */
			h = 0;
			v++;
			break;
		case CHTYPE_TAB: /* if a tab, to next tab stop */
			while (++h & 07)
				continue;
			break;
		default:
			w = Width(*cp);
			if (w > 1 && h + w > th) { /* won't fit on line */
				h = 0;
				v++;
			}
			h += ct_visual_width(*cp);
			break;
                }

		if (h >= th) {	/* check, extra long tabs picked up here also */
			h -= th;
			v++;
		}
	}
        /* if we have a next character, and it's a doublewidth one, we need to
         * check whether we need to linebreak for it to fit */
        if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
                if (h + w > th) {
                    h = 0;
                    v++;
                }

	/* now go there */
	terminal_move_to_line(el, v);
	terminal_move_to_char(el, h);
	terminal__flush(el);
}


/* re_fastputc():
 *	Add a character fast.
 */
private void
re_fastputc(EditLine *el, Int c)
{
	int w = Width((Char)c);
	while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
	    re_fastputc(el, ' ');

	terminal__putc(el, c);
	el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
	while (--w > 0)
		el->el_display[el->el_cursor.v][el->el_cursor.h++]
			= MB_FILL_CHAR;

	if (el->el_cursor.h >= el->el_terminal.t_size.h) {
		/* if we must overflow */
		el->el_cursor.h = 0;

		/*
		 * If we would overflow (input is longer than terminal size),
		 * emulate scroll by dropping first line and shuffling the rest.
		 * We do this via pointer shuffling - it's safe in this case
		 * and we avoid memcpy().
		 */
		if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
			int i, lins = el->el_terminal.t_size.v;
			Char *firstline = el->el_display[0];
	
			for(i = 1; i < lins; i++)
				el->el_display[i - 1] = el->el_display[i];

			re__copy_and_pad(firstline, STR(""), (size_t)0);
			el->el_display[i - 1] = firstline;
		} else {
			el->el_cursor.v++;
			el->el_refresh.r_oldcv++;
		}
		if (EL_HAS_AUTO_MARGINS) {
			if (EL_HAS_MAGIC_MARGINS) {
				terminal__putc(el, ' ');
				terminal__putc(el, '\b');
			}
		} else {
			terminal__putc(el, '\r');
			terminal__putc(el, '\n');
		}
	}
}


/* re_fastaddc():
 *	we added just one char, handle it fast.
 *	Assumes that screen cursor == real cursor
 */
protected void
re_fastaddc(EditLine *el)
{
	Char c;
	int rhdiff;

	c = el->el_line.cursor[-1];

	if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
		re_refresh(el);	/* too hard to handle */
		return;
	}
	rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
	    el->el_rprompt.p_pos.h;
	if (el->el_rprompt.p_pos.h && rhdiff < 3) {
		re_refresh(el);	/* clear out rprompt if less than 1 char gap */
		return;
	}			/* else (only do at end of line, no TAB) */
	switch (ct_chr_class(c)) {
	case CHTYPE_TAB: /* already handled, should never happen here */
		break;
	case CHTYPE_NL:
	case CHTYPE_PRINT:
		re_fastputc(el, c);
		break;
	case CHTYPE_ASCIICTL:
	case CHTYPE_NONPRINT: {
		Char visbuf[VISUAL_WIDTH_MAX];
		ssize_t i, n =
		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
		for (i = 0; n-- > 0; ++i)
			re_fastputc(el, visbuf[i]);
		break;
	}
	}
	terminal__flush(el);
}


/* re_clear_display():
 *	clear the screen buffers so that new new prompt starts fresh.
 */
protected void
re_clear_display(EditLine *el)
{
	int i;

	el->el_cursor.v = 0;
	el->el_cursor.h = 0;
	for (i = 0; i < el->el_terminal.t_size.v; i++)
		el->el_display[i][0] = '\0';
	el->el_refresh.r_oldcv = 0;
}


/* re_clear_lines():
 *	Make sure all lines are *really* blank
 */
protected void
re_clear_lines(EditLine *el)
{

	if (EL_CAN_CEOL) {
		int i;
		for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
			/* for each line on the screen */
			terminal_move_to_line(el, i);
			terminal_move_to_char(el, 0);
			terminal_clear_EOL(el, el->el_terminal.t_size.h);
		}
	} else {
		terminal_move_to_line(el, el->el_refresh.r_oldcv);
					/* go to last line */
		terminal__putc(el, '\r');	/* go to BOL */
		terminal__putc(el, '\n');	/* go to new line */
	}
}
