/*
 *  ElysianWorld JavaScript Library
 * -----------------------------------
 *
 * Copyright (c) 2005 Cherie & Madou Media GmbH <minah@aziz.am>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


/**********************************************************
 * Basic functionality
 **********************************************************/

/*
 * elysianPageSwitchUrl
 *
 * Change the current page from JavaScript
 *
 */

function elysianPageSwitchUrl(_url)
{
	if (elysianBrowser == BROWSER_SAFARI)
		top.location = _url;
	else
		top.location.href = _url;
}


/*
 * elysianParentSwitchUrl
 *
 * Change the parent page from JavaScript
 *
 */

function elysianParentSwitchUrl(_url)
{
	if (elysianBrowser == BROWSER_SAFARI)
		window.elyParent.location = _url;
	else
		window.elyParent.location.href = _url;
}


/**********************************************************
 * Utility objects
 **********************************************************/


/*
 * ElysianSpot
 *
 * The area which an element occupies
 *
 */

function ElysianSpot(_left, _top, _right, _bottom)
{
	this.left = _left;
	this.top = _top;
	this.right = _right;
	this.bottom = _bottom;
	
}


/**********************************************************
 * Various functions for accessing the DOM tree
 **********************************************************/


var elysianWorld = this;


/*
 * elysianElementGet
 *
 * Get an element by its ID
 *
 */

var elysianElementGet;
var bmode = 0;

if (elysianBrowser == BROWSER_NETSCAPE && elysianBrowserVersion < 6.0)
		bmode = 1;
else if (elysianBrowser == BROWSER_IE && elysianBrowserVersion < 5.0)
		bmode = 2;

if (bmode == 0) {
	elysianElementGet = function(_name) {
		return elysianWorld.document.getElementById(_name)
	};
} else if (bmode == 1) {
	elysianElementGet = function(_name) {
		return elysianWorld.document[_name];
	};
} else if (bmode == 2) {
	elysianElementGet = function(_name) {
		return elysianWorld[_name];
	};
}


/*
 * elysianElementSpot
 *
 * Get an element's "spot" in the browser window or frame.
 *
 */

function elysianElementSpot(_element)
{
	var left = _element.offsetLeft,
	    top = _element.offsetTop,
	    right = _element.offsetLeft + _element.offsetWidth,
	    bottom = _element.offsetTop + _element.offsetHeight;


	while ((_element = _element.offsetParent) != null) {
		if (_element.offsetLeft) {
			left += _element.offsetLeft;
			right += _element.offsetLeft;
		}

		if (_element.offsetTop) {
			top += _element.offsetTop;
			bottom += _element.offsetTop;
		}
	}

	return new ElysianSpot(left, top, right, bottom);
}


function elysianElementRelativeSpot(_element, _parent)
{
	var left = _element.offsetLeft,
	    top = _element.offsetTop,
	    right = _element.offsetLeft + _element.offsetWidth,
	    bottom = _element.offsetTop + _element.offsetHeight;


	while ((_element = _element.offsetParent) != _parent.offsetParent) {
		if (_element.offsetLeft) {
			left += _element.offsetLeft;
			right += _element.offsetLeft;
		}

		if (_element.offsetTop) {
			top += _element.offsetTop;
			bottom += _element.offsetTop;
		}
	}

	return new ElysianSpot(left, top, right, bottom);
}


/*
 * elysianElementSetContent
 *
 * Dynamically update the contents of a <div> element
 *
 */

function elysianElementSetContent(_element, _xml)
{
	if (elysianBrowser == BROWSER_IE) {
		_element.innerHTML = _xml;
	} else {
		var parser = new DOMParser();
		var text = '<div xmlns="http://www.w3.org/1999/xhtml">' + _xml + '</div>';
		var newdiv = parser.parseFromString(text, 'application/xhtml+xml');
		var newtree = newdiv.documentElement;
		var node;

		while (_element.firstChild)
			_element.removeChild(_element.firstChild);
		for (var i = 0; i < newtree.childNodes.length; ++i) {
			node = document.importNode(newtree.childNodes[i], true);
			_element.appendChild(node);
		}
	}
}


function elysianElementSetContentJs(_element, _xml)
{
	var jsStart;
	var jsEnd;
	var js;

	jsStart = _xml.indexOf('<script type="text/javascript">');
	jsEnd = _xml.indexOf('</script>');
	if (jsStart != -1 && jsEnd != -1)
		js = _xml.substr(jsStart + 31, jsEnd - jsStart - 31);
	else
		js = '';

	if (elysianBrowser == BROWSER_IE) {
		_element.innerHtml = _xml;
	} else {
		var parser = new DOMParser();
		var text = '<div xmlns="http://www.w3.org/1999/xhtml">' + _xml + '</div>';
		var newdiv = parser.parseFromString(text, 'application/xhtml+xml');
		var newtree = newdiv.documentElement;
		var node;

		while (_element.firstChild)
			_element.removeChild(_element.firstChild);
		for (var i = 0; i < newtree.childNodes.length; ++i) {
			node = document.importNode(newtree.childNodes[i], true);
			_element.appendChild(node);
		}
	}

	return js;
}


