/*
 *	$Source$
 *	$Author$
 *	$Header$
 */

#ifndef lint
static char *rcsid_cwindows_c = "$Header$";
#endif lint

#include <stdio.h>
#include <sys/types.h>
#include <curses.h>
#include "cwindows.h"

CWINDOW	*COpen()
{
	initscr();		/* Initialize curses */

	rootcw = (CWINDOW *) malloc(sizeof(CWINDOW));
	rootcw->_transparent = FALSE;
	rootcw->mapped = TRUE;
	rootcw->boxed = FALSE;
	rootcw->child = NULL;
	rootcw->nextsib = NULL;
	rootcw->prevsib = NULL;
	rootcw->parent = NULL;
	rootcw->w = newwin(0,0,0,0);
	rootcw->clip = newwin(0,0,0,0);
	rootcw->name = strdup("C Windows Root Window");
	_C_autosync = 0;
	return(rootcw);
}

CClose()
{
	CWINDOW *root;

	root = rootcw;
	rootcw = NULL;
	CDestroyWindow(root);
	clear();
	move(LINES,COLS);
	refresh();
	endwin();
}


CWINDOW *CCreateWindow(parent, name, lines, cols, begin_y, begin_x)
	CWINDOW	*parent;
	char	*name;
	int	lines, cols;
	int	begin_y, begin_x;
{
	CWINDOW	*child;

	child = (CWINDOW *) malloc(sizeof(CWINDOW));
	child->_transparent = FALSE;
	child->mapped = FALSE;
	child->boxed = FALSE;
	child->child = NULL;
	child->parent = parent;
	child->nextsib = parent->child;
	child->prevsib = NULL;
	if (parent->child)
		parent->child->prevsib = child;
	parent->child = child;
	child->w = newwin(lines, cols,
			  begin_y+parent->w->_begy,
			  begin_x+parent->w->_begx);
	child->clip = newwin(lines, cols,
			  begin_y+parent->w->_begy,
			  begin_x+parent->w->_begx);
	if (name)
		child->name = strdup(name);
	else
		child->name = NULL;
	if (_C_autosync)
		CSync();
	return(child);
}

CMapWindow(cw)
	CWINDOW *cw;
{
	cw->mapped = TRUE;
	if (_C_autosync)
		CSync();
}

CUnmapWindow(cw)
	CWINDOW	*cw;
{
	if (cw != rootcw)
		cw->mapped = FALSE;
	if (_C_autosync)
		CSync();
}

CBoxWindow(cw)
	CWINDOW	*cw;
{
	register WINDOW *w = cw->w;
	
	if (!cw->boxed) {
		delwin(cw->clip);
		cw->clip = newwin(w->_maxy+2, w->_maxx+2,
				  w->_begy-1, w->_begx-1);
		box(cw->clip, '|', '-');
		cw->boxed = 1;
	}
}

CUnBoxWindow(cw)
	CWINDOW	*cw;
{
	register WINDOW *w = cw->w;
	
	if (cw->boxed) {
		delwin(cw->clip);
		cw->clip = newwin(w->_maxy, w->_maxx,
				  w->_begy, w->_begx);
		cw->boxed = 0;
	}
}

CText(cw, x, y, text)
	CWINDOW	*cw;
	int	x, y;
	char	*text;
{
	register int	oldy;
	
	oldy = y;
	wmove(cw->w, x, y);
	while (*text) {
		waddch(cw->w, *text);
		if (oldy != cw->w->_cury)
			break;
	}
}

CDestroyWindow(cw)
	CWINDOW	*cw;
{
	CWINDOW *child, *next;
	
	if (cw == rootcw) {
		fprintf(stderr, "Attempt to free root C window!\n");
		abort();
	}
	if (cw->prevsib)
		cw->prevsib->nextsib = cw->nextsib;
	else
		if (cw->parent)
			cw->parent->child = cw->nextsib;
	if (cw->nextsib)
		cw->nextsib->prevsib = cw->prevsib;
	delwin(cw->w);
	delwin(cw->clip);
	child = cw->child;
	while (child) {
		next = child->nextsib;
		CDestroyWindow(child);
		child = next;
	}
	if (cw->name)
		free(cw->name);
	free(cw);
	if (_C_autosync)
		CSync();
}


_CWriteWindow(cw, dest_window)
	CWINDOW	*cw;
	WINDOW	*dest_window;
{
	CWINDOW *child;
	
	if (!cw->mapped)
		return;
#ifndef notdef
	if (!cw->child && !cw->boxed) {
		if (cw->_transparent)
			overlay(cw->w, dest_window);
		else
			overwrite(cw->w, dest_window);
	} else {
		overwrite(cw->w, cw->clip);
		child = cw->child;
		if (child)
			while (child->nextsib) child = child->nextsib;
		while (child) {
			_CWriteWindow(child, cw->clip);
			child = child->prevsib;
		}
		if (cw->_transparent)
			overlay(cw->clip, dest_window);
		else
			overwrite(cw->clip, dest_window);
	}
#else
	if (cw->_transparent)
		overlay(cw->w, dest_window);
	else
		overwrite(cw->w, dest_window);
	child = cw->child;
	if (child)
		while (child->nextsib) child = child->nextsib;
	while (child) {
		_CWriteWindow(child, dest_window);
		child = child->prevsib;
	}
	
#endif
}
	
CSync()
{
	_CWriteWindow(rootcw, stdscr);
	refresh();
}

CGetWindowLocX(cw)
	CWINDOW	*cw;
{
	return(cw->w->_begx);
}


CGetWindowLocY(cw)
	CWINDOW *cw;
{
	return(cw->w->_begy);
}

CGetCursorLocX(cw)
	CWINDOW *cw;
{
	return(cw->w->_curx);
}

CGetCursorLocY(cw)
	CWINDOW *cw;
{
	return(cw->w->_cury);
}

CGetSizeX(cw)
	CWINDOW *cw;
{
	return(cw->w->_maxx);
}

CGetSizeY(cw)
	CWINDOW *cw;
{
	return(cw->w->_maxy);
}
