var isSafari = navigator.userAgent.indexOf("Safari") > -1
var isWebKit = navigator.userAgent.indexOf("WebKit") > -1
// return a reference to the supplied object, whether we refer to it by name or by reference
function getLazyReference(obj)
{
	if (obj.id)
	{
		return obj;
	}
	else
	{
		return document.getElementById(obj);
	}
}

function removeElement(obj)
{
	if (obj && obj.parentNode)
	{
		obj.parentNode.removeChild(obj);
	}
}

function getFrameWindow(frameName)
{
	var frame = document.getElementById(frameName)
	
	if (frame && frame.contentWindow)
	{
		frame = frame.contentWindow;
	}
		
	return frame;
}

// actually add an event listener, regardless of browser
function addListener(obj, eventType, listenerFunction)
{
	if (!obj)
	{
		alert("bad object for " + eventType + ", obj:" + obj + ", fn:" + listenerFunction + ", caller:" + addListener.caller);
		return;
	}
	if (obj.addEventListener)
	{
		return obj.addEventListener(eventType, listenerFunction, true);
		
	}
	else if (obj.attachEvent)
	{
		return  obj.attachEvent("on" + eventType, listenerFunction);
	}
}

function cancelEvent(e)
{
	e.cancelBubble = true;
	
	if (e.preventDefault)
	{
		e.preventDefault()
	}
	
	if (e.stopPropagation)
	{
		e.stopPropagation()
	}
	
	return false;
}

// yank an element out of an array (by reference, so nothing is returned)
function arrayRemove(array, obj)
{
	for (var a=0; a<array.length; a++)
	{
		if (array[a] == obj)
		{
			array.splice(a, 1);
		}
	}
}

// recursively find the X position of the specified element.	
function getLeft(obj)
{
//logMulti(obj.offsetLeft + ": " + obj.id, obj.tagName);
	if (obj.offsetParent)
	{
		return obj.offsetLeft + getLeft(obj.offsetParent);
	}
	else
	{
		return obj.offsetLeft;
	}
}

// recursively find the Y position of the specified element.	
function getTop(obj)
{
	if (obj.offsetParent)
	{
		var off = obj.offsetTop + getTop(obj.offsetParent);
		return off;
		//return obj.offsetTop + getTop(obj.offsetParent);
	}
	else
	{
		return obj.offsetTop;
	}
}

// recursively find the first descendant of this object with the specified className
function getDescendantByClassName(obj, className)
{
	if (obj.className == className)
	{
		return obj;
	}
	
	for (var a=0; a<obj.childNodes.length; a++)
	{
		/*
		if (obj.childNodes[a].className == className)
		{
			return obj.childNodes[a];
		}
		*/
		
		var descendant = getDescendantByClassName(obj.childNodes[a], className);
		if (descendant != null)
		{	
			return descendant;
		}
	}
	
	return null;
}

function trace(obj, goBig)
{
	var txt = document.getElementById('txt');
	if (txt == null)
	{
		return;
	}
	
	txt.value += obj + "\r\n";
	
	if (goBig)
	{
		for (key in obj)
		{
			txt.value += key + ":" + obj[key] + "\r\n";
			
		}
		txt.value += "\r\n\r\n";
	}

}

var logShouldClear = true;
function log(text, clear)
{
	if (window.dontLog)
		return;
		
	var txt = document.getElementById("txt");
	if (txt)
	{
		if (clear || logShouldClear)
		{
			txt.value = "";
		}
		txt.value = txt.value + text + "\r\n";
	}
	
	logShouldClear = false;
	setTimeout("logShouldClear = true", 100);
}

function logMulti()
{
	if (window.dontLog)
		return;
		
	var line = "";
	var isFirst = true;
	for (var a=0; a<logMulti.arguments.length; a++)
	{
		if (!isFirst)
		{
			line += ", ";
		}
		line += logMulti.arguments[a];
		isFirst = false;
	}

	log(line);
}

function alertMulti()
{
	var line = "";
	var isFirst = true;
	for (var a=0; a<alertMulti.arguments.length; a++)
	{
		if (!isFirst)
		{
			line += ", ";
		}
		line += alertMulti.arguments[a];
		isFirst = false;
	}

	alert(line);
}