/*
 * ElysianRequest
 *
 * An object for sending HTTP requests
 *
 */

function ElysianRequest() {
	if (elysianBrowser == BROWSER_IE) {
		try {
			this.request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (oldVersion) {
			try {
				this.request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(failed) {
				this.request = false;
			}
		}
	} else
		this.request = new XMLHttpRequest();

	this.getRequest = function(_url) {
		var async = this.onStateChange ? true : false;

		if (!this.request)
			return false;

		if (async)
			this.request.onreadystatechange = this.onStateChange;

		if (elysianBrowser == BROWSER_MOZILLA)
			this.request.overrideMimeType('text/xml');
		this.request.open("GET", _url, async);
		this.request.send(null);

		if (async)
			return true;
		else {
			if (this.request.readystate == 4 && this.request.status == 200)
				return this.request.responseText;
			else
				return false;
		}
	}
}


/*
 * elysianDocumentGet
 *
 * Request a document a web server
 *
 */

function elysianDocumentGet(_url)
{
	var req = elysianRequestCreate();


}



/**********************************************************
 * User Interface
 **********************************************************/


/*
 * ElysianButtonStyle
 *
 * An object that contains backgrounds for a button's left edge,
 * text area, and right edge.
 *
 */

function ElysianButtonStyle(_left, _center, _right) {

	// Let's preload the images

	this.leftImage = new Image();
	this.centerImage = new Image();
	this.rightImage = new Image();

	this.leftImage.src = _left;
	this.centerImage.src = _center;
	this.rightImage.src = _right;

	this.left = 'url(' + _left + ')';
	this.center = 'url(' + _center + ')';
	this.right = 'url(' + _right + ')';
}


/*
 * ElysianToggleButtonStyle
 *
 * An object that contains a background image for toggle buttons.
 *
 */

function ElysianToggleButtonStyle(_background) {

	// Let's preload the images

	this.backgroundImage = new Image();
	this.backgroundImage.src = _background;
	this.background = 'url(' + _background + ')';
}


/*
 * ElysianCheckboxStyle
 *
 * An object that contains on/off images for checkboxes
 *
 */

function ElysianCheckboxStyle(_on, _off) {
	this.onImage = new Image();
	this.onImage.src = _on;
	this.offImage = new Image();
	this.offImage.src = _off;
}


/*
 * ElysianStyle
 *
 * An object that contains bakcgrounds and other style attributes
 * for various UI elements.
 *
 */

var elysianStyles = new Array();

function ElysianStyle(_name) {

	this.name = _name;
	elysianStyles[_name] = this;

	this.buttons = new Array();
	this.toggleButtons = new Array();
	this.checkboxes = new Array();

	this.addButtonState = function(_button, _left, _center, _right) {
		if (!this.buttons[_button])
			this.buttons[_button] = new Array();
		this.buttons[_button][this.buttons[_button].length] = new ElysianButtonStyle(_left, _center, _right);
	}

	this.addToggleButtonState = function(_button, _background) {
		if (!this.toggleButtons[_button])
			this.toggleButtons[_button] = new Array();
		this.toggleButtons[_button][this.toggleButtons[_button].length] = new ElysianToggleButtonStyle(_background);
	}

	this.addCheckbox = function(_checkbox, _on, _off) {
		this.checkboxes[_checkbox] = new ElysianCheckboxStyle(_on, _off);
	}
}


/*
 * ElysianButton
 *
 * An animated button which is normally used to submit forms
 *
 */

var elysianButtons = new Array();

function ElysianButton(_name, _style, _button) {

	elysianButtons[_name] = this;
	this.name = _name;

	this.buttonDivLeft = elysianElementGet(_name + '_left');
	this.buttonImgLeft = elysianElementGet(_name + '_left_img');
	this.buttonDivCenter = elysianElementGet(_name + '_center');
	this.buttonDivRight = elysianElementGet(_name + '_right');
	this.buttonImgRight = elysianElementGet(_name + '_right_img');

	tmpstyle = elysianStyles[_style];
	if (tmpstyle)
		this.style = tmpstyle.buttons[_button];
	else
		this.style = null;

	this.state = 0;

	this.timer = null;

	this.setState = function(_state) {
		this.state = _state;
		this.buttonImgLeft.src = this.style[_state].leftImage.src;
		this.buttonDivCenter.style.backgroundImage = this.style[_state].center;
		this.buttonImgRight.src = this.style[_state].rightImage.src;
	}

	this.fadeIn = function() {
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state < this.style.length - 1) {
			this.setState(this.state + 1);
			if (this.state < this.style.length - 1)
				this.timer = window.setTimeout("elysianButtons['" + this.name + "'].fadeIn()", 70);
		}
	}

	this.fadeOut = function() {
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state > 0) {
			this.setState(this.state - 1);
			if (this.state > 0)
				this.timer = window.setTimeout("elysianButtons['" + this.name + "'].fadeOut()", 50);
		}
	}

	this.click = function() {
		alert('clicked');
	}

	this.enter = function() {
		if (this.style)
			this.fadeIn();
	}

	this.leave = function() {
		if (this.style)
			this.fadeOut();
	}

	this.clickHandler = function() {
		if (this.click)
			this.click();
	}

	eval('this.buttonDivLeft.onmouseover = function () {elysianButtons["' + this.name + '"].enter();}');
	eval('this.buttonDivCenter.onmouseover = function () {elysianButtons["' + this.name + '"].enter();}');
	eval('this.buttonDivRight.onmouseover = function () {elysianButtons["' + this.name + '"].enter();}');

	eval('this.buttonDivLeft.onmouseout = function () {elysianButtons["' + this.name + '"].leave();}');
	eval('this.buttonDivCenter.onmouseout = function () {elysianButtons["' + this.name + '"].leave();}');
	eval('this.buttonDivRight.onmouseout = function () {elysianButtons["' + this.name + '"].leave();}');

	eval('this.buttonDivLeft.onclick = function () {elysianButtons["' + this.name + '"].clickHandler();}');
	eval('this.buttonDivCenter.onclick = function () {elysianButtons["' + this.name + '"].clickHandler();}');
	eval('this.buttonDivRight.onclick = function () {elysianButtons["' + this.name + '"].clickHandler();}');
}



