// * this is for making emacs happy: -*-Mode: C++;-*-
/****************************************************************************
 * Copyright (c) 2007-2012,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.                                                           *
 ****************************************************************************/

/*
 * Authors:
 *	Thomas E. Dickey
 *	Juergen Pfeifer
 *
 * The NCursesWindow class was originally based on a file written by
 * Eric Newton, later modified by Ulrich Drepper and Anatoly Ivasyuk.
 * However, aside from the compatible interface definition, no trace
 * of the original code remains in this version: it consists only of
 * changes introduced since 1995.
 */

#include "internal.h"
#include "cursesw.h"

MODULE_ID("$Id: cursesw.cc,v 1.54 2014/02/01 22:10:42 tom Exp $")

#define COLORS_NEED_INITIALIZATION  -1
#define COLORS_NOT_INITIALIZED       0
#define COLORS_MONOCHROME            1
#define COLORS_ARE_REALLY_THERE      2

#define HaveColors() (colorInitialized == COLORS_ARE_REALLY_THERE)

// declare static variables for the class
long NCursesWindow::count = 0L;
bool NCursesWindow::b_initialized = FALSE;

int
NCursesWindow::scanw(const char* fmt, ...)
{
    int result = ERR;

    va_list args;
    va_start(args, fmt);
    result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
    va_end(args);

    return result;
}


int
NCursesWindow::scanw(int y, int x, const char* fmt, ...)
{
    int result = ERR;

    if (::wmove(w, y, x) != ERR) {
	va_list args;
	va_start(args, fmt);
	result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
	va_end(args);
    }
    return result;
}


int
NCursesWindow::scanw(const char* fmt, va_list args)
{
    int result = ERR;

    result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);

    return result;
}


int
NCursesWindow::scanw(int y, int x, const char* fmt, va_list args)
{
    int result = ERR;

    if (::wmove(w, y, x) != ERR) {
	result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
    }
    return result;
}


int
NCursesWindow::printw(const char * fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    int result = ::vw_printw(w, fmt, args);
    va_end(args);
    return result;
}


int
NCursesWindow::printw(int y, int x, const char * fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    int result = ::wmove(w, y, x);
    if (result == OK) {
	result = ::vw_printw(w, fmt, args);
    }
    va_end(args);
    return result;
}


int
NCursesWindow::printw(const char * fmt, va_list args)
{
    int result = ::vw_printw(w, fmt, args);
    return result;
}


int
NCursesWindow::printw(int y, int x, const char * fmt, va_list args)
{
    int result = ::wmove(w, y, x);
    if (result == OK) {
	result = ::vw_printw(w, fmt, args);
    }
    return result;
}


void
NCursesWindow::set_keyboard(void)
{
    keypad(TRUE);
    meta(TRUE);
}

void
NCursesWindow::err_handler(const char *msg) const THROWS(NCursesException)
{
  THROW(new NCursesException(msg));
}

void
NCursesWindow::initialize()
{
    if (!b_initialized) {
	::initscr();
	b_initialized = TRUE;
	if (colorInitialized == COLORS_NEED_INITIALIZATION) {
	    colorInitialized = COLORS_NOT_INITIALIZED;
	    useColors();
	}
	::noecho();
	::cbreak();
    }
}

void
NCursesWindow::constructing()
{
    initialize();
    ++count;
}

NCursesWindow::NCursesWindow()
  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
{
    constructing();

    w = static_cast<WINDOW *>(0);
}

NCursesWindow::NCursesWindow(int nlines, int ncols, int begin_y, int begin_x)
  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
{
    constructing();

    w = ::newwin(nlines, ncols, begin_y, begin_x);
    if (w == 0) {
	err_handler("Cannot construct window");
    }
    set_keyboard();
}

NCursesWindow::NCursesWindow(WINDOW* window)
  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
{
    constructing();

    // We used to use a reference on the "window" parameter, but we cannot do
    // that with an opaque pointer (see NCURSES_OPAQUE).  If the parameter was
    // "::stdscr", that is first set via the "constructing() call, and is null
    // up to that point.  So we allow a null pointer here as meaning the "same"
    // as "::stdscr".
    w = window ? window : ::stdscr;
    set_keyboard();
}

NCursesWindow::NCursesWindow(NCursesWindow& win, int ny, int nx,
			     int begin_y, int begin_x, char absrel)
  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
{
    constructing();
    if (absrel == 'a') {	// absolute origin
	begin_y -= win.begy();
	begin_x -= win.begx();
    }

    // Link this window into its parent's list of subwindows.
    // We use derwin(), since this also works for pads.
    w = ::derwin(win.w, ny, nx, begin_y, begin_x);
    if (w == 0) {
	err_handler("Cannot construct subwindow");
    }

    par = &win;
    sib = win.subwins;
    win.subwins = this;
}

NCursesWindow::NCursesWindow(NCursesWindow& win,
				bool do_box NCURSES_PARAM_INIT(TRUE))
  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
{
    constructing();
    int myHeight = win.height();
    int myWidth  = win.width();
    w = :: derwin(win.w, myHeight - 2, myWidth - 2, 1, 1);
    if (w == 0) {
	err_handler("Cannot construct subwindow");
    }

    par = &win;
    sib = win.subwins;
    win.subwins = this;
    subwins = 0;

    if (do_box) {
	win.box();
	win.touchwin();
    }
}

