/****************************************************************************
 * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc.              *
 *                                                                          *
 * Permission is hereby granted, free of charge, to any person obtaining a  *
 * copy of this software and associated documentation files (the            *
 * "Software"), to deal in the Software without restriction, including      *
 * without limitation the rights to use, copy, modify, merge, publish,      *
 * distribute, distribute with modifications, sublicense, and/or sell       *
 * copies of the Software, and to permit persons to whom the Software is    *
 * furnished to do so, subject to the following conditions:                 *
 *                                                                          *
 * The above copyright notice and this permission notice shall be included  *
 * in all copies or substantial portions of the Software.                   *
 *                                                                          *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
 *                                                                          *
 * Except as contained in this notice, the name(s) of the above copyright   *
 * holders shall not be used in advertising or otherwise to promote the     *
 * sale, use or other dealings in this Software without prior written       *
 * authorization.                                                           *
 ****************************************************************************/

/*
**	lib_addch.c
**
**	The routine waddch().
**
*/

#include <curses.priv.h>
#include <ctype.h>

MODULE_ID("$Id: lib_addch.c,v 1.129 2014/08/16 20:41:04 tom Exp $")

static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT);

/*
 * Ugly microtweaking alert.  Everything from here to end of module is
 * likely to be speed-critical -- profiling data sure says it is!
 * Most of the important screen-painting functions are shells around
 * waddch().  So we make every effort to reduce function-call overhead
 * by inlining stuff, even at the cost of making wrapped copies for
 * export.  Also we supply some internal versions that don't call the
 * window sync hook, for use by string-put functions.
 */

/* Return bit mask for clearing color pair number if given ch has color */
#define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0))

static NCURSES_INLINE NCURSES_CH_T
render_char(WINDOW *win, NCURSES_CH_T ch)
/* compute a rendition of the given char correct for the current context */
{
    attr_t a = WINDOW_ATTRS(win);
    int pair = GetPair(ch);

    if (ISBLANK(ch)
	&& AttrOf(ch) == A_NORMAL
	&& pair == 0) {
	/* color/pair in attrs has precedence over bkgrnd */
	ch = win->_nc_bkgd;
	SetAttr(ch, a | AttrOf(win->_nc_bkgd));
	if ((pair = GET_WINDOW_PAIR(win)) == 0)
	    pair = GetPair(win->_nc_bkgd);
	SetPair(ch, pair);
    } else {
	/* color in attrs has precedence over bkgrnd */
	a |= AttrOf(win->_nc_bkgd) & COLOR_MASK(a);
	/* color in ch has precedence */
	if (pair == 0) {
	    if ((pair = GET_WINDOW_PAIR(win)) == 0)
		pair = GetPair(win->_nc_bkgd);
	}
	AddAttr(ch, (a & COLOR_MASK(AttrOf(ch))));
	SetPair(ch, pair);
    }

    TR(TRACE_VIRTPUT,
       ("render_char bkg %s (%d), attrs %s (%d) -> ch %s (%d)",
	_tracech_t2(1, CHREF(win->_nc_bkgd)),
	GetPair(win->_nc_bkgd),
	_traceattr(WINDOW_ATTRS(win)),
	GET_WINDOW_PAIR(win),
	_tracech_t2(3, CHREF(ch)),
	GetPair(ch)));

    return (ch);
}

NCURSES_EXPORT(NCURSES_CH_T)
_nc_render(WINDOW *win, NCURSES_CH_T ch)
/* make render_char() visible while still allowing us to inline it below */
{
    return render_char(win, ch);
}

/* check if position is legal; if not, return error */
#ifndef NDEBUG			/* treat this like an assertion */
#define CHECK_POSITION(win, x, y) \
	if (y > win->_maxy \
	 || x > win->_maxx \
	 || y < 0 \
	 || x < 0) { \
		TR(TRACE_VIRTPUT, ("Alert! Win=%p _curx = %d, _cury = %d " \
				   "(_maxx = %d, _maxy = %d)", win, x, y, \
				   win->_maxx, win->_maxy)); \
		return(ERR); \
	}
#else
#define CHECK_POSITION(win, x, y)	/* nothing */
#endif

static bool
newline_forces_scroll(WINDOW *win, NCURSES_SIZE_T * ypos)
{
    bool result = FALSE;

    if (*ypos >= win->_regtop && *ypos == win->_regbottom) {
	*ypos = win->_regbottom;
	result = TRUE;
    } else {
	*ypos = (NCURSES_SIZE_T) (*ypos + 1);
    }
    return result;
}