/*
 * ElysianTabButton
 *
 * An animated button which forms part of a tabset
 *
 */

var elysianTabButtons = new Array();

function ElysianTabButton(_name, _style, _onbutton, _offbutton) {

	elysianTabButtons[_name] = this;
	this.name = _name;

	this.buttonDivLeft = elysianElementGet(_name + '_left');
	this.buttonImgLeft = elysianElementGet(_name + '_left_img');
	this.buttonDivCenter = elysianElementGet(_name + '_center');
	this.buttonDivRight = elysianElementGet(_name + '_right');
	this.buttonImgRight = elysianElementGet(_name + '_right_img');
	this.group = null;
	this.value = false;

	tmpstyle = elysianStyles[_style];
	if (tmpstyle) {
		this.onstyle = tmpstyle.buttons[_onbutton];
		this.offstyle = tmpstyle.buttons[_offbutton];
	} else {
		this.onstyle = null;
		this.offstyle = null;
	}

	this.state = 0;

	this.timer = null;

	this.setState = function(_state) {
		this.state = _state;
		if (this.value) {
			this.buttonImgLeft.src = this.onstyle[_state].leftImage.src;
			this.buttonDivCenter.style.backgroundImage = this.onstyle[_state].center;
			this.buttonImgRight.src = this.onstyle[_state].rightImage.src;
		} else {
			this.buttonImgLeft.src = this.offstyle[_state].leftImage.src;
			this.buttonDivCenter.style.backgroundImage = this.offstyle[_state].center;
			this.buttonImgRight.src = this.offstyle[_state].rightImage.src;
		}
	}

	this.fadeIn = function() {
		var s = (this.value ? this.onstyle.length - 1 : this.offstyle.length - 1);

		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state < s) {
			this.setState(this.state + 1);
			if (this.state < s)
				this.timer = window.setTimeout("elysianTabButtons['" + this.name + "'].fadeIn()", 70);
		}
	}

	this.fadeOut = function() {
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state > 0) {
			this.setState(this.state - 1);
			if (this.state > 0)
				this.timer = window.setTimeout("elysianTabButtons['" + this.name + "'].fadeOut()", 50);
		}
	}

	this.enter = function() {
		if (this.value ? this.onstyle : this.offstyle)
			this.fadeIn();
	}

	this.leave = function() {
		if (this.value ? this.onstyle : this.offstyle)
			this.fadeOut();
	}

	this.clickHandler = function() {
		if (!this.value)
			this.group.setActive(this.name);
	}

	this.activate = function() {
		this.value = true;
		this.setState(this.onstyle.length - 1);
		if (this.onActivate)
			this.onActivate();
	}

	this.deactivate = function() {
		this.value = false;
		this.setState(0);
		if (this.onDeactivate)
			this.onDeactivate();
	}

	eval('this.buttonDivLeft.onmouseover = function () {elysianTabButtons["' + this.name + '"].enter();}');
	eval('this.buttonDivCenter.onmouseover = function () {elysianTabButtons["' + this.name + '"].enter();}');
	eval('this.buttonDivRight.onmouseover = function () {elysianTabButtons["' + this.name + '"].enter();}');

	eval('this.buttonDivLeft.onmouseout = function () {elysianTabButtons["' + this.name + '"].leave();}');
	eval('this.buttonDivCenter.onmouseout = function () {elysianTabButtons["' + this.name + '"].leave();}');
	eval('this.buttonDivRight.onmouseout = function () {elysianTabButtons["' + this.name + '"].leave();}');

	eval('this.buttonDivLeft.onclick = function () {elysianTabButtons["' + this.name + '"].clickHandler();}');
	eval('this.buttonDivCenter.onclick = function () {elysianTabButtons["' + this.name + '"].clickHandler();}');
	eval('this.buttonDivRight.onclick = function () {elysianTabButtons["' + this.name + '"].clickHandler();}');
}


