///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//        ProtoClasses   v1.0      (c) 2008 Daniel Robinson
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
var ProtoClassLibrary = 1.0;
protoClasses = new Array();
bodyElement = null;

var browserName=navigator.appName;
var browserVersion=parseFloat(navigator.appVersion);
var isIE = browserName == "Microsoft Internet Explorer";

function getObject(object) {
	if (!object) {return null;}
	return (typeof(object) == "object") ? object : document.getElementById(object);
}

function registerClass(className, classFunction) {
	if (typeof(classFunction) != "function") {return;}
	protoClasses[className] = classFunction;
}
function createObjects(parent) {
	if (typeof(parent) == "object") {
		var body = parent;
	} else {
		var body = document.getElementsByTagName('body')[0];
	}
	var divs = body.getElementsByTagName('div');
	var createdObjects = new Array();
	for (var c = 0; c < divs.length; c++) {
		var protoClass = divs[c].getAttribute('protoclass');
		if (protoClass != null && protoClass != "") {
			var fn = protoClasses[protoClass];
			if (typeof(fn) == "function") {
				
				fn(divs[c]);
				createdObjects.push(divs[c]);
			}
		}
	}

	for (var c = 0; c < createdObjects.length; c++) {
		if (typeof(createdObjects[c].afterCreation) == "function") {
			createdObjects[c].afterCreation();
		}
	}
}

function pointerCoords(event) {
	var ev = event || window.event;
	var x = ev.pageX || (ev.clientX +
		(document.documentElement.scrollLeft || document.body.scrollLeft));
	var y = ev.pageY || (ev.clientY +
		(document.documentElement.scrollTop || document.body.scrollTop));
	return {left: x, top: y};
 }


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        Prototype extensions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Date.prototype.add = function(milliseconds) {
	this.setTime(this.getTime() + milliseconds);
}
Date.prototype.second = 1000;
Date.prototype.minute = Date.prototype.second * 60;
Date.prototype.hour = Date.prototype.minute * 60;
Date.prototype.day = Date.prototype.hour * 24;
Date.prototype.year = Date.prototype.day * 365;

Array.prototype.indexOf = function(item) {
	for (var c = 0; c < this.length; c++) {
		if (this[c] == item) { return c; }
	}
	return -1;
}