NCursesWindow NCursesWindow::Clone()
{
    WINDOW *d = ::dupwin(w);
    NCursesWindow W(d);
    W.subwins = subwins;
    W.sib = sib;
    W.par = par;
    W.alloced = alloced;
    return W;
}

typedef int (*RIPOFFINIT)(NCursesWindow&);
static RIPOFFINIT R_INIT[5];       // There can't be more
static int r_init_idx   = 0;
static RIPOFFINIT* prip = R_INIT;

NCursesWindow::NCursesWindow(WINDOW *win, int ncols)
  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
{
    (void) ncols;
    initialize();
    w = win;
}

int _nc_xx_ripoff_init(WINDOW *w, int ncols)
{
    (void) ncols;
    int res = ERR;

    RIPOFFINIT init = *prip++;
    if (init) {
	res = init(*(new NCursesWindow(w,ncols)));
    }
    return res;
}

int NCursesWindow::ripoffline(int ripoff_lines,
			      int (*init)(NCursesWindow& win))
{
    int code = ::_nc_ripoffline(ripoff_lines,_nc_xx_ripoff_init);
    if (code == OK && init && ripoff_lines) {
	R_INIT[r_init_idx++] = init;
    }
    return code;
}

bool
NCursesWindow::isDescendant(NCursesWindow& win)
{
    bool result = FALSE;

    for (NCursesWindow* p = subwins; p != NULL; p = p->sib) {
	if (p == &win || p->isDescendant(win)) {
	    result = TRUE;
	    break;
	}
    }
    return result;
}

void
NCursesWindow::kill_subwindows()
{
    NCursesWindow* p = subwins;

    subwins = 0;
    while (p != 0) {
	NCursesWindow* q = p->sib;
	p->kill_subwindows();
	if (p->alloced) {
	    if (p->w != 0)
		::delwin(p->w);
	}
	delete p;
	p = q;
    }
}


NCursesWindow::~NCursesWindow()
{
    kill_subwindows();

    if (par != 0) {
	// Remove this window from the parent's list of subwindows.
	NCursesWindow * next = par->subwins;
	NCursesWindow * prev = 0;
	while (next != 0) {
	    if (next == this) {
		if (prev != 0) {
		    prev->sib = next->sib;
		} else {
		    par->subwins = next->sib;
		}
		break;
	    }
	    prev = next;
	    next = next->sib;
	}
    }

    if (alloced && w != 0)
	::delwin(w);

    if (alloced) {
	--count;
	if (count == 0) {
	    ::endwin();
	} else if (count < 0) { // cannot happen!
	    err_handler("Too many windows destroyed");
	}
    }
}

// ---------------------------------------------------------------------
// Color stuff
//
int NCursesWindow::colorInitialized = COLORS_NOT_INITIALIZED;

void
NCursesWindow::useColors(void)
{
    if (colorInitialized == COLORS_NOT_INITIALIZED) {
	if (b_initialized) {
	    if (::has_colors()) {
		::start_color();
		colorInitialized = COLORS_ARE_REALLY_THERE;
	    } else {
		colorInitialized = COLORS_MONOCHROME;
	    }
	} else {
	    colorInitialized = COLORS_NEED_INITIALIZATION;
	}
    }
}

NCURSES_PAIRS_T
NCursesWindow::getPair() const
{
    return static_cast<NCURSES_PAIRS_T>(PAIR_NUMBER(getattrs(w)));
}

NCURSES_COLOR_T
NCursesWindow::getcolor(int getback) const
{
    NCURSES_COLOR_T fore, back;

    if (HaveColors()) {
	if (::pair_content(getPair(), &fore, &back) == ERR)
	    err_handler("Can't get color pair");
    } else {
	// Monochrome means white on black
	back = COLOR_BLACK;
	fore = COLOR_WHITE;
    }
    return getback ? back : fore;
}

int NCursesWindow::NumberOfColors()
{
    return (HaveColors()) ? COLORS : 1;
}

NCURSES_PAIRS_T
NCursesWindow::getcolor() const
{
    return (HaveColors()) ? getPair() : 0;
}

int
NCursesWindow::setpalette(NCURSES_COLOR_T fore, NCURSES_COLOR_T back, NCURSES_PAIRS_T pair)
{
    return (HaveColors()) ? ::init_pair(pair, fore, back) : OK;
}

int
NCursesWindow::setpalette(NCURSES_COLOR_T fore, NCURSES_COLOR_T back)
{
    return setpalette(fore, back, getPair());
}


int
NCursesWindow::setcolor(NCURSES_PAIRS_T pair)
{
    if (HaveColors()) {
	if ((pair < 1) || (pair > COLOR_PAIRS))
	    err_handler("Can't set color pair");

	attroff(A_COLOR);
	attrset(COLOR_PAIR(pair));
    }
    return OK;
}

#if HAVE_HAS_KEY
bool NCursesWindow::has_mouse() const
{
    return ((::has_key(KEY_MOUSE) || ::has_mouse())
	     ? TRUE : FALSE);
}
#endif