function ElysianTabSet() {

	this.tabs = new Array();
	this.activeTab = null;

	this.addTab = function(_button) {
		this.tabs[_button.name] = _button;
		_button.group = this;
	}

	this.setActive = function(_name) {
		if (this.activeTab)
			this.activeTab.deactivate();
		this.activeTab = this.tabs[_name];
		this.activeTab.activate();
	}
}



/*
 * ElysianToggleButton
 *
 * An animated button which is normally used to submit forms
 *
 */

var elysianToggleButtons = new Array();

function ElysianToggleButton(_name, _style, _onbutton, _offbutton, _initial) {

	elysianToggleButtons[_name] = this;
	this.name = _name;

	this.buttonDiv = elysianElementGet(_name);
	this.helpDiv = elysianElementGet(_name + '_help');

	tmpstyle = elysianStyles[_style];
	if (tmpstyle) {
		this.onstyle = tmpstyle.toggleButtons[_onbutton];
		this.offstyle = tmpstyle.toggleButtons[_offbutton];
	} else {
		this.onstyle = null;
		this.offstyle = null;
	}

	this.state = 0;
	this.value = _initial;

	this.timer = null;

	this.setState = function(_state) {
		this.state = _state;
		if (this.value)
			this.buttonDiv.style.backgroundImage = this.onstyle[_state].background;
		else
			this.buttonDiv.style.backgroundImage = this.offstyle[_state].background;
	}

	this.fadeIn = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state < s.length - 1) {
			this.setState(this.state + 1);
			if (this.state < s.length - 1)
				this.timer = window.setTimeout("elysianToggleButtons['" + this.name + "'].fadeIn()", 70);
		}
	}

	this.fadeOut = function() {
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state > 0) {
			this.setState(this.state - 1);
			if (this.state > 0)
				this.timer = window.setTimeout("elysianToggleButtons['" + this.name + "'].fadeOut()", 50);
		}
	}

	this.click = function() {
	}

	this.showHelpBubble = function() {
		var left;
		var top;
		var anchorSpot;

		if (this.helpDiv != null) {
			anchorSpot = elysianElementSpot(this.buttonDiv),
			this.helpDiv.style.display = 'block';
			left = anchorSpot.left;
			top = anchorSpot.bottom + 2;
			this.helpDiv.style.left = left.toString() + 'px';
			this.helpDiv.style.top = top.toString() + 'px';
		}
	}

	this.hideHelp = function() {
		if (this.helpDiv != null) {
			this.helpDiv.style.display = 'none';
		}
	}

	this.enter = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (s)
			this.fadeIn();
		this.showHelpBubble();
	}

	this.leave = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (s)
			this.fadeOut();
		this.hideHelp();
	}

	this.clickHandler = function() {
		this.value = this.value ? 0 : 1;
		if (this.value)
			this.setState(this.onstyle.length - 1);
		else
			this.setState(this.offstyle.length - 1);

		if (this.click)
			this.click();
	}

	this.setState(0);

	eval('this.buttonDiv.onmouseover = function () {elysianToggleButtons["' + this.name + '"].enter();}');
	eval('this.buttonDiv.onmouseout = function () {elysianToggleButtons["' + this.name + '"].leave();}');
	eval('this.buttonDiv.onclick = function () {elysianToggleButtons["' + this.name + '"].clickHandler();}');
}