String.prototype.trim = function() {
    a = this.replace(/^\s+/, '');
    return a.replace(/\s+$/, '');
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 	Cookies
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var protoCookies = new Object();

protoCookies.initialized = false;

protoCookies.initCookies = function() {
	var tokens = document.cookie.split(';');
	for (var c = 0; c < tokens.length; c++) {
		var subToken = tokens[c];
		if (subToken.indexOf('=') > -1) {
			var subTokens = subToken.split('=',2);
			protoCookies[subTokens[0].trim()] = subTokens[1];
		} else {
			if (protoCookies[subToken] == null || protoCookies[subToken] == undefined) {
				protoCookies[subToken] = '';
			}
		}
	}
	protoCookies.initialized = true;
}

protoCookies.getCookie = function(cookieName, defaultValue) {
	if (!protoCookies.initialized) {
		protoCookies.initCookies();
	}

	return (protoCookies[cookieName] == null) ? defaultValue : protoCookies[cookieName];
}

protoCookies.setCookie = function(cookieName, value, overwrite, days) {
	if (typeof(overwrite) == "undefined") {
		overwrite = true;
	}
	if (!overwrite) {
		if (protoCookies.getCookie(cookieName, null) != null) { return; }
	}
	days = (!days) ? 36500 : days;
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = cookieName+"="+value+expires+"; path=/";
	protoCookies[cookieName] = value;		
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        Timer Class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function Timer(interval, maxTick) {
	this.tickcount = 0;
	this.interval = interval;
	this.enabled = false;
	this.ontimertick = null;
	this.timer = null;
	
	this.enable = function () {
		if (this.enabled == true) {return;}
		this.enabled = true;
		this.timer = setInterval(this.timertickfunc(), this.interval);
	}
	
	this.disable = function (clear) {
		if (this.enabled == false) {return;}
		this.enabled = false;
		clearInterval(this.timer);
		if (clear) {
			this.tickcount = 0;
		}
	}
		
	this.timertickfunc = function () {
		var o = this;
		return function() {
			o.doTimerTick();
		}
	}
	
	this.doTimerTick = function () {
		this.tickcount++;
		if (this.maxTick > 0 && this.tickcount > this.maxTick) {
			this.disable(true);
			this.doTimerFinished();
			return;
		}
		if (typeof(this.ontimertick) == "function") {
			this.ontimertick(this, this.tickcount == 1);
		}
	}
	this.doTimerFinished = function () {
		if (typeof(this.ontimerfinished) == "function") {
			this.ontimerfinished(this);
		}
	}
	this.maxTick = (typeof(maxTick) == "number") ? maxTick : 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//			PROTO				
//			Provides a base for all protoclasses
//			html attributes:
//				protoclass		name of the protoclass to construct
//			
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function proto(element) {
	var e = getObject(element);
	
	if (e == null) {
		e = document.createElement('div');
	}
	e.protoClass = e.getAttribute('protoclass');
	

	e.fireEvent = function(eventName) {
		var ev = this[eventName];
		if (typeof(ev) == "function") {
			return ev.call(this);
		}
	}
	
	e.registerEvent = function(eventName) {
		this[eventName] = Function(this.getAttr(eventName, null));
	}
	
	e.getAttr = function(attrib, defaultVal) {
		var res = this.getAttribute(attrib);
		if (res == null || res == undefined || res=="") {
			res = (defaultVal != null && defaultVal != undefined) ? defaultVal : "";
		}
		return res;
	}
	
	e.registerEvent('onshow');
	e.registerEvent('onhide');
//	e.onshow = Function(e.getAttr('onshow', null));
//	e.onhide = Function(e.getAttr('onhide', null));
	e.border = e.getAttr('border', 1);
	
	e.setProtoClass = function(protoclass) {
		if (!this.protoClass) {
			this.protoClass = protoclass;
			this.setAttribute('protoclass', protoclass);
		}
	}
	e.setVisibility = function(visible, display) {
		if (typeof(display) == 'undefined') {
			display = true;
		}
		if (display) {
			this.style.display = (visible) ? 'block' : 'none';
		}
		this.style.visibility = (visible) ? 'visible' : 'hidden';
	}
	e.showMe = function(x, y, display) {
		if (x != null && y != null) {
			this.setLeft(x);
			this.setTop(y);
		}
		this.setVisibility(true, display);

		if (typeof(this.onshow) == "function") {
			this.onshow();
		}
	}
	e.hideMe = function(display) {
		this.setVisibility(false, display);
		if (typeof(this.onhide) == "function") {
			this.onhide();
		}
	}
		e.ptInRect = function(x, y) {
		var coords = this.getAbsPos();
		return ((x >= coords.x) && (x <= coords.x + this.offsetWidth) && (y >= coords.y) && (y <= coords.y + this.offsetHeight));
	}
	e.getAbsPos = function(element) {
		var ele = element || this;
		var left = 0;
		var top = 0;
		while (ele.offsetParent) {
			left += ele.offsetLeft;
			top += ele.offsetTop;
			ele = ele.offsetParent;
		}
		return {x: left, y: top}
	}
	e.isVisible = function() {
		return (this.style.visibility == "visible") && (this.style.display != "none");
	}
	e.isProto = function(element) {
		if (!element) {return false;}
		var e = getObject(element);
		
		if (e.nodeType != 1) {return false;}
		var pClass = e.getAttribute('protoclass');
		
		return (pClass != null) && (pClass != "");
	}
	
	e.isParentProto = function() {
		return this.isProto(this.parentNode);
	}
	
	e.getBody = function() {
		if (bodyElement == null || bodyElement == undefined) {
			bodyElement = document.getElementsByTagName('body')[0];
		}
		return bodyElement;
	}
	
	e.getPageWidth = function() {
		if (typeof(window.innerWidth) == "number") {
			return window.innerWidth;
		}
		if (document.documentElement && (document.documentElement.clientWidth)) {
			return document.documentElement.clientWidth;
		}
		if (document.body && document.body.clientWidth) {
			return document.body.clientWidth;
		}
		return 800;
	}
	
	e.getPageHeight = function() {
		if (typeof(window.innerHeight) == "number") {
			return window.innerHeight;
		}
		if (document.documentElement && (document.documentElement.clientHeight)) {
			return document.documentElement.clientHeight;
		}
		if (document.body && document.body.clientHeight) {
			return document.body.clientHeight;
		}
		return 800;
	}
		
	e.getWidth = function() {
		return this.offsetWidth;
	}
	e.getHeight = function() {
		return this.offsetHeight;
	}
	e.getBorder = function() {
		var b = this.style.borderWidth;
		var widths = b.split(" ");
		return {
			top: widths[0],
			right: widths[1],
			bottom: widths[2],
			left: widths[3]
		}
	}
	e.getInnerWidth = function() {
		var border = this.getBorder();
		return this.getWidth() - (border * 2);
	}
	e.getInnerHeight = function() {
		var border = this.getBorder();
		return this.getHeight() - (border * 2);
	}
	e.setInnerWidth = function(width) {
		var border = this.getBorder();
		this.setWidth(width - (border * 2));
	}
	e.setInnerHeight = function(height) {
		var border = this.getBorder();
		this.setHeight(height - (border * 2));
	}
	e.setWidth = function(width) {
		this.style.width = width + 'px';
		this.resizeContent();
	}
	e.setHeight = function(height) {
		this.style.height = height + 'px';
		this.resizeContent();
	}
	e.getLeft = function() {
		return parseInt(this.style.left);
	}
	e.getTop = function() {
		return parseInt(this.style.top);
	}
	e.setLeft = function(left) {
		this.style.left = left + 'px';
	}
	e.setTop = function(top) {
		this.style.top = top + 'px';
	}
	e.resizeContent = function() {
	}
	e.afterCreation = function() {
	}
	e.attachObjects = function() {
		var attach = this.getAttr('attach', '');
		if (!attach) {return;}
		var tokens = attach.match(/[a-zA-Z0-9]*/g);
		state = 0;
		var varname = "";
		for (var c = 0; c < tokens.length; c++) {
			var token = tokens[c];
			if (token != "") {
				switch(state) {
					case 0:
						varname = token;
						state = 1;
					break;
					case 1:
						this[varname] = getObject(token);
						state = 0;
					break;
				}
			}
		}
	}
	
	e.attachObjects();
	
	var extendedConstructor = e.getAttribute('constructor');
	if (typeof(extendedConstructor) != "undefined" && extendedConstructor != "" && extendedConstructor != null) {
		e.extendedConstructor = Function(extendedConstructor);
		e.extendedConstructor(e);
	}
	return e;
}

var defaultConstructor = proto;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//			BASIC				
//			Provides a base for all protoclasses
//			html attributes:
//				protoclass		name of the protoclass to construct
//			
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function Basic(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('basic');
	return e;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//				LISTBOX
//				
//				html attributes:
//					normalclass		css class for a normal item
//					highlightclass	css class for a highlighted item
//					selectedclass	css class for selected item
//					autoadd		automatically adds any child elements as items for the list box
//					
//				events	
//					onchange		selection changed event
//				
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ListBox(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('listbox');
	e.value = '';
	e.items = new Array();
	e.values = new Array();
	e.normalClass = e.getAttr('normalclass', "");
	e.highlightClass = e.getAttr('highlightclass', "");
	e.selectedClass = e.getAttr('selectedclass', "");
	e.selected = null;
	e.selectedId = -1;
	e.updateCount = 0;
	e.length = 0;
	e.registerEvent('onchange');
	//e.onchange = new Function(e.getAttr('onchange', ""));
	
	e.doChange = function(item, oldId, newId) {
		if (typeof(this.onchange) == "function") {
			this.onchange(item, oldId, newId);
		}
	}
	
	e.beginUpdate = function() {
		this.updateCount++;
	}
	
	e.endUpdate = function() {
		this.updateCount--;
		if (this.updateCount < 0) {this.updateCount = 0;}
		if (this.updateCount == 0) {
			this.doChange(this.selected, -1, this.selectedId);
		}
	}
	
	e.setSelected = function(item) {
		if (this.selected == item) {return;}
		var oldIndex = (this.selected) ? this.selected.itemIndex : -1;
		if (this.selected != null) {
			this.selected.className = this.selected.normalClass;
		}
		this.selected = item;
		if (this.selected != null) {
			this.selectedId = item.itemIndex;
			this.selected.className = this.selectedClass;
			this.value = item.getAttribute('value');
			if (!this.value) {
				this.value = this.values[item.itemIndex];
			}
		} else {
			this.selectedId = -1;
		}
		if (this.updateCount == 0) {
			this.doChange(this.selected, oldIndex, this.selectedId);
		}
	}
	
	e.setItemEvents = function(item) {
		item.onmousemoveold = item.onmousemove;
		item.onmousemove = function(e) {
			if (!this.listbox) {return}
			if (typeof(this.listbox.onmousemove) == "function") {
				this.listbox.onmousemove(e);
			}
			if (typeof(this.onmousemoveold) == "function") {
				this.onmousemoveold(e);
			}
		}
		item.onmouseoverold = item.onmouseover;
		item.onmouseover = function(e) {
			if (this.listbox.selected != this) {
				this.className = this.listbox.highlightClass;
			}
			if (typeof(this.onmouseoverold) == "function") {
				this.onmouseoverold(e);
			}
		}
		item.onmouseoutold = item.onmouseout;
		item.onmouseout = function(e) {
			this.className = (this.listbox.selected == this) ? this.listbox.selectedClass : this.normalClass;
			if (typeof(this.onmouseoutold) == "function") {
				this.onmouseoutold(e);
			}
		}
		item.onclickold = item.onclick;
		item.onclick = function(e) {
			this.listbox.setSelected(this);
			if (typeof(this.onclickold) == "function") {
				this.onclickold(e);
			}
			if (typeof(this.listbox.onclick) == "function") {
				this.listbox.onclick(this);
			}
		}
	}
	
	e.setItemStyle = function(item) {
		if (item.className == "") {
			item.normalClass = this.normalClass;
		} else {
			if (item.className != this.normalClass) {
				item.normalClass = item.className;
			} else {
				item.normalClass = this.normalClass;
			}
		}
		item.className = (this.selected == item) ? this.selectedClass : item.normalClass;
		item.style.cursor = 'pointer';
	}	
	
	e.setAllItemsStyle = function() {
		for (var c = 0; c < this.items.length; c++) {
			this.setItemStyle(this.items[c]);
		}
	}
	e.setClasses = function(normal, highlight, selected) {
		this.normalClass = (normal) ? normal : this.normalClass;
		this.highlightClass = (highlight) ? highlight : this.highlightClass;
		this.selectedClass = (selected) ? selected : this.selectedClass;
		this.setAllItemsStyle();
	}
	e.addItem = function(item, value, append) {
		var itemobj = null;
		var itemvalue = value;
		if (typeof(item) == "string") {
			itemobj = document.createElement('div');
			itemobj.innerHTML = item;
			this.appendChild(itemobj);
		}
		if (typeof(item) == "object") {
			itemobj = item;
			itemvalue = item.getAttribute('value');
		}
		itemobj.listbox = this;
		itemobj.itemIndex = this.items.push(itemobj) - 1;
		this.values.push(itemvalue);
		if (append == true) {
			this.appendChild(itemobj);
		}
		itemobj.itemValue = itemvalue;
		this.length = this.items.length;
		this.setItemEvents(itemobj);
		this.setItemStyle(itemobj);
		if (this.items.length == 1) {
			this.setSelected(itemobj);
		}
		return itemobj;
	}	
	
	e.autoAdd = function () {
		for (var c = 0; c < this.childNodes.length; c++) {
			var node = this.childNodes[c];
			if (node.nodeName != "#text") {
				this.addItem(node);
			}
		}
	}
	
	e.clear = function () {
		this.innerHTML = '';
		this.values.length = 0;
		this.items.length = 0;
		this.value = 0;
		this.length = 0;
		this.selected = null;
		this.selectedId = -1;
	}
	
	if (e.getAttr('autoadd') == "true") {
		e.autoAdd();
	}
	e.afterCreation = function() {
	}
	return e;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//				TABSET, TABBUTTON, TABPAGE, TABPAGES
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TabSet(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('tabset');
	e.normalClass = e.getAttr('normalclass', '');
	e.highlightClass = e.getAttr('highlightclass', '');
	e.selectedClass = e.getAttr('selectedclass', '');
	e.cookie = e.getAttr('cookie', '');
	e.selectedIndex = -1;
	e.selectedButton = null;
	e.selectedPage = null;
	e.pages = getObject(e.getAttr('pages'));
	e.buttons = new Array();
	e.length = 0;
	e.registerEvent('ontabchanging');
	e.registerEvent('ontabchanged');

	e.reset = function() {
		e.buttons = new Array();
	}
	e.addButton = function(button) {
		if (!button) {return;}
		if (this.isProto(button)) {

			this.buttons.push(button);
			button.tabSet = this;
			button.className = (this.normalClass != "") ? this.normalClass : button.className;
			button.index = this.buttons.length - 1;
			if (button.createHidden) {
				button.hideMe();
			}
		}
		this.length = this.buttons.length;
		return button;
	}
	e.setupButtons = function() {
		var buttoneles = this.childNodes;
		for (c = 0; c < buttoneles.length; c++) {
			var b = buttoneles[c];
			this.addButton(b);
		}
	}
	
	e.setSelected = function(button, suppressEvent) {
		var buttonObj = getObject(button);
		if (!buttonObj) {
			buttonObj = this.buttons[button];
		}
		if (buttonObj == this.selectedButton) {return;}
		this.fireEvent('ontabchanging');
		if (this.selectedButton != null) {
			this.selectedButton.className = this.normalClass;
			this.selectedButton.hidePage();
			this.selectedButton.selected = false;
		}
		buttonObj.className = this.selectedClass;
		buttonObj.showPage();
		buttonObj.selected = true;
		this.selectedButton = buttonObj;
		this.selectedPage = buttonObj.page;
		this.selectedIndex = buttonObj.index;
		if (this.cookie != "") {
			protoCookies.setCookie(this.cookie, this.selectedIndex);
		}
		if (!suppressEvent) {
			this.fireEvent('ontabchanged');
		}
	}
	e.afterCreation = function() {
		this.setupButtons();
		for (var c = 0; c < this.buttons.length; c++) {
			var b = this.buttons[c];
			if (b.page) {
				b.page.hideMe();
			}
		}
		if (this.cookie != "") {
			this.setSelected(protoCookies.getCookie(this.cookie, 0));
		} else {
			this.setSelected(this.buttons[0], true);
		}
	}
	e.addPage = function(content) {
		var page = null;
		if (!this.pages) {
			page = TabPage(null);
			page.innerHTML = content;
		} else {
			page = this.pages.addPage(null, content, true);
		}
		return page;
	}	
	e.newButton = function(content, pagecontent) {
		
		var b = TabButton(null);
		b.innerHTML = content;
		b.page = this.addPage(pagecontent);
		this.addButton(b);
		this.appendChild(b);
		return {button: b, page: b.page}
	}
		
	return e;
}
function TabButton(element) {
	var e = defaultConstructor(element);
	
	e.setProtoClass('tabbutton');
	
	e.onmouseoverold = Function(e.getAttr('onmouseover'));
	e.onmouseoutold = Function(e.getAttr('onmouseout'));
	e.onclickold = Function(e.getAttr('onclick'));
	e.selected = (e.getAttr('selected', 'false') == 'true') ? true : false;
	e.style.cursor = 'pointer';
	e.page = (getObject(e.getAttr('page')));
	if (isIE) {
		e.createHidden = e.hidden != null;
	} else {
		e.createHidden = e.hasAttribute('hidden');
	}
	if (e.page) {
		e.page.tabButton = e;
	}
	
	e.hidePage = function() {
		if (this.page) {
			this.page.hideMe();
		}
	}
	
	e.showPage = function() {
		if (this.page) {
			this.page.showMe();
		}
	}
	
	e.onmouseover = function(event) {
		if (this.selected) {return;}
		this.className = (this.selected) ? this.tabSet.selectedClass : this.tabSet.highlightClass;
		this.onmouseoverold(event);
	}
	
	e.onmouseout = function(event) {
		if (this.selecetd) {return;}
		this.className = (this.selected) ? this.tabSet.selectedClass : this.tabSet.normalClass;
		this.onmouseoutold(event);
	}
	
	e.onclick = function(event) {
		if (this.selected) {return;}
		this.tabSet.setSelected(this);
		this.onclickold(event);
	}
	
	e.afterCreation = function() {

	}
	return e;
}
function TabPage(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('tabpage');
	return e;
	
}
function TabPages(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('tabpages');
	e.pages = new Array();
	e.addPage = function(page, content, createHidden) {
		page = getObject(page);
		
		if (!page) {
			page = TabPage(null);
			page.innerHTML = content;
			if (createHidden) {
				page.hideMe();
			}
			this.appendChild(page);
			
		}

		if (this.isProto(page)) {
			page.className = this.getAttr('pageclass');
			this.pages.push(page);	
			
		} else {
			return null;
		}

		return page;
	}
	
	e.setupPages = function() {
		var childPages = this.childNodes;
		for (var c = 0; c < childPages.length; c++) {
			this.addPage(childPages[c]);

		}
	}
	
	e.afterCreation = function() {
		this.setupPages();
	}
	return e;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        AbsoluteCenter
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function AbsoluteCenter(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('absolutecenter');
	e.horz = (e.getAttr('centerhorz').toLowerCase() == 'true');
	e.vert = (e.getAttr('centervert').toLowerCase() == 'true');
	e.style.position = 'absolute';
	var b = window;
	if (!b.centeredItems) {
		b.centeredItems = new Array();
	}
	b.centeredItems.push(e);
	
	b.oldonresize = b.onresize;
	b.onresize = function() {
		if (!this.centeredItems) {return;}
		for (var c = 0; c < this.centeredItems.length; c++) {
			var item = this.centeredItems[c];
			if (item.center) {
				item.center();
			}
		}
	}
	
	e.center = function() {
		var w = this.offsetWidth;
		var h = this.offsetHeight;
		var sw = this.getPageWidth();
		var sh = this.getPageHeight();

		if (this.horz) {
			this.style.left = (sw / 2) - (w / 2) +'px';
		}
		if (this.vert) {
			this.style.top = (sh / 2) - (h / 2) + 'px';
		}
	}
	e.afterCreation = function() {
		this.center();
	}
	return e;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        Info Slider
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function InfoSlider(element) {
//	properties
	var e = defaultConstructor(element);
	e.setProtoClass('infoslider');	
	e.panels = new Array();
	e.repeatPanel = e.getAttr('repeatpanel', -1);
	e.repeatNext = (e.repeatPanel == 0) ? 1 : 0;
	e.interval = parseInt(e.getAttr('interval', 1000));
	e.steps = parseInt(e.getAttr('steps', 1));
	e.timer = new Timer(e.interval, 0);
	e.direction = parseInt(e.getAttr('direction', 1));
	e.autoAdd = e.getAttr('autoadd', 'true') == 'true';
	e.autoSlide = e.getAttr('autoslide', 'true') == 'true';
	e.slideTimer = new Timer(1, e.steps);
	e.currentPanel = null;
	e.currentIndex = 0;
	e.onslidefinish = Function(e.getAttr('onslidefinish', 'null;'));
//	functions
	e.indexOf = function (panel) {
		for (var c = 0; c < this.panels.length; c++) {
			if (panel == this.panels[c]) {return c;}
		}
		return -1;
	}
	
	e.doOnSlideFinish = function(oldpanel, newpanel) {
		if (typeof(this.onslidefinish) == "function") {
			this.onslidefinish(oldpanel, newpanel);
		}
	}
	
	e.getPadding = function() {
		var res = parseInt((this.style.padding) ? this.style.padding : "0");
		return (!res || res == NaN) ? 0 : res;
	}
	
	e.setPanelVisibility = function(panel, visible) {
		panel.style.visibility = (visible) ? "visible" : "hidden";
		panel.style.display = (visible) ? "block" : "none";
	}
		
	e.addChildrenAsPanels = function() {
		if (this.childNodes.length == 0) {return;}
		for (var c = 0; c < this.childNodes.length; c++) {
			var n = this.childNodes[c];
			if (n.nodeType == 1) {
				this.addPanel(n);
			}
		}
	}
			
	e.addPanel = function () {
		for (var c = 0; c < arguments.length; c++) {
			var panel = arguments[c];
			var p = (typeof(panel) != "object") ? document.getElementById(panel) : panel; 
			if (this.panels.length != 0) {
				p.style.visible = "hidden";
				p.style.display = "none";
			} else {
				this.currentPanel = p;
				p.style.top = "0px";
				p.style.visibility = "visible";
				p.style.display = "block";
			}
			var id = this.panels.push(p);
			p.style.position = "absolute";
			p.style.left = "0px";
			p.style.width = (this.width - (2 * this.getPadding())).toString() + "px";
			p.style.height = (this.height - (2 * this.getPadding())).toString() + "px";
		}
	}
	e.setEleStyle = function () {
		this.style.overflow = "hidden";
	}
	
	e.slide = function (panel, direction) {
		this.timer.disable();
		var pid1 = this.indexOf(this.currentPanel);
		var pid2 = panel;
		switch(typeof(panel)) {
			case "undefined":
			case "null":
				if (this.repeatPanel > -1) {
					pid2 = (this.repeatPanel == this.currentIndex) ? this.repeatNext : this.repeatPanel;
					if (this.repeatPanel == this.currentIndex) {
						this.repeatNext = (this.repeatNext + 1) % this.panels.length;
						this.repeatNext = (this.repeatNext == this.repeatPanel) ? 1 : this.repeatNext;
					}

				} else {
					pid2 = (pid1 + 1) % this.panels.length;
				}
				break;
			case "object":
				pid2 = this.indexOf(panel);
				pid2 = (pid2 < 0) ? (pid1 + 1) % this.panels.length : pid2;
				break;
			case "number":
				pid2 = panel;
				pid2 = (pid2 < 0 || pid2 >= this.panels.length) ? (pid1 + 1) % this.panels.length : pid2;
				break;
			case "string":
				pid2 = this.indexOf(document.getElementById(panel));
				pid2 = (pid2 < 0 || pid2 >= this.panels.length) ? (pid1 + 1) % this.panels.length : pid2;
				break;
		}
		
		var p1 = this.panels[pid1];
		var p2 = this.panels[pid2];
		
		if (p1 == p2) {
			if (this.autoSlide == true) {
				this.timer.enable();
			}
			return;
		}
		var dir = (typeof(direction) == "undefined") ? this.direction : direction;
		if (dir >= 0 && dir < 5) {
			this.slideTimer.direction = dir;
		} else {
			this.slideTimer.direction = Math.floor((Math.random() * 4) + 1);
		}
		if (dir < 0) {
			var oppdir = 0;
			switch(this.direction) {
				case 1:
					oppdir = 2;
					break;
				case 2:
					oppdir = 1;
					break;
				case 3:
					oppdir = 4;
					break;
				case 4:
					oppdir = 3;
					break;
			}
			this.slideTimer.direction = oppdir;
		}
			
		switch(this.slideTimer.direction) {
			case 1:
				p2.style.top = this.height;
				p2.style.left = 0;
				break;
			case 2:
				p2.style.top = 0-this.height;
				p2.style.left = 0;
				break;
			case 3:
				p2.style.top = 0;
				p2.style.left = 0-this.width;
				break;
			case 4:
				p2.style.top = 0;
				p2.style.left = 0-this.width;
				break;
		}
		this.setPanelVisibility(p2, true);
		this.slideTimer.p1 = p1;
		this.slideTimer.p2 = p2;
		this.slideTimer.ontimertick = function(timer, firsttick) {
			if (!this.p1 || !this.p2) {return;}
			if (firsttick) {
				this.moveBy = (this.direction < 3) ? (this.infoslider.height / this.maxTick) : (this.infoslider.width / this.maxTick);
			}
			var moveBy = this.moveBy;
			var delta = moveBy * (this.tickcount);
			switch (this.direction) {
				case 1:
					this.p1.style.top = Math.floor(-delta) + "px";
					this.p2.style.top = Math.floor(this.infoslider.height - delta) + "px";
					break;
				case 2:
					this.p1.style.top = Math.floor(delta) + "px";
					this.p2.style.top = Math.floor(delta - this.infoslider.height) + "px";
					break;
				case 3:
					this.p1.style.left = Math.floor(-delta) + "px";
					this.p2.style.left = Math.floor(this.infoslider.width - delta) + "px";
					break;
				case 4:
					this.p1.style.left = Math.floor(delta) + "px";
					this.p2.style.left = Math.floor(delta - this.infoslider.width) + "px";
					break;
			}
				
		}						
		this.slideTimer.ontimerfinished = function() {
			this.infoslider.setPanelVisibility(this.p1, false);
			this.infoslider.currentPanel  = p2;
			this.infoslider.currentIndex = this.infoslider.panels.indexOf(p2);
			this.infoslider.doOnSlideFinish(this.p1, p2);
			this.p1 = null;
			this.p2 = null;
			if (this.infoslider.autoSlide) {
				this.infoslider.timer.enable();
			}
		}
		
		this.slideTimer.enable();
	}	
	
//	initialization
	e.init = function() {
		this.setEleStyle();
		this.timer.infoslider = this;
		this.timer.ontimertick = function(timer, firsttick) {
			if (!this.infoslider) {return};
			this.infoslider.slide();
		}	
		this.slideTimer.infoslider = this;
		this.width = this.offsetWidth;
		this.height = this.offsetHeight;
		this.width = (this.width == NaN) ? 100 : this.width;
		this.height = (this.height == NaN) ? 100 : this.height;
		if (this.autoSlide) {
			this.timer.enable();
		}
		if (this.autoAdd) {
			
			this.addChildrenAsPanels();
		}
	}
	
	e.init();
	return e;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        ColorBox
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var DefaultColors = new Array(
		'', '#000000', '#1A1A1A', '#333333', '#4D4D4D', '#666666', '#808080', '#999999', '#B3B3B3', '#CCCCCC', '#E6E6E6', '#F2F2F2', '#FFFFFF',
		'#FF0000', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#FF00FF', '#800000', '#808000', '#008000', '#008080', '#000080', '#800080',
		'#2B0000', '#550000', '#800000', '#AA0000', '#D40000', '#FF0000', '#FF2A2A', '#FF5555', '#FF8080', '#FFAAAA', '#FFD4D4', '#FFEEEE',
		'#2B2B00', '#555500', '#808000', '#AAAA00', '#D4D400', '#FFFF00', '#FFFF2A', '#FFFF55', '#FFFF80', '#FFFFAA', '#FFFFD4', '#FFFFEE',
		'#002B00', '#005500', '#008000', '#00AA00', '#00D400', '#00FF00', '#2AFF2A', '#55FF55', '#80FF80', '#AAFFAA', '#D4FFD4', '#EEFFEE',
		'#002B2B', '#005555', '#008080', '#00AAAA', '#00D4D4', '#00FFFF', '#2AFFFF', '#55FFFF', '#80FFFF', '#AAFFFF', '#D4FFFF', '#EEFFFF',
		'#00002B', '#000055', '#000080', '#0000AA', '#0000D4', '#0000FF', '#2A2AFF', '#5555FF', '#8080FF', '#AAAAFF', '#D4D4FF', '#EEEEFF',
		'#2B002B', '#550055', '#800080', '#AA00AA', '#D400D4', '#FF00FF', '#FF2AFF', '#FF55FF', '#FF80FF', '#FFAAFF', '#FFD4FF', '#FFEEFF',
		'#002b00', '#005500', '#008000', '#00aa00', '#00d500', '#00ff00', '#24ff24', '#49ff49', '#6dff6d', '#92ff92', '#b6ffb6', '#dbffdb', 
		'#2b1500', '#552b00', '#804000', '#aa5500', '#d56b00', '#ff8000', '#ff9224', '#ffa449', '#ffb66d', '#ffc992', '#ffdbb6', '#ffeddb', 
		'#061114', '#0b2228', '#11343c', '#164550', '#1c5664', '#216778', '#417d8b', '#60929f', '#80a8b2', '#a0bec5', '#c0d4d8', '#dfe9ec', 
		'#2b2b23', '#555547', '#80806a', '#aaaa8d', '#d5d5b1', '#ffffd4', '#ffffda', '#ffffe0', '#ffffe6', '#ffffed', '#fffff3', '#fffff9', 
		'#000700', '#000e00', '#001600', '#001d00', '#002400', '#002b00', '#244924', '#496849', '#6d866d', '#92a492', '#b6c2b6', '#dbe1db', 
		'#021612', '#042d24', '#074337', '#095949', '#0b705b', '#0d866d', '#309782', '#52a997', '#75baac', '#97cbc0', '#badcd5', '#dceeea', 
		'#2b0e2b', '#551c55', '#802b80', '#aa39aa', '#d547d5', '#ff55ff', '#ff6dff', '#ff86ff', '#ff9eff', '#ffb6ff', '#ffceff', '#ffe7ff', 
		'#1c0000', '#390000', '#550000', '#710000', '#8e0000', '#aa0000', '#b62424', '#c24949', '#ce6d6d', '#db9292', '#e7b6b6', '#f3dbdb', 
		'#150015', '#2b002b', '#400040', '#550055', '#6b006b', '#800080', '#922492', '#a449a4', '#b66db6', '#c992c9', '#dbb6db', '#eddbed', 
		'#2b1800', '#553000', '#804800', '#aa6000', '#d57800', '#ff9000', '#ffa024', '#ffb049', '#ffc06d', '#ffcf92', '#ffdfb6', '#ffefdb', 
		'#061114', '#0b2228', '#11343c', '#164550', '#1c5664', '#216778', '#417d8b', '#60929f', '#80a8b2', '#a0bec5', '#c0d4d8', '#dfe9ec', 
		'#150000', '#2b0000', '#400000', '#550000', '#6b0000', '#800000', '#922424', '#a44949', '#b66d6d', '#c99292', '#dbb6b6', '#eddbdb', 
		'#151500', '#2b2b00', '#404000', '#555500', '#6b6b00', '#808000', '#929224', '#a4a449', '#b6b66d', '#c9c992', '#dbdbb6', '#ededdb', 
		'#001500', '#002b00', '#004000', '#005500', '#006b00', '#008000', '#249224', '#49a449', '#6db66d', '#92c992', '#b6dbb6', '#dbeddb', 
		'#001515', '#002b2b', '#004040', '#005555', '#006b6b', '#008080', '#249292', '#49a4a4', '#6db6b6', '#92c9c9', '#b6dbdb', '#dbeded', 
		'#000015', '#00002b', '#000040', '#000055', '#00006b', '#000080', '#242492', '#4949a4', '#6d6db6', '#9292c9', '#b6b6db', '#dbdbed', 
		'#150015', '#2b002b', '#400040', '#550055', '#6b006b', '#800080', '#922492', '#a449a4', '#b66db6', '#c992c9', '#dbb6db', '#eddbed', 
		'#000c00', '#001800', '#002400', '#003000', '#003c00', '#004800', '#246224', '#497c49', '#6d966d', '#92b192', '#b6cbb6', '#dbe5db', 
		'#00090a', '#001114', '#011a1e', '#012328', '#012b32', '#01343c', '#255158', '#4a6e74', '#6e8b90', '#92a8ab', '#b6c5c7', '#dbe2e3', 
		'#2b1c1c', '#553939', '#805555', '#aa7171', '#d58e8e', '#ffaaaa', '#ffb6b6', '#ffc2c2', '#ffcece', '#ffdbdb', '#ffe7e7', '#fff3f3', 
		'#2b2b1c', '#555539', '#808055', '#aaaa71', '#d5d58e', '#ffffaa', '#ffffb6', '#ffffc2', '#ffffce', '#ffffdb', '#ffffe7', '#fffff3', 
		'#1c2b1c', '#395539', '#558055', '#71aa71', '#8ed58e', '#aaffaa', '#b6ffb6', '#c2ffc2', '#ceffce', '#dbffdb', '#e7ffe7', '#f3fff3', 
		'#1c2b2b', '#395555', '#558080', '#71aaaa', '#8ed5d5', '#aaffff', '#b6ffff', '#c2ffff', '#ceffff', '#dbffff', '#e7ffff', '#f3ffff', 
		'#1c1c2b', '#393955', '#555580', '#7171aa', '#8e8ed5', '#aaaaff', '#b6b6ff', '#c2c2ff', '#ceceff', '#dbdbff', '#e7e7ff', '#f3f3ff', 
		'#2b1c2b', '#553955', '#805580', '#aa71aa', '#d58ed5', '#ffaaff', '#ffb6ff', '#ffc2ff', '#ffceff', '#ffdbff', '#ffe7ff', '#fff3ff', 
		'#032318', '#054531', '#086849', '#0a8a61', '#0dad7a', '#0fcf92', '#31d6a2', '#54ddb1', '#76e4c1', '#98ead0', '#baf1e0', '#ddf8ef', 
		'#002021', '#003f42', '#005f63', '#007f83', '#009ea4', '#00bec5', '#24c7cd', '#49d1d6', '#6ddade', '#92e3e6', '#b6ecee', '#dbf6f7');
function ColorElement(colorbox, color) {
	var e = document.createElement('div');
	e.colorelement = this;
	
	e.colorbox = colorbox;
	e.color = color;
	
	
	
	e.onclick = function() {
		this.Click();
	}
	
	e.Init = function() {
		var style = this.style;
		style.cssFloat = 'left';
		style.cursor = 'pointer';
		style.visibility = 'visible';

		if (this.color) {
			style.fontSize = '2px';
			style.width = this.colorbox.colorWidth + 'px';
			style.height = this.colorbox.colorHeight + 'px';
			style.backgroundColor = this.color;
			this.title = this.color;
		} else {
			style.fontSize = '10px';
			style.width = '100%';
			style.height = '12px';
			style.textAlign = 'center';
			style.backgroundColor = '#FFFFFF';
			this.title = 'clear';
			this.innerHTML = 'clear';
		}
			
		
		
		this.colorbox.appendChild(this);
	}
	
	e.Click = function() {
		this.colorbox.SetColor(this.color, true);
	}
	
	e.Init();
	return e;
}
function ColorBox(element) {
	var e = defaultConstructor(element);
	e.setProtoClass('colorbox');	
	e.ColorElements = new Array();
//	e.color = e.getAttr('selcolor', '#FFFFFF');

	e.colorWidth = parseInt(e.getAttr('colwidth', '10'));
	e.colorHeight = parseInt(e.getAttr('colheight', '10'));
	e.oncolorchange = Function(e.getAttr('oncolorchange', 'null'));
	e.colorDIV = getObject(e.getAttr('colordiv'));
	e.useDefaults = (e.getAttr('usedefaults', 'true') == 'true');
	e.DoColorChange = function() {
		if (typeof(this.oncolorchange) == "function") {
			this.oncolorchange(this.color, this);
		}
	}
	
	e.SetColor = function(color, fireInputOnChange) {
		this.color = color;
		if (this.inputElement) {
			this.inputElement.value = this.color;
			
			if (fireInputOnChange == true && this.inputElement.onchange) {
				this.inputElement.onchange();
			}
		}
		if (this.colorDIV) {
			this.colorDIV.style.backgroundColor = color;
		}
		this.DoColorChange();
	}
	e.setColor = e.SetColor;
	
	e.GetWidth = function() {
		return this.offsetWidth;
	}
	
	e.GetHeight = function() {
		return this.offsetHeight;
	}
	
	e.AddColor = function(color) {
		if (typeof(color) == 'string') {
			var colorelement = ColorElement(this, color);
			this.ColorElements.push(colorelement);
		}
		if (typeof(color) == 'object' && (color.length)) {
			for (var c = 0; c < color.length; c++) {
				this.AddColor(color[c]);
			}
		}
	}
	
	e.Arrange = function() {
	}
	
	e.AttachDIV = function(adiv) {
		this.colorDIV = getObject(adiv);
		this.DoColorChange();
	}
	
	e.AddDefaults = function() {
		this.AddColor(DefaultColors);
	}
	if (e.useDefaults) {
		e.AddDefaults();
	}
	e.afterCreation = function() {
		this.SetColor(this.getAttr('selcolor', '#FFFFFF'));
		this.inputElement = getObject(this.getAttr('inputname'));
		if (this.inputElement) {
			this.inputElement.colorBox = this;
		}
	}
	return e;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        Countdown Timer, Time Display
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TimerBase(element) {
	var e = defaultConstructor(element);
	e.timer = new Timer(1000, 0);
	e.timer.timerElement = e;
	e.innerHTML = 'Initialising clock...';
	e.setDisplayTime = function(hours, minutes, seconds) {
		var h = (hours < 10) ? '0' + hours : hours;
		var m = (minutes < 10) ? '0' + minutes : minutes;
		var s = (seconds < 10) ? '0' + seconds : seconds;

		this.innerHTML = h + ':' + m + ':' + s;
	}
	return e;
}

function CurrentTime(element) {
	
	var e = TimerBase(element);
	e.setProtoClass('currenttime');

	e.timer.ontimertick = function(timer, firstTick) {
		var d = new Date();
		this.timerElement.setDisplayTime(d.getHours(), d.getMinutes(), d.getSeconds());
		
	}
	e.afterCreation = function() {
		this.timer.enable();
	}
	
	e.disable = function() {
		this.timer.disable();
	}
	
	return e;
}

function CountdownTimer(element) {
	var e = TimerBase(element);
	e.setProtoClass('countdowntimer');
	e.startTime = null;
	e.timeLimit = 0;
	e.firedWarning = false;
	e.warningTime = e.getAttr('warningtime', 5);
	e.ontimeup = Function(e.getAttr('ontimeup'));
	e.onwarning = Function(e.getAttr('onwarning'));
	e.doWarning = function() {
		if (typeof(this.onwarning) == "function") {
			this.onwarning(this);
			this.firedWarning = true;
		}
	}
	e.doTimeUp = function() {
		if (typeof(this.ontimeup) == "function") {
			this.ontimeup(this);
		}
	}
	
	
	e.timer.ontimertick = function(timer, firstTick) {
		
		var t = this.timerElement;
		if (t.endTime) {
			var currTime = new Date();
			var difference = t.endTime.getTime() - currTime.getTime();
			var totalseconds = (difference / 1000) + 1;
			
			var seconds = totalseconds % 60;
			
			var totalminutes = totalseconds / 60;
			var minutes = totalminutes % 60;
			var hours = totalseconds / (60 * 60);
			
			t.setDisplayTime(Math.floor(hours), Math.floor(minutes), Math.floor(seconds));
			if (totalseconds <= t.warningTime && !t.firedWarning) {
				t.doWarning();
			}
			if (currTime.getTime() > t.endTime.getTime()) {
				this.disable();
				t.doTimeUp();
				t.endTime = null;
			}
		}	
	}
	
	e.start = function(timeLimit) {
		this.timer.disable();
		this.endTime = new Date();
		this.endTime.add(timeLimit * 1000);
		this.firedWarning = false;
		this.timer.enable();
	}
	return e;	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                        Register Classes
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
registerClass('listbox', ListBox);
registerClass('tabset', TabSet);
registerClass('tabbutton', TabButton);
registerClass('tabpage', TabPage);
registerClass('tabpages', TabPages);
registerClass('absolutecenter', AbsoluteCenter);
registerClass('infoslider', InfoSlider);
registerClass('colorbox', ColorBox);
registerClass('countdowntimer', CountdownTimer);
registerClass('currenttime', CurrentTime);
registerClass('basic', Basic);