/*
 * The _WRAPPED flag is useful only for telling an application that we've just
 * wrapped the cursor.  We don't do anything with this flag except set it when
 * wrapping, and clear it whenever we move the cursor.  If we try to wrap at
 * the lower-right corner of a window, we cannot move the cursor (since that
 * wouldn't be legal).  So we return an error (which is what SVr4 does). 
 * Unlike SVr4, we can successfully add a character to the lower-right corner
 * (Solaris 2.6 does this also, however).
 */
static int
wrap_to_next_line(WINDOW *win)
{
    win->_flags |= _WRAPPED;
    if (newline_forces_scroll(win, &(win->_cury))) {
	win->_curx = win->_maxx;
	if (!win->_scroll)
	    return (ERR);
	scroll(win);
    }
    win->_curx = 0;
    return (OK);
}

#if USE_WIDEC_SUPPORT
static int waddch_literal(WINDOW *, NCURSES_CH_T);
/*
 * Fill the given number of cells with blanks using the current background
 * rendition.  This saves/restores the current x-position.
 */
static void
fill_cells(WINDOW *win, int count)
{
    NCURSES_CH_T blank = blankchar;
    int save_x = win->_curx;
    int save_y = win->_cury;

    while (count-- > 0) {
	if (waddch_literal(win, blank) == ERR)
	    break;
    }
    win->_curx = (NCURSES_SIZE_T) save_x;
    win->_cury = (NCURSES_SIZE_T) save_y;
}
#endif

/*
 * Build up the bytes for a multibyte character, returning the length when
 * complete (a positive number), -1 for error and -2 for incomplete.
 */
#if USE_WIDEC_SUPPORT
NCURSES_EXPORT(int)
_nc_build_wch(WINDOW *win, ARG_CH_T ch)
{
    char *buffer = WINDOW_EXT(win, addch_work);
    int len;
    int x = win->_curx;
    int y = win->_cury;
    mbstate_t state;
    wchar_t result;

    if ((WINDOW_EXT(win, addch_used) != 0) &&
	(WINDOW_EXT(win, addch_x) != x ||
	 WINDOW_EXT(win, addch_y) != y)) {
	/* discard the incomplete multibyte character */
	WINDOW_EXT(win, addch_used) = 0;
	TR(TRACE_VIRTPUT,
	   ("Alert discarded multibyte on move (%d,%d) -> (%d,%d)",
	    WINDOW_EXT(win, addch_y), WINDOW_EXT(win, addch_x),
	    y, x));
    }
    WINDOW_EXT(win, addch_x) = x;
    WINDOW_EXT(win, addch_y) = y;

    init_mb(state);
    buffer[WINDOW_EXT(win, addch_used)] = (char) CharOf(CHDEREF(ch));
    WINDOW_EXT(win, addch_used) += 1;
    buffer[WINDOW_EXT(win, addch_used)] = '\0';
    if ((len = (int) mbrtowc(&result,
			     buffer,
			     (size_t) WINDOW_EXT(win, addch_used),
			     &state)) > 0) {
	attr_t attrs = AttrOf(CHDEREF(ch));
	if_EXT_COLORS(int pair = GetPair(CHDEREF(ch)));
	SetChar(CHDEREF(ch), result, attrs);
	if_EXT_COLORS(SetPair(CHDEREF(ch), pair));
	WINDOW_EXT(win, addch_used) = 0;
    } else if (len == -1) {
	/*
	 * An error occurred.  We could either discard everything,
	 * or assume that the error was in the previous input.
	 * Try the latter.
	 */
	TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error"));
	/* handle this with unctrl() */
	WINDOW_EXT(win, addch_used) = 0;
    }
    return len;
}
#endif /* USE_WIDEC_SUPPORT */