function ElysianImageToggleButton(_name, _style, _onbutton, _offbutton, _initial) {

	elysianToggleButtons[_name] = this;
	this.name = _name;

	this.buttonImage = elysianElementGet(_name + '_img');
	this.labelDiv = elysianElementGet(_name + '_label');
	this.helpDiv = elysianElementGet(_name + '_help');

	tmpstyle = elysianStyles[_style];
	if (tmpstyle) {
		this.onstyle = tmpstyle.toggleButtons[_onbutton];
		this.offstyle = tmpstyle.toggleButtons[_offbutton];
	} else {
		this.onstyle = null;
		this.offstyle = null;
	}

	this.state = 0;
	this.value = _initial;

	this.timer = null;

	this.setState = function(_state) {
		this.state = _state;
		if (this.value)
			this.buttonImage.src = this.onstyle[_state].backgroundImage.src;
		else
			this.buttonImage.src = this.offstyle[_state].backgroundImage.src;
	}

	this.fadeIn = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state < s.length - 1) {
			this.setState(this.state + 1);
			if (this.state < s.length - 1)
				this.timer = window.setTimeout("elysianToggleButtons['" + this.name + "'].fadeIn()", 70);
		}
	}

	this.fadeOut = function() {
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state > 0) {
			this.setState(this.state - 1);
			if (this.state > 0)
				this.timer = window.setTimeout("elysianToggleButtons['" + this.name + "'].fadeOut()", 50);
		}
	}

	this.click = function() {
	}

	this.showHelpBubble = function() {
		var left;
		var top;
		var anchorSpot;

		if (this.helpDiv != null) {
			anchorSpot = elysianElementSpot(this.buttonImage),
			this.helpDiv.style.display = 'block';
			left = anchorSpot.left;
			top = anchorSpot.bottom + 2;
			this.helpDiv.style.left = left.toString() + 'px';
			this.helpDiv.style.top = top.toString() + 'px';
		}
	}

	this.hideHelp = function() {
		if (this.helpDiv != null) {
			this.helpDiv.style.display = 'none';
		}
	}

	this.enter = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (s)
			this.fadeIn();
		this.showHelpBubble();
	}

	this.leave = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (s)
			this.fadeOut();
		this.hideHelp();
	}

	this.clickHandler = function() {
		this.value = this.value ? 0 : 1;
		if (this.value)
			this.setState(this.onstyle.length - 1);
		else
			this.setState(this.offstyle.length - 1);

		if (this.click)
			this.click();
	}

	this.setState(0);

	eval('this.buttonImage.onmouseover = function () {elysianToggleButtons["' + this.name + '"].enter();}');
	eval('this.buttonImage.onmouseout = function () {elysianToggleButtons["' + this.name + '"].leave();}');
	eval('this.buttonImage.onclick = function () {elysianToggleButtons["' + this.name + '"].clickHandler();}');
	if (this.labelDiv) {
		eval('this.labelDiv.onmouseover = function () {elysianToggleButtons["' + this.name + '"].enter();}');
		eval('this.labelDiv.onmouseout = function () {elysianToggleButtons["' + this.name + '"].leave();}');
		eval('this.labelDiv.onclick = function () {elysianToggleButtons["' + this.name + '"].clickHandler();}');
	}
}


/*
 * ElysianRadioButton
 *
 * An animated button which is normally used to submit forms
 *
 */

var elysianRadioButtons = new Array();

function ElysianRadioButton(_name, _style, _onbutton, _offbutton, _initial) {

	elysianRadioButtons[_name] = this;
	this.name = _name;

	this.buttonImage = elysianElementGet(_name + '_img');
	this.labelDiv = elysianElementGet(_name + '_label');
	this.helpDiv = elysianElementGet(_name + '_help');

	tmpstyle = elysianStyles[_style];
	if (tmpstyle) {
		this.onstyle = tmpstyle.toggleButtons[_onbutton];
		this.offstyle = tmpstyle.toggleButtons[_offbutton];
	} else {
		this.onstyle = null;
		this.offstyle = null;
	}

	this.state = 0;
	this.value = _initial;

	this.timer = null;

	this.setState = function(_state) {
		this.state = _state;
		if (this.value)
			this.buttonImage.src = this.onstyle[_state].backgroundImage.src;
		else
			this.buttonImage.src = this.offstyle[_state].backgroundImage.src;
	}

	this.fadeIn = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state < s.length - 1) {
			this.setState(this.state + 1);
			if (this.state < s.length - 1)
				this.timer = window.setTimeout("elysianRadioButtons['" + this.name + "'].fadeIn()", 70);
		}
	}

	this.fadeOut = function() {
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		if (this.state > 0) {
			this.setState(this.state - 1);
			if (this.state > 0)
				this.timer = window.setTimeout("elysianRadioButtons['" + this.name + "'].fadeOut()", 50);
		}
	}

	this.click = function() {
	}

	this.showHelpBubble = function() {
		var left;
		var top;
		var anchorSpot;

		if (this.helpDiv != null) {
			anchorSpot = elysianElementSpot(this.buttonDiv),
			this.helpDiv.style.display = 'block';
			left = anchorSpot.left;
			top = anchorSpot.bottom + 2;
			this.helpDiv.style.left = left.toString() + 'px';
			this.helpDiv.style.top = top.toString() + 'px';
		}
	}

	this.hideHelp = function() {
		if (this.helpDiv != null) {
			this.helpDiv.style.display = 'none';
		}
	}

	this.enter = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (s)
			this.fadeIn();
		this.showHelpBubble();
	}

	this.leave = function() {
		var s = (this.value ? this.onstyle : this.offstyle);
		if (s)
			this.fadeOut();
		this.hideHelp();
	}

	this.clickHandler = function() {
		if (!this.value) {
			this.value = 1;
			this.setState(this.onstyle.length - 1);
			this.group.setValue(this.groupValue);
		}

		if (this.click)
			this.click();
	}

	this.setState(0);

	eval('this.buttonImage.onmouseover = function () {elysianRadioButtons["' + this.name + '"].enter();}');
	eval('this.buttonImage.onmouseout = function () {elysianRadioButtons["' + this.name + '"].leave();}');
	eval('this.buttonImage.onclick = function () {elysianRadioButtons["' + this.name + '"].clickHandler();}');
	
	if (this.labelDiv) {
		eval('this.labelDiv.onmouseover = function () {elysianRadioButtons["' + this.name + '"].enter();}');
		eval('this.labelDiv.onmouseout = function () {elysianRadioButtons["' + this.name + '"].leave();}');
		eval('this.labelDiv.onclick = function () {elysianRadioButtons["' + this.name + '"].clickHandler();}');
	}
}


