/*	Copyright (c) 1988 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

/*
 *      Copyright (c) 1997, by Sun Microsystems, Inc.
 *      All rights reserved.
 */

#pragma ident	"@(#)waddnstr.c	1.11	97/08/14 SMI"	/* SVr4.0 1.3	*/

/*LINTLIBRARY*/

#include	<sys/types.h>
#include	"curses_inc.h"

/* This routine adds a string starting at (_cury, _curx) */

int
waddnstr(WINDOW *win, char *tstr, int i)
{
	chtype	ch;
	short	maxx_1 = win->_maxx - 1, cury = win->_cury,
		curx = win->_curx;
	chtype	**_y = win->_y;
	bool	savimmed = win->_immed,
		savsync = win->_sync;
	int	rv = OK;
	int	pflag;
	unsigned	char *str = (unsigned char *)tstr;

#ifdef	DEBUG
	if (outf) {
		if (win == stdscr)
			fprintf(outf, "waddnstr(stdscr, ");
		else
			fprintf(outf, "waddnstr(%o, ", win);
		fprintf(outf, "\"%s\")\n", str);
	}
#endif	/* DEBUG */

	/* throw away any current partial character */
	win->_nbyte = -1;
	win->_insmode = FALSE;
	pflag = 1;

	win->_immed = win->_sync = FALSE;

	if (i < 0)
		i = MAXINT;

	while (((ch = *str) != 0) && (i-- > 0)) {
		if (pflag == 1) {
			if (_scrmax > 1 && (rv = _mbvalid(win)) == ERR)
				break;
			curx = win->_curx;
			cury = win->_cury;
		}
		if (_mbtrue && ISMBIT(ch)) {
			int	m, k, ty;
			chtype		c;
			/* make sure we have the whole character */
			c = RBYTE(ch);
			ty = TYPE(c);
			m = cswidth[ty] - (ty == 0 ? 1 : 0);
			for (k = 1; str[k] != '\0' && k <= m; ++k)
				if (!ISMBIT(str[k]))
					break;
			if (k <= m)
				break;
			if (m > i)
				break;
			for (k = 0; k <= m; ++k, ++str) {
				if ((rv = _mbaddch(win, A_NORMAL,
				    RBYTE(*str))) == ERR)
					goto done;
				if (k > 0)
					i--;
			}
			pflag = 1;
			cury = win->_cury;
			curx = win->_curx;
			continue;
		}

		/* do normal characters while not next to edge */
		if ((ch >= ' ') && (ch != _CTRL('?')) && (curx < maxx_1)) {
			if (_scrmax > 1 && ISMBIT(_y[cury][curx]) &&
			    (rv = _mbclrch(win, cury, curx)) == ERR)
				break;
			if (curx < win->_firstch[cury])
				win->_firstch[cury] = curx;
			if (curx > win->_lastch[cury])
				win->_lastch[cury] = curx;
			ch = _WCHAR(win, ch);
			_y[cury][curx] = ch;
#ifdef	_VR3_COMPAT_CODE
			if (_y16update)
				/* LINTED */
				win->_y16[cury][curx] = _TO_OCHTYPE(ch);
#endif	/* _VR3_COMPAT_CODE */
			curx++;
			pflag = 0;
		} else {
			win->_curx = curx;
			/* found a char that is too tough to handle above */
			if (waddch(win, ch) == ERR) {
				rv = ERR;
				break;
			}
			cury = win->_cury;
			curx = win->_curx;
			pflag = 1;
		}
		str++;
		win->_curx = curx;
	}

done :
	win->_curx = curx;
	win->_flags |= _WINCHANGED;
	win->_sync = savsync;
	if (win->_sync)
		wsyncup(win);

	return ((win->_immed = savimmed) ? wrefresh(win) : rv);
}
