var Util = {}

// actually add an event listener, regardless of browser
Util.AddListener = function(obj, eventType, listenerFunction)
{
	if (!obj)
	{
		alert("bad object for " + eventType + ", obj:" + obj + ", fn:" + listenerFunction + ", caller:" + addListener.caller);
		return;
	}
	if (obj.addEventListener)
	{
		obj.addEventListener(eventType, listenerFunction, true);
		
	}
	else if (obj.attachEvent)
	{
		var success = obj.attachEvent("on" + eventType, listenerFunction);
	}
}

function cancelEvent(e)
{
	e.cancelBubble = true;
	
	if (e.preventDefault)
	{
		e.preventDefault()
	}
	
	if (e.stopPropagation)
	{
		e.stopPropagation()
	}
	
	return false;
}

// recursively find the X position of the specified element.	
function getLeft(obj)
{
	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;
	}
}

Util.RandInt = function(max)
{
	return Math.floor(Math.random()*max);
}

Util.ForceInt = function(val)
{
	if (isNaN(val))
	{
		if (!val || !val.replace)
		{
			return 0;
		}
		val = val.replace(/[^0-9]/, "");
	}
	val = parseInt(val);
	
	return isNaN(val) ? 0 : val;
	
}

// spin thru the supplied collection, passing each to the function as an arument.
Util.Map = function(collection, func)
{
	for (var a=0; a<collection.length; a++)
	{
		func(collection[a]);
	}
}

// spin thru the supplied collection of objects and call the requested method on each one.
Util.MapMethod = function(collection, methodName)
{
	for (var a=0; a<collection.length; a++)
	{
		collection[a][methodName]();
	}
}

// spin thru the supplied collection, combining all values using the specified function
Util.Reduce = function(fn, collection, init)
{
	var sum = init;
	for (var a=0; a<collection.length; a++)
	{
		sum = fn( sum, collection[a] );
	}
	return sum;
}

// Util.CopyProperties(srcObj, destObj, "x", "y", "height");
Util.CopyProperties = function(src, dest)
{
	for (var a=2; a<Util.CopyProperties.arguments.length; a++)
	{
		var propertyName = Util.CopyProperties.arguments[a];
		dest[propertyName] = src[propertyName];
	}
}


// A weak implementation of String.format().  
// Doesn't do global substitutions (so "{0} {1} {0}" won't replace the 2nd {0})
Util.Format = function(formatString)
{
	for (var a=1; a<Util.Format.arguments.length; a++)
	{
		formatString = formatString.replace("{" + (a-1) + "}", Util.Format.arguments[a]);
	}

	return formatString;
}

Util.GetSelectValue = function(select)
{
	return select.options[select.selectedIndex].value
}

Util.GetMax = function(num1, num2)
{
	return num1 > num2 ? num1 : num2;
}

Util.GetMin = function(num1, num2)
{
	return num1 < num2 ? num1 : num2;
}

// ensure that the value lies between min & max
Util.Bound = function(value, min, max)
{
	if (value < min)
	{
		return min;
	}
	if (value > max)
	{
		return max;
	}
	return value;
}

Util.Trace = function(obj, goBig)
{
	var txt = "";
	
	txt += obj + "\r\n";
	
	if (goBig)
	{
		for (key in obj)
		{
			txt += key + ":" + obj[key] + "\r\n";
			//txt += key + ":" + Util.Trace(obj[key]) + "\r\n";
			
		}
		txt += "\r\n\r\n";
	}
	
	return txt;

}



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);
}

Util.AlertMulti = function()
{
	var line = "";
	var isFirst = true;
	for (var a=0; a<Util.AlertMulti.arguments.length; a++)
	{
		if (!isFirst)
		{
			line += ", ";
		}
		line += Util.AlertMulti.arguments[a];
		isFirst = false;
	}

	alert(line);
}