function ElysianRadioGroup(_initial) {

	this.buttons = new Array();
	this.value = _initial;
	this.active = null;

	this.addButton = function(_button, _value) {
		this.buttons[_value] = _button;
		_button.group = this;
		_button.groupValue = _value;
		if (_button.value == 1)
		this.active = _button;
	}

	this.setValue = function(_newValue) {
		this.active.value = 0;
		this.active.setState(0);
		this.active = this.buttons[_newValue];
		this.value = _newValue;
		if (this.onChange)
			this.onChange();
	}
}


/*
 * ElysianCheckbox
 *
 * A checkbox with an associated hidden input
 *
 */

var elysianCheckboxes = new Array();

function ElysianCheckbox(_name, _style, _checkbox, _initial) {

	elysianCheckboxes[_name] = this;
	this.name = _name;

	this.checkboxImage = elysianElementGet(_name + '_img');
	this.checkboxInput = elysianElementGet(_name + '_input');
	this.checkboxInput.value = (_initial ? '1' : '0');
	this.state = _initial;

	tmpstyle = elysianStyles[_style];
	if (tmpstyle)
		this.images = tmpstyle.checkboxes[_checkbox];
	else
		this.images = null;

	this.toggle = function() {
		if (this.state) {
			this.state = false;
			this.checkboxInput.value = '0';
			if (this.images) {
				this.checkboxImage.src = this.images.offImage.src;
			}
		} else {
			this.state = true;
			this.checkboxInput.value = '1';
			if (this.images) {
				this.checkboxImage.src = this.images.onImage.src;
			}
		}
	}


	eval('this.checkboxImage.onclick = function () {elysianCheckboxes["' + this.name + '"].toggle();}');
}


/*
 * ElysianMenu
 *
 * A popup menu which can be used in the main menu bar or elsewhere on the page.
 *
 */

var elysianMenus = new Array(),
    elysianOpenMenu = null,
    elysianMenuTimeout = null;


/* Menu positioning constants */

var ELYSIAN_MENU_LEFT = 1,
      ELYSIAN_MENU_RIGHT = 2,
      ELYSIAN_MENU_TOP = 4,
      ELYSIAN_MENU_BOTTOM = 8;

function ElysianMenu(_anchor, _position, _hspace, _vspace) {

	elysianMenus[_anchor] = this;
	this.name = _anchor;

	this.anchorDiv = elysianElementGet(_anchor);
	this.bodyDiv = elysianElementGet(_anchor + '_body');
	this.position = _position;
	this.hspace = _hspace;
	this.vspace = _vspace;

	this.timer = null;

	this.open = function() {
		var anchorSpot = elysianElementSpot(this.anchorDiv),
		    left, top, right, bottom;
		left = anchorSpot.left + this.hspace;
		top = anchorSpot.top + this.vspace;
		right = anchorSpot.right + this.hspace - this.bodyDiv.offsetWidth;
		bottom = anchorSpot.bottom + this.vspace;
		if ((this.position & ELYSIAN_MENU_RIGHT) != 0)
			this.bodyDiv.style.left = right.toString() + 'px';
		else
			this.bodyDiv.style.left = left.toString() + 'px';
		if ((this.position & ELYSIAN_MENU_TOP) != 0)
			this.bodyDiv.style.bottom = '-' + top.toString() + 'px';
		else
			this.bodyDiv.style.top = bottom.toString() + 'px';
		elysianOpenMenu = this;
		this.bodyDiv.style.position = 'absolute';
		this.bodyDiv.style.display = 'block';
	}

	this.close = function() {
		this.bodyDiv.style.display = 'none';
		elysianOpenMenu = null;
	}

	this.enter = function() {
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
		if (elysianOpenMenu) {
			elysianOpenMenu.close();
		}
		this.open();
	}

	this.leave = function() {
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
		elysianMenuTimeout = window.setTimeout("elysianOpenMenu.close()", 500);
	}

	this.reenter = function() {
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
	}

	this.clickHandler = function() {
		if (this.click)
			this.click();
	}

	this.addItem = function(_item) {
		var item = elysianElementGet(this.name + '_' + _item);
		/* item.onmouseover = function() {
			elysianOpenMenu.reenter();
		}
		item.onmouseout = function() {
			elysianOpenMenu.leave();
		} */
	}

	this.bodyDiv.onmouseover = function() {
		if (elysianOpenMenu)
			elysianOpenMenu.reenter();
	}
	this.bodyDiv.onmouseout = function() {
		if (elysianOpenMenu)
			elysianOpenMenu.leave();
	}

	eval('this.anchorDiv.onmouseover = function () {elysianMenus["' + this.name + '"].enter();}');
	eval('this.anchorDiv.onmouseout = function () {elysianMenus["' + this.name + '"].leave();}');
	eval('this.anchorDiv.onclick = function () {elysianMenus["' + this.name + '"].clickHandler();}');
}


