function addLoadListener(fn){
	if(typeof window.addEventListener != "undefined"){	// Mozilla, Safari, et.
		window.addEventListener("load", fn, false);
	}
	else if(typeof document.addEventListener != "undefined"){	// Opera
		document.addEventListener("load", fn, false);
	}
	else if(typeof window.attachEvent != "undefined"){	// IE
		window.attachEvent("onload", fn);
	}
	else{	// IE5 mac
		var oldfn = window.onload;
		if(typeof oldfn != "function"){
			window.onload = fn;
		}
		else{
			window.onload = function(){
				oldfn();
				fn();
			}
		}
	}
}

function attachEventListener(target, eventType, functionRef, capture){
	if(typeof target.addEventListener != "undefined"){	// non-IE
		target.addEventListener(eventType, functionRef, capture);
	}
	else if(typeof target.attachEvent != "undefined"){	// IE
		target.attachEvent("on" + eventType, functionRef);
	}
	else{	// IE5 mac
		eventType = "on" + eventType;
		if(typeof target[eventType] == "function"){
			var oldListener = target[eventType];
			target[eventType] = function(){
				oldListener();
				return functionRef();
			}
		}
		else{
			target[eventType] = functionRef;
		}
	}	
}

function detachEventListener(target, eventType, functionRef, capture){
	if(typeof target.removeEventListener != "undefined"){	// non-IE
		target.removeEventListener(eventType, functionRef, capture);
	}
	else if(typeof target.detachEvent != "undefined"){	// IE
		target.detachEvent("on" + eventType, functionRef);
	}
	else{	// IE5 mac
		target["on" + eventType] = null;
	}
}

function getPosition(theElement){
	var positionX = 0;
	var positionY = 0;

	while(theElement != null){
		positionX += theElement.offsetLeft;
		positionY += theElement.offsetTop;
		theElement = theElement.offsetParent;
	}

	return [positionX, positionY];
}


function getEventTarget(event){
	// retrieves target element, then bubbles up, returning first non-text node
	// this is the element MOST LIKELY (not exact) to which the event handler was applied
	var targetElement = null;

	if(typeof event.target != "undefined"){	// non-IE
		targetElement = event.target;
	}
	else{	// IE
		targetElement = event.srcElement;
	}

	var TEXT_NODE = 3;

	while(targetElement.nodeType == TEXT_NODE && targetElement.parentNode != null){
		targetElement = targetElement.parentNode;
	}

	return targetElement;
}

function getScrollingPosition(){
	// array for X and y scroll position
	var position = [0, 0];

	// if the window.pageYOffset property is supported
	// (Mozilla, Konqueror, Safari, Opera)
	if(typeof window.pageYOffset != "undefined"){
		// store position values
		position = [window.pageXOffset, window.pageYOffset];
	}

	// if the documentElement.scrollTop property is supported
	// and the value is greater than zero
	// (IE6+ standards mode)
	if(typeof document.documentElement.scrollTop != "undefined"
	   && document.documentElement.scrollTop > 0){
		// store position values
		position = [document.documentElement.scrollLeft,
					document.documentElement.scrollTop];
	}

	// if the body.scrollTop is supported
	// (IE5, IE6+ quirks mode)
	if(typeof document.body.scrollTop != "undefined"){
		// store position values
		position = [document.body.scrollLeft, document.body.scrollTop];
	}

	return position;
}

function identifyBrowser(){
	/*
	  will return one of the following values:
	  "kde" - konquerer 3.2+
	  "opera7" - opera7+
	  "opera5" - opera 5-6
	  "ie5mac" - IE5 (Mac)
	  "ie[x]" - IE (Windows versions), [x] is replaced with version number (5.5 and above only)
	  "safari1.2" - safari 1.2+
	  "safari1" - safari1
	  "mozilla" - gecko-based browsers (firefox, epiphany, etc.)

	  false - javascript not supported
	*/
	var agent = navigator.userAgent.toLowerCase();

	if(typeof navigator.vendor != "undefined" 
	   && navigator.vendor == "KDE" 
	   && typeof window.sidebar != "undefined"){
		// window.sidebar is available in konqueror 3.2+
		return "kde";
	}
	else if(typeof window.opera != "undefined"){
		var version = parseFloat(agent.replace(/.*opera[\/ ]([^ $]+).*/, "$1"));

		if(version >= 7){
			return "opera7";
		}
		else if(version >= 5){
			return "opera5";
		}

		return false;
	}
	else if(typeof document.all != "undefined"){	// IE
		if(typeof document.getElementById != "undefined"){
			var browser = agent.replace(/.*ms(ie[\/ ][^ $]+).*/, "$1").replace(/ /, "");
 
			if(typeof document.uniqueID != "undefined"){
				if(browser.indexOf("5.5") != -1){
					return browser.replace(/(.*5\.5).*/, "$1");
				}
				else{
					return browser.replace(/(.*)\..*/, "$1");
				}
			}
			else{
				return "ie5mac";
			}
		}

		return false;	// very old version of IE that doesn't support JavaScript
	}
	else if(typeof document.getElementById != "undefined"){
		if(navigator.vendor.indexOf("Apple Computer, Inc.") != -1){
			if(typeof window.XMLHttpRequest != "undefined"){
				return "safari1.2";
			}
 
			return "safari1";
		}
		else if(agent.indexOf("gecko") != -1){
			return "mozilla";	// firefox, epiphany, etc.
		}
	}

	return false;
}

function identifyOS(){
	var agent = navigator.userAgent.toLowerCase();

	if(agent.indexOf("win") != -1){
		return "win";
	}
	else if(agent.indexOf("mac")){
		return "mac";
	}
	else{
		return "unix";
	}

	return false;
}

function stopDefaultAction(event){
	// cancel element's default action

	event.returnValue = false;	// IE

	if(typeof event.preventDefault != "undefined"){	// non-IE
		event.preventDefault();
	}

	return true;
}

function setPointerCursor(event){
	if(typeof event == "undefined"){
		event = window.event;
	}

	var target = getEventTarget(event);
	target.style.cursor = "pointer";
}