// Event handling code
// written by Dean Edwards, 2005
// with input from Tino Zijdel - crisp@xs4all.nl
// http://therealcrisp.xs4all.nl/upload/addEvent_dean.html
// Broken by Draknek

function add_event (obj, type, func)
{
	obj = get_element(obj);

	if (obj.addEventListener)
	{
		obj.addEventListener(type, func, false);
	}
	else
	{
		add_event_fallback(obj, type, func);
	}
}

function add_event_fallback (element, type, handler)
{
	if (! handler.$$guid)
	{
		handler.$$guid = add_event_fallback.guid++;
	}
	
	if (! element.events)
	{
		element.events = {};
	}
	
	var handlers = element.events[type];
	
	if (! handlers)
	{
		handlers = element.events[type] = {};
		if (element['on' + type]) handlers[0] = element['on' + type];
		element['on' + type] = handleEvent;
	}

	handlers[handler.$$guid] = handler;
}
add_event_fallback.guid = 1;

function remove_event (obj, type, func)
{
	obj = get_element(obj);

	if (obj.removeEventListener)
	{
		obj.removeEventListener(type, func, false);
	}
	else
	{
		remove_event_fallback(obj, type, func);
	}
}

function remove_event_fallback (element, type, handler)
{
	if (element.events && element.events[type] && handler.$$guid)
	{
		delete element.events[type][handler.$$guid];
	}
}

function handleEvent(event)
{
	event = event || fixEvent(window.event);
	var returnValue = true;
	var handlers = this.events[event.type];

	for (var i in handlers)
	{
		if (!Object.prototype[i])
		{
			this.$$handler = handlers[i];
			if (this.$$handler(event) === false) returnValue = false;
		}
	}

	if (this.$$handler) this.$$handler = null;

	return returnValue;
}

function fixEvent(event)
{
	event.preventDefault = fixEvent.preventDefault;
	event.stopPropagation = fixEvent.stopPropagation;
	return event;
}
fixEvent.preventDefault = function()
{
	this.returnValue = false;
}
fixEvent.stopPropagation = function()
{
	this.cancelBubble = true;
}

// Class manipulation functions, also from Dean Edwards
// http://dean.edwards.name/IE7/caveats/

function add_class(obj, className)
{
	obj = get_element(obj);
	
    if (! has_class(obj, className))
	{
		if (obj.className)
		{
			obj.className += " " + className;
		}
		else
		{
			obj.className = className;
		}
	}
}

function remove_class (obj, className)
{
	obj = get_element(obj);
    var regexp = new RegExp("(^|\s)" + className + "(\s|$)");
	obj.className = obj.className.replace(regexp, "$2");
}

function has_class (obj, className)
{
	obj = get_element(obj);
    var regexp = new RegExp("\b" + className + "\b");
    return regexp.test(obj.className);
}

// Get the current style of an object, from PPK
// http://www.quirksmode.org/dom/getstyles.html

function get_style (obj, style)
{
	obj = get_element(obj);
	
	if (! obj)
	{
		return false;
	}
	
	if (obj.currentStyle)
	{
		return obj.currentStyle[style];
	}
	else if (document.defaultView.getComputedStyle)
	{
		return document.defaultView.getComputedStyle(obj, null).getPropertyValue(style);
	}
}

// Everything else made by Draknek
// Use as you wish

// Call a function when the page is loaded
function add_load_event (func, wait)
{
	var func_once = once_only(func);
	add_event_fallback(window, 'load', func_once); // Using the advanced model doesn't work in all browsers

	if (! wait)
	{
		add_event(document, 'DOMContentLoaded', func_once); // Start earlier if we can
	}
}

// Returns a function that will only execute once
function once_only (func)
{
	return function (e)
	{
		if (! func.called)
		{
			func.called = true;
			return func(e);
		}
	}
}

function get_element (obj)
{
	if (typeof(obj) == 'string')
	{
		return document.getElementById(obj);
	}
	else
	{
		return obj;
	}
}

function get_children (obj, tag)
{
	obj = get_element(obj);
	
	if (! (obj && (obj.children || obj.childNodes)))
	{
		return false;
	}
	
	var ret = [];
	
	if ((tag == '*') || ! tag)
	{
		if (obj.children)
		{
			ret = obj.children;
		}
		else
		{
			for (var i = 0; i < obj.childNodes.length; i++)
			{
				if (obj.childNodes[i].nodeType == 1)
				{
					ret[ret.length] = obj.childNodes[i];
				}
			}
		}
	}
	else
	{
		tag = tag.toUpperCase();
		var children = obj.children || obj.childNodes;
		
		for (var i = 0; i < children.length; i++)
		{
			if (children[i].nodeName == tag)
			{
				ret[ret.length] = children[i];
			}
		}
	}
	
	return ret;
}

function get_child (obj, tag)
{
	return get_first(get_children(obj, tag));
}

function get_descendants (obj, tag)
{
	obj = get_element(obj);
	return obj.getElementsByTagName(tag);
}

function get_text_nodes (obj)
{
	obj = get_element(obj);
	var ret = [];
	
	if (obj && obj.childNodes)
	{
		for (var i = 0; i < obj.childNodes.length; i++)
		{
			if (obj.childNodes[i].nodeType == 3)
			{
				ret[ret.length] = obj.childNodes[i];
			}
		}
	}
	
	return ret;
}

function get_text (obj)
{
	return get_first(get_text_nodes(obj)).nodeValue;
}

function get_data (obj)
{
	return get_text(obj);
}

function get_first (array)
{
	if (array && (array.length == 1))
	{
		return array[0];
	}
	else
	{
		return false;
	}
}

// val is between 0 and 10
function set_opacity (obj, val)
{
	obj = get_element(obj);
	
	if (! obj || ! obj.style)
	{
		return false;
	}
	
	obj.style.MozOpacity = val/10;
	obj.style.opacity = val/10;
	obj.style.filter = 'alpha(opacity=' + val*10 + ')';
}

function rand (max)
{
	return Math.floor(Math.random() * max);
}