function ElysianIconbarMenu(_anchor, _position) {

	elysianMenus[_anchor] = this;
	this.name = _anchor;

	this.anchorDiv = elysianElementGet(_anchor);
	this.anchorDivIcon = elysianElementGet(_anchor + '_icon');
	this.anchorDivParent = elysianElementGet(_anchor + '_cell');
	this.bodyDiv = elysianElementGet(_anchor + '_body');
	this.position = _position;

	this.timer = null;

	this.open = function() {
		var anchorSpot = elysianElementSpot(this.anchorDivParent),
		    left, top, right, bottom;
		left = anchorSpot.left - 18;
		bottom = anchorSpot.top + 17;
		this.bodyDiv.style.left = left.toString() + 'px';
		this.bodyDiv.style.top = bottom.toString() + 'px';
		elysianOpenMenu = this;
		this.bodyDiv.style.position = 'absolute';
		this.bodyDiv.style.display = 'block';
	}

	this.close = function() {
		this.bodyDiv.style.display = 'none';
		elysianOpenMenu = null;
	}

	this.enter = function() {
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
		if (elysianOpenMenu) {
			elysianOpenMenu.close();
		}
		this.open();
	}

	this.leave = function() {
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
		elysianMenuTimeout = window.setTimeout("elysianOpenMenu.close()", 500);
	}

	this.reenter = function() {
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
	}

	this.clickHandler = function() {
		if (this.click)
			this.click();
	}

	this.addItem = function(_item) {
		var item = elysianElementGet(this.name + '_' + _item);
		/* item.onmouseover = function() {
			elysianOpenMenu.reenter();
		}
		item.onmouseout = function() {
			elysianOpenMenu.leave();
		} */
	}

	this.bodyDiv.onmouseover = function() {
		if (elysianOpenMenu)
			elysianOpenMenu.reenter();
	}
	this.bodyDiv.onmouseout = function() {
		if (elysianOpenMenu)
			elysianOpenMenu.leave();
	}

	eval('this.anchorDiv.onmouseover = function () {elysianMenus["' + this.name + '"].enter();}');
	eval('this.anchorDiv.onmouseout = function () {elysianMenus["' + this.name + '"].leave();}');
	eval('this.anchorDiv.onclick = function () {elysianMenus["' + this.name + '"].clickHandler();}');

	eval('this.anchorDivIcon.onmouseover = function () {elysianMenus["' + this.name + '"].enter();}');
	eval('this.anchorDivIcon.onmouseout = function () {elysianMenus["' + this.name + '"].leave();}');
	eval('this.anchorDivIcon.onclick = function () {elysianMenus["' + this.name + '"].clickHandler();}');
}


/*
 * ElysianCombo
 *
 * Combo box. Essentially a button with a dropdown menu
 *
 */


var elysianCombos = new Array();