static
#if !USE_WIDEC_SUPPORT		/* cannot be inline if it is recursive */
NCURSES_INLINE
#endif
int
waddch_literal(WINDOW *win, NCURSES_CH_T ch)
{
    int x;
    int y;
    struct ldat *line;

    x = win->_curx;
    y = win->_cury;

    CHECK_POSITION(win, x, y);

    ch = render_char(win, ch);

    line = win->_line + y;

    CHANGED_CELL(line, x);

    /*
     * Build up multibyte characters until we have a wide-character.
     */
#if NCURSES_SP_FUNCS
#define DeriveSP() SCREEN *sp = _nc_screen_of(win);
#else
#define DeriveSP()		/*nothing */
#endif
    if_WIDEC({
	DeriveSP();
	if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) {
	    int len = _nc_build_wch(win, CHREF(ch));

	    if (len >= -1) {
		attr_t attr = AttrOf(ch);

		/* handle EILSEQ (i.e., when len >= -1) */
		if (len == -1 && is8bits(CharOf(ch))) {
		    int rc = OK;
		    const char *s = NCURSES_SP_NAME(unctrl)
		      (NCURSES_SP_ARGx (chtype) CharOf(ch));

		    if (s[1] != '\0') {
			while (*s != '\0') {
			    rc = waddch(win, UChar(*s) | attr);
			    if (rc != OK)
				break;
			    ++s;
			}
			return rc;
		    }
		}
		if (len == -1)
		    return waddch(win, ' ' | attr);
	    } else {
		return OK;
	    }
	}
    });

    /*
     * Non-spacing characters are added to the current cell.
     *
     * Spacing characters that are wider than one column require some display
     * adjustments.
     */
    if_WIDEC({
	int len = wcwidth(CharOf(ch));
	int i;
	int j;
	wchar_t *chars;

	if (len == 0) {		/* non-spacing */
	    if ((x > 0 && y >= 0)
		|| (win->_maxx >= 0 && win->_cury >= 1)) {
		if (x > 0 && y >= 0)
		    chars = (win->_line[y].text[x - 1].chars);
		else
		    chars = (win->_line[y - 1].text[win->_maxx].chars);
		for (i = 0; i < CCHARW_MAX; ++i) {
		    if (chars[i] == 0) {
			TR(TRACE_VIRTPUT,
			   ("added non-spacing %d: %x",
			    x, (int) CharOf(ch)));
			chars[i] = CharOf(ch);
			break;
		    }
		}
	    }
	    goto testwrapping;
	} else if (len > 1) {	/* multi-column characters */
	    /*
	     * Check if the character will fit on the current line.  If it does
	     * not fit, fill in the remainder of the line with blanks.  and
	     * move to the next line.
	     */
	    if (len > win->_maxx + 1) {
		TR(TRACE_VIRTPUT, ("character will not fit"));
		return ERR;
	    } else if (x + len > win->_maxx + 1) {
		int count = win->_maxx + 1 - x;
		TR(TRACE_VIRTPUT, ("fill %d remaining cells", count));
		fill_cells(win, count);
		if (wrap_to_next_line(win) == ERR)
		    return ERR;
		x = win->_curx;
		y = win->_cury;
		line = win->_line + y;
	    }
	    /*
	     * Check for cells which are orphaned by adding this character, set
	     * those to blanks.
	     *
	     * FIXME: this actually could fill j-i cells, more complicated to
	     * setup though.
	     */
	    for (i = 0; i < len; ++i) {
		if (isWidecBase(win->_line[y].text[x + i])) {
		    break;
		} else if (isWidecExt(win->_line[y].text[x + i])) {
		    for (j = i; x + j <= win->_maxx; ++j) {
			if (!isWidecExt(win->_line[y].text[x + j])) {
			    TR(TRACE_VIRTPUT, ("fill %d orphan cells", j));
			    fill_cells(win, j);
			    break;
			}
		    }
		    break;
		}
	    }
	    /*
	     * Finally, add the cells for this character.
	     */
	    for (i = 0; i < len; ++i) {
		NCURSES_CH_T value = ch;
		SetWidecExt(value, i);
		TR(TRACE_VIRTPUT, ("multicolumn %d:%d (%d,%d)",
				   i + 1, len,
				   win->_begy + y, win->_begx + x));
		line->text[x] = value;
		CHANGED_CELL(line, x);
		++x;
	    }
	    goto testwrapping;
	}
    });

    /*
     * Single-column characters.
     */
    line->text[x++] = ch;
    /*
     * This label is used only for wide-characters.
     */
    if_WIDEC(
  testwrapping:
    );

    TR(TRACE_VIRTPUT, ("cell (%ld, %ld..%d) = %s",
		       (long) win->_cury, (long) win->_curx, x - 1,
		       _tracech_t(CHREF(ch))));

    if (x > win->_maxx) {
	return wrap_to_next_line(win);
    }
    win->_curx = (NCURSES_SIZE_T) x;
    return OK;
}