// DEPRECATED in favor of the get & set methods below
function PngSrc(image, src)
{
	image = getLazyReference(image);
	
	// IE6 doesn't like PNGs, so we'll try GIFs instead
	if (document.all && navigator.appVersion.indexOf("MSIE 6") > -1)
	{
		src = src.replace(".png", ".gif");
	}
	
	image.src = src;
}

function GetPngSrc(src)
{
	// IE6 doesn't like PNGs, so we'll try GIFs instead
	if (document.all && navigator.appVersion.indexOf("MSIE 6") > -1)
	{
		return src.replace(".png", ".gif");
	}
	
	return src;
}

function SetPngSrc(image, src)
{
	image = getLazyReference(image);
	
	// IE6 doesn't like PNGs, so we'll try GIFs instead
	if (document.all && navigator.appVersion.indexOf("MSIE 6") > -1)
	{
		src = src.replace(".png", ".gif");
	}
	
	image.src = src;
}

function getGreater(first, second)
{
	if (first > second)
	{
		return first;
	}
	
	return second;
}

function getLesser(first, second)
{
	if (first < second)
	{
		return first;
	}
	
	return second;
}

function moveElementTo(element, x, y)
{
	var obj = getLazyReference(element);

	obj.style.left = x + 'px';
	obj.style.top = y + 'px';
}

function slideElementTo(element, x, y, stepCount, hideOnArrival)
{
	var obj = getLazyReference(element);
	
	if (obj.cancelSlide)
	{
		obj.cancelSlide = null;
		return;
	}
	
	var currentX = parseInt(obj.style.left);
	var currentY = parseInt(obj.style.top);
	
	if (!isNaN(currentX))
	{
		var newX = currentX + (x - currentX)/stepCount;
		obj.style.left = newX + 'px';
	}
	if (!isNaN(currentY))
	{
		var newY = currentY + (y - currentY)/stepCount;
		obj.style.top = newY + 'px';
	}
	
	
	if (stepCount > 1)
	{
		hideOnArrival = (hideOnArrival) ? true : false; // deal with possible nulls
		var script = "slideElementTo('" + obj.id + "', " 
						+ x + ", " 
						+ y + ", " 
						+ (stepCount-1) + ", "
						+ hideOnArrival + ")";

		setTimeout(script, 30);  
	}
	else if (hideOnArrival)
	{
		obj.style.display = "none";
	}
	
}   

function fadeElementOut(id, count, doc)
{
	doc = doc ? doc : document;
	try
	{
		var obj = doc.getElementById(id);
		if (!obj)
		{
			log("bad object: " + id);
			return;
		}
		
		obj.style.filter = "alpha(opacity:" + count + ")";
		obj.style.MozOpacity = count/100;
		obj.style.opacity = count/100;
		
		if (count > 0)
		{
			setTimeout(function(){fadeElementOut(id, count-5, doc);}, 30);
		}
		else
		{
			obj.style.display="none";
		}
	}
	catch(ex)
	{
		// This is just a silly effect.  It's not worth throwing if it fails.
		// NOTE: we end up here sometimes if the page is redirected mid fade.
	}
}
 

function createCookie(name,value,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 = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

function getSelectValue(select)
{
	select = getLazyReference(select);
	return select.options[select.selectedIndex].value;
}

// 
// sets the select box to the specified value, creating a new option if necessary (and requested).
// returns the index of the selected option.
//
function setSelectValue(select, value, createIfNotExists)
{
	select = getLazyReference(select);
	for (var a=0; a<select.options.length; a++)
	{
		if (select.options[a].value == value)
		{
			select.selectedIndex = a;
			return a;
		}
	}
	if (createIfNotExists)
	{
		// TODO - create, select, and return the index of a new option
	}
	return -1;
	
}

// A weak implementation of String.format().  
// Doesn't do global substitutions (so "{0} {1} {0}" won't replace the 2nd {0})
function format(formatString)
{
	for (var a=1; a<format.arguments.length; a++)
	{
		formatString = formatString.replace("{" + (a-1) + "}", format.arguments[a]);
	}

	return formatString;
}

function trim(text) 
{  
	return text.replace(/^\s+|\s+$/g,'');
}

function ltrim(text) 
{  
	return text.replace(/^\s+/g,'');
}

function getProtocol()
{
	return location.href.split(":")[0];
}