function ElysianCombo(_name, _style, _button, _position, _hspace, _vspace, _ehspace) {

	elysianCombos[_name] = this;
	this.name = _name;

	this.buttonDivLeft = elysianElementGet(_name + '_left');
	this.buttonImgLeft = elysianElementGet(_name + '_left_img');
	this.buttonDivCenter = elysianElementGet(_name + '_center');
	this.buttonDivRight = elysianElementGet(_name + '_right');
	this.buttonImgRight = elysianElementGet(_name + '_right_img');

	this.bodyDiv = elysianElementGet(_name + '_body');
	this.position = _position;
	this.hspace = _hspace;
	this.ehspace = _ehspace ? _ehspace : false;
	this.vspace = _vspace;

	this.scrollingParent = null;

	tmpstyle = elysianStyles[_style];
	if (tmpstyle)
		this.style = tmpstyle.buttons[_button];
	else
		this.style = null;

	this.state = 0;

	this.animTimer = null;
	this.menuTimer = null;

	this.open = function() {
		var anchorSpot,
		    left, top, right, bottom;
		if ((this.position & ELYSIAN_MENU_RIGHT) != 0)
			anchorSpot = elysianElementSpot(this.buttonDivRight);
		else
			anchorSpot = elysianElementSpot(this.buttonDivLeft);
		left = anchorSpot.left + this.hspace;
		top = anchorSpot.top + this.hspace;
		right = anchorSpot.right + this.vspace - this.bodyDiv.offsetWidth;
		bottom = anchorSpot.bottom + this.vspace;
		if (this.scrollingParent != null) {
			top = top - this.scrollingParent.scrollTop;
			bottom = bottom - this.scrollingParent.scrollTop;
		}
		if ((this.position & ELYSIAN_MENU_RIGHT) != 0) {
			this.bodyDiv.style.left = right.toString() + 'px';
		} else
			this.bodyDiv.style.left = left.toString() + 'px';
		if ((this.position & ELYSIAN_MENU_TOP) != 0)
			this.bodyDiv.style.bottom = '-' + top.toString() + 'px';
		else
			this.bodyDiv.style.top = bottom.toString() + 'px';
		elysianOpenMenu = this;
		this.bodyDiv.style.position = 'absolute';
		this.bodyDiv.style.display = 'block';
		if ((this.position & ELYSIAN_MENU_RIGHT) != 0) {
			if (this.ehspace) {
				right = anchorSpot.right + this.ehspace;
				this.bodyDiv.style.left = right.toString() + 'px';
			} else {
				right = anchorSpot.right + this.vspace - this.bodyDiv.offsetWidth;
				this.bodyDiv.style.left = right.toString() + 'px';
			}
		}
	}

	this.close = function() {
		this.bodyDiv.style.display = 'none';
		elysianOpenMenu = null;
	}

	this.setState = function(_state) {
		this.state = _state;
		this.buttonImgLeft.src = this.style[_state].leftImage.src;
		this.buttonDivCenter.style.backgroundImage = this.style[_state].center;
		this.buttonImgRight.src = this.style[_state].rightImage.src;
	}

	this.fadeIn = function() {
		if (this.animTimer) {
			window.clearTimeout(this.animTimer);
			this.animTimer = null;
		}
		if (this.state < this.style.length - 1) {
			this.setState(this.state + 1);
			if (this.state < this.style.length - 1)
				this.animTimer = window.setTimeout("elysianCombos['" + this.name + "'].fadeIn()", 70);
		}
	}

	this.fadeOut = function() {
		if (this.animTimer) {
			window.clearTimeout(this.animTimer);
			this.animTimer = null;
		}
		if (this.state > 0) {
			this.setState(this.state - 1);
			if (this.state > 0)
				this.animTimer = window.setTimeout("elysianCombos['" + this.name + "'].fadeOut()", 50);
		}
	}

	this.clicked = function() {
		if (this.style)
			this.fadeOut();
		this.close();
	}

	this.enter = function() {
		if (this.style)
			this.fadeIn();

		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
		if (elysianOpenMenu != this) {
			if (elysianOpenMenu) {
				elysianOpenMenu.close();
			}
			this.open();
		}
	}

	this.leave = function() {
		if (this.style)
			this.fadeOut();
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
		elysianMenuTimeout = window.setTimeout("elysianOpenMenu.close()", 500);
	}

	this.reenter = function() {
		if (this.style)
			this.fadeIn();
		if (elysianMenuTimeout) {
			window.clearTimeout(elysianMenuTimeout);
			elysianMenuTimeout = null;
		}
	}

	this.clickHandler = function() {
		if (this.click)
			this.click();
	}

	this.addItem = function(_item) {
		var item = elysianElementGet(this.name + '_' + _item);
		/* item.onmouseover = function() {
			elysianOpenMenu.reenter();
		}
		item.onmouseout = function() {
			elysianOpenMenu.leave();
		} */
	}

	this.bodyDiv.onmouseover = function() {
		if (elysianOpenMenu)
			elysianOpenMenu.reenter();
	}

	this.bodyDiv.onmouseout = function() {
		if (elysianOpenMenu)
			elysianOpenMenu.leave();
	}

	eval('this.buttonDivLeft.onmouseover = function () {elysianCombos["' + this.name + '"].enter();}');
	eval('this.buttonDivCenter.onmouseover = function () {elysianCombos["' + this.name + '"].enter();}');
	eval('this.buttonDivRight.onmouseover = function () {elysianCombos["' + this.name + '"].enter();}');

	eval('this.buttonDivLeft.onmouseout = function () {elysianCombos["' + this.name + '"].leave();}');
	eval('this.buttonDivCenter.onmouseout = function () {elysianCombos["' + this.name + '"].leave();}');
	eval('this.buttonDivRight.onmouseout = function () {elysianCombos["' + this.name + '"].leave();}');
}



/*
 * ElysianDialog
 *
 * Popup dialog window shown inside a page
 *
 */

var elysianDialogs = new Array();


function ElysianDialog(_name) {

	this.name = _name;
	elysianDialogs[_name] = this;

	this.dialogDiv = elysianElementGet(_name);
	this.buttons = new Array();

	this.open = function() {
		var x, y;
		var b;

		this.dialogDiv.style.display = 'block';

		if (elysianBrowser == BROWSER_IE) {
			x = (document.body.offsetWidth - this.dialogDiv.offsetWidth) / 2;
			y = ((document.body.offsetHeight - this.dialogDiv.offsetHeight) / 2);
		} else {
			x = (window.innerWidth - this.dialogDiv.offsetWidth) / 2;
			y = ((window.innerHeight - this.dialogDiv.offsetHeight) / 2) + window.pageYOffset;
		}

		this.dialogDiv.style.left = x.toString() + 'px';
		this.dialogDiv.style.top = y.toString() + 'px';


		for (b = 0; b < this.buttons.length; b++) {
			this.buttons[b].setState(0);
		}

		this.onOpen();
	}

	this.close = function() {
		this.dialogDiv.style.display = 'none';
	}

	this.addButton = function(_button) {
		this.buttons[this.buttons.length] = _button;
	}

	this.onOpen = function() {
	}
}