static NCURSES_INLINE int
waddch_nosync(WINDOW *win, const NCURSES_CH_T ch)
/* the workhorse function -- add a character to the given window */
{
    NCURSES_SIZE_T x, y;
    chtype t = (chtype) CharOf(ch);
#if USE_WIDEC_SUPPORT || NCURSES_SP_FUNCS || USE_REENTRANT
    SCREEN *sp = _nc_screen_of(win);
#endif
    const char *s = NCURSES_SP_NAME(unctrl) (NCURSES_SP_ARGx t);
    int tabsize = 8;

    /*
     * If we are using the alternate character set, forget about locale.
     * Otherwise, if unctrl() returns a single-character or the locale
     * claims the code is printable (and not also a control character),
     * treat it that way.
     */
    if ((AttrOf(ch) & A_ALTCHARSET)
	|| (
#if USE_WIDEC_SUPPORT
	       (sp != 0 && sp->_legacy_coding) &&
#endif
	       s[1] == 0
	)
	|| (
	       (isprint((int)t) && !iscntrl((int)t))
#if USE_WIDEC_SUPPORT
	       || ((sp == 0 || !sp->_legacy_coding) &&
		   (WINDOW_EXT(win, addch_used)
		    || !_nc_is_charable(CharOf(ch))))
#endif
	)) {
	return waddch_literal(win, ch);
    }

    /*
     * Handle carriage control and other codes that are not printable, or are
     * known to expand to more than one character according to unctrl().
     */
    x = win->_curx;
    y = win->_cury;

    switch (t) {
    case '\t':
#if USE_REENTRANT
	tabsize = *ptrTabsize(sp);
#else
	tabsize = TABSIZE;
#endif
	x = (NCURSES_SIZE_T) (x + (tabsize - (x % tabsize)));
	/*
	 * Space-fill the tab on the bottom line so that we'll get the
	 * "correct" cursor position.
	 */
	if ((!win->_scroll && (y == win->_regbottom))
	    || (x <= win->_maxx)) {
	    NCURSES_CH_T blank = blankchar;
	    AddAttr(blank, AttrOf(ch));
	    while (win->_curx < x) {
		if (waddch_literal(win, blank) == ERR)
		    return (ERR);
	    }
	    break;
	} else {
	    wclrtoeol(win);
	    win->_flags |= _WRAPPED;
	    if (newline_forces_scroll(win, &y)) {
		x = win->_maxx;
		if (win->_scroll) {
		    scroll(win);
		    x = 0;
		}
	    } else {
		x = 0;
	    }
	}
	break;
    case '\n':
	wclrtoeol(win);
	if (newline_forces_scroll(win, &y)) {
	    if (win->_scroll)
		scroll(win);
	    else
		return (ERR);
	}
	/* FALLTHRU */
    case '\r':
	x = 0;
	win->_flags &= ~_WRAPPED;
	break;
    case '\b':
	if (x == 0)
	    return (OK);
	x--;
	win->_flags &= ~_WRAPPED;
	break;
    default:
	while (*s) {
	    NCURSES_CH_T sch;
	    SetChar(sch, UChar(*s++), AttrOf(ch));
	    if_EXT_COLORS(SetPair(sch, GetPair(ch)));
	    if (waddch_literal(win, sch) == ERR)
		return ERR;
	}
	return (OK);
    }

    win->_curx = x;
    win->_cury = y;

    return (OK);
}

NCURSES_EXPORT(int)
_nc_waddch_nosync(WINDOW *win, const NCURSES_CH_T c)
/* export copy of waddch_nosync() so the string-put functions can use it */
{
    return (waddch_nosync(win, c));
}

/*
 * The versions below call _nc_synchook().  We wanted to avoid this in the
 * version exported for string puts; they'll call _nc_synchook once at end
 * of run.
 */

/* These are actual entry points */

NCURSES_EXPORT(int)
waddch(WINDOW *win, const chtype ch)
{
    int code = ERR;
    NCURSES_CH_T wch;
    SetChar2(wch, ch);

    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("waddch(%p, %s)"), (void *) win,
				      _tracechtype(ch)));

    if (win && (waddch_nosync(win, wch) != ERR)) {
	_nc_synchook(win);
	code = OK;
    }

    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
    return (code);
}

NCURSES_EXPORT(int)
wechochar(WINDOW *win, const chtype ch)
{
    int code = ERR;
    NCURSES_CH_T wch;
    SetChar2(wch, ch);

    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wechochar(%p, %s)"),
				      (void *) win,
				      _tracechtype(ch)));

    if (win && (waddch_nosync(win, wch) != ERR)) {
	bool save_immed = win->_immed;
	win->_immed = TRUE;
	_nc_synchook(win);
	win->_immed = save_immed;
	code = OK;
    }
    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
    return (code);
}
