function BrowserDetect() 
{
	var ua = navigator.userAgent.toLowerCase(); 
	this.ua = ua;

	this.isGecko     = (ua.indexOf('gecko') != -1);
	this.isMozilla   = (this.isGecko && ua.indexOf("gecko/") + 14 == ua.length);
	this.isNS        = ( (this.isGecko) ? (ua.indexOf('netscape') != -1) : ( (ua.indexOf('mozilla') != -1) && (ua.indexOf('spoofer') == -1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera') == -1) && (ua.indexOf('webtv') == -1) && (ua.indexOf('hotjava') == -1) ) );
	this.isIE        = ( (ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1) ); 
	this.isOpera     = (ua.indexOf("opera") != -1); 
		
	this.versionMinor = parseFloat(navigator.appVersion); 
	
	if (this.isNS && this.isGecko)
		this.versionMinor = parseFloat(ua.substring(ua.lastIndexOf('/')+1));
	else if (this.isIE && this.versionMinor >= 4)
		this.versionMinor = parseFloat(ua.substring(ua.indexOf('msie ')+5));
	
	this.versionMajor = parseInt(this.versionMinor); 
	this.geckoVersion = ( (this.isGecko) ? ua.substring( (ua.lastIndexOf('gecko/') + 6), (ua.lastIndexOf('gecko/') + 14) ) : -1 );
	
	this.isWin   = (ua.indexOf('win') != -1);
	this.isWin32 = (this.isWin && ( ua.indexOf('95') != -1 || ua.indexOf('98') != -1 || ua.indexOf('nt') != -1 || ua.indexOf('win32') != -1 || ua.indexOf('32bit') != -1) );
	this.isMac   = (ua.indexOf('mac') != -1);
	this.isUnix  = (ua.indexOf('unix') != -1 || ua.indexOf('linux') != -1 || ua.indexOf('sunos') != -1 || ua.indexOf('bsd') != -1 || ua.indexOf('x11') != -1);
	
	this.isNS4x = (this.isNS && this.versionMajor == 4);
	this.isNS40x = (this.isNS4x && this.versionMinor < 4.5);
	this.isNS47x = (this.isNS4x && this.versionMinor >= 4.7);
	this.isNS4up = (this.isNS && this.versionMinor >= 4);
	this.isNS6x = (this.isNS && this.versionMajor == 6);
	this.isNS6up = (this.isNS && this.versionMajor >= 6);
	
	this.isIE4x = (this.isIE && this.versionMajor == 4);
	this.isIE4up = (this.isIE && this.versionMajor >= 4);
	this.isIE5x = (this.isIE && this.versionMajor == 5);
	this.isIE55 = (this.isIE && this.versionMinor == 5.5);
	this.isIE5up = (this.isIE && this.versionMajor >= 5);
	this.isIE6x = (this.isIE && this.versionMajor == 6);
	this.isIE6up = (this.isIE && this.versionMajor >= 6);
	
	this.isIE4xMac = (this.isIE4x && this.isMac);

	return this;
}
var browser = new BrowserDetect();

NS.createNS("Utils.CSS");

Utils.CSS.getStyle = function(obj,name)
{
	if (obj.currentStyle)
		return obj.currentStyle[name];
	else if (window.getComputedStyle)
		return document.defaultView.getComputedStyle(obj,null).getPropertyValue(name);
}

Utils.CSS.hasClass = function(obj,cname,exactMatch)
{
	if (exactMatch == null)
		exactMatch = true;
	
	if (!exactMatch)
		cname = cname + "*";
	
	var regex = new RegExp('\\b'+cname+'\\b'); 
	return regex.test(obj.className);
}

Utils.CSS.addClass = function(obj,cname){ if (!Utils.CSS.hasClass(obj,cname)) obj.className = obj.className+' '+cname; }
Utils.CSS.addClasses = function(obj,classes){ for (var i=0; i < classes.length; i++) Utils.CSS.addClass(obj,classes[i]); }
Utils.CSS.remClass = function(obj,cname) { if (Utils.CSS.hasClass(obj,cname)) { var regex = new RegExp('\\s*\\b'+cname+'\\b','g'); obj.className = obj.className.replace(regex,''); } }
Utils.CSS.remClasses = function(obj,classes) { for (var i=0; i < classes.length; i++) Utils.CSS.remClass(obj,classes[i]); }
Utils.CSS.getClasses = function(obj) { return obj.className.split(" "); }


NS.createNS("Utils.OOP");

Utils.OOP.extend = function(newClass,baseClass)
{
	function base() {};
	base.prototype = baseClass.prototype;
	newClass.prototype = new base();
	newClass.prototype.constructor = newClass;	
	newClass.parentConstructor = baseClass;
	newClass.parentClass = baseClass.prototype;
	newClass.prototype.parentMethod = function(name,params) { baseClass.prototype[name].apply(this,params); }
}

NS.createNS("Utils.DOM");

Utils.DOM.isChildElement = function(el,parentEl)
{
	while(el != null)
	{
		if (el.parentNode == parentEl)
			return true;
		el = el.parentNode;
	}
	return false;
}

Utils.DOM.getElementsByClassName = function(parentEl,className,exactMatch,elementsToCheck)
{
	if (!exactMatch)
		exactMatch = true;
	
	if (!elementsToCheck)
		elementsToCheck = "*";
		
	var elList = new Array();
	var elements = parentEl.getElementsByTagName(elementsToCheck);
	
	for (var i=0; i < elements.length; i++)
	{
		if (Utils.CSS.hasClass(elements[i],className,exactMatch))
			elList.push(elements[i]);
	}
	
	return elList;
}

Utils.DOM.setWidth = function(obj,width) { obj.style.width = width + "px"; }
Utils.DOM.setHeight = function(obj,height) { obj.style.height = height + "px"; }
Utils.DOM.setTop = function(obj,top) { obj.style.top = top + "px"; }
Utils.DOM.setLeft = function(obj,left) { obj.style.left = left + "px"; }
Utils.DOM.setSize = function(obj,width,height) { if (width != null) Utils.DOM.setWidth(obj,width); if (height != null) Utils.DOM.setHeight(obj,height); }
Utils.DOM.setPos = function(obj,top,left) { if (top) this.setTop(obj,top); if (left) this.setLeft(obj,left); }
Utils.DOM.setBounds = function(obj,top,left,width,height) { this.setPos(obj,top,left); this.setSize(obj,width,height); }
Utils.DOM.matchSize = function(destEl,sourceEl){ this.setBounds(destEl,sourceEl.offsetTop,sourceEl.offsetLeft,sourceEl.offsetWidth,sourceEl.offsetHeight); }

Utils.DOM.centerEl = function(el,parentEl)
{
	var pWidth = 0;
	var pHeight = 0;
	
	var elWidth = el.offsetWidth;
	var elHeight = el.offsetHeight;

	if (parentEl != null)
	{
		pWidth = parentEl.offsetWidth;
		pHeight = parentEl.offsetHeight;
	}
	else
	{
		var viewportBounds = Utils.DOM.getViewportBounds();
		pWidth = viewportBounds.w;
		pHeight = viewportBounds.h;
	}

	var scrollOffset = 0;
	
	var pos = Utils.CSS.getStyle(el,"position");
	
	if ((pos != "fixed") && (parentEl == null))
	{
		if (window.pageYOffset)
			scrollOffset = window.pageYOffset;
		else if (document.documentElement && document.documentElement.scrollTop)
			scrollOffset = document.documentElement.scrollTop;
		else if (document.body)
			scrollOffset = document.body.scrollTop;
	}
		
	this.setPos(el,((pHeight - elHeight) / 2) + scrollOffset,(pWidth - elWidth) / 2); 
}

Utils.DOM.getViewportBounds = function()
{
	var obj = {};
	
	if (window.innerWidth) { obj.w = window.innerWidth; obj.h = window.innerHeight; }
	else if (document.documentElement && document.documentElement.clientWidth) { obj.w = document.documentElement.clientWidth; obj.h = document.documentElement.clientHeight; }
	else { obj.w = document.body.clientWidth; obj.h = document.body.clientHeight; }
	
	return obj;
}

Utils.DOM.disableForm = function(obj,buttonsOnly)
{
	for (var i = 0; i < obj.elements.length; i++)
	{
		if (!buttonsOnly || ((obj.elements[i].nodeName == "INPUT" && obj.elements[i].type == "submit") || obj.elements[i].nodeName == "BUTTON"))
		{
			if (!browser.isIE || !Utils.CSS.hasClass(obj.elements[i],'text'))
				Utils.CSS.addClass(obj.elements[i],'disabled');

			obj.elements[i].disabled = true;
		}
	}
}

Utils.DOM.enableForm = function(obj)
{
	for (var i = 0; i < obj.elements.length; i++)
	{
		if (!browser.isIE || !Utils.CSS.hasClass(obj.elements[i],'text'))
			Utils.CSS.remClass(obj.elements[i],'disabled');
		
		obj.elements[i].disabled = false;
	}
}

Utils.DOM.getDocumentBounds = function()
{
	var obj = {}; var sh = document.body.scrollHeight; var oh = document.body.offsetWidth;
	
	if (sh > oh) { obj.w = document.body.scrollWidth; obj.h = document.body.scrollHeight; }
	else { obj.w = document.body.offsetWidth; obj.h = document.body.offsetHeight; }
	
	return obj;
}

Utils.EventManager = new function()
{
	var listeners = [];	

	function getListenerIndex(obj,eventName,cbSignature)
	{
		for (var i = 0; i < listeners.length; i++)
		{
			var item = listeners[i];
			if (item[0] == obj && item[1] == eventName && item[2] == cbSignature)
				return i;
		}
		
		return -1;
	}
	
	this.addListener = function(obj,eventName,cb,capture)
	{
		if (capture == undefined)
			capture = false;
			
		var func = function(e){ return cb.call(new Utils.Event(e)); };
	
		if (obj.addEventListener)
			obj.addEventListener(eventName,func,capture);
		else if (obj.attachEvent)
			obj.attachEvent("on"+eventName,func);

		var i = listeners.length;
		listeners[i] = [obj,eventName,cb.signature,func];
		return i;
	}

	this.removeListener = function(obj,eventName,cb)
	{
		var index = getListenerIndex(obj,eventName,cb.signature);
		if (index == -1)
			return false;
		
		return this.removeListenerByIndex(obj,index);
	}
	
	this.removeListenerByIndex = function(obj,index)
	{
		var item = listeners[index];
		
		listeners.splice(index,1);

		if (obj.removeEventListener)
			obj.removeEventListener(item[1],item[3],false);
		else if (obj.detachEvent)
			obj.detachEvent("on"+item[1],item[3]);
		else
			return false;
				
		return true;
	}
	
	this.getListenerCount = function()
	{
		return listeners.length;
	}
};

function EventListener(obj,event,cb,capture)
{
	this.obj = obj;
	this.event = event;
	this.callback = cb;
	
	this.capture = capture;
	return this;
}

Utils.Event = function(e)
{
	this._e = e;
}

	Utils.Event.prototype =
	{
		getTarget:function()
		{
			if (this._e.target)
				return this._e.target;
			else
				return this._e.srcElement;
		},
		
		getRelatedTarget:function()
		{
			var target = this._e.relatedTarget;
			if (!target)
			{
				if (this._e.type == "mouseout")
					target = this._e.toElement;
				else if (this._e.type == "mouseover")
					target = this._e.fromElement;
			}
			return target;
		},

		stopPropagation : function()
		{
			if (this._e.stopPropagation)
				this._e.stopPropagation();
			else
				this._e.cancelBubble = true;
		},

		preventDefault : function()
		{
			if (this._e.preventDefault)
				this._e.preventDefault();
			else
				this._e.returnValue = false;
		},
		
		getClientPos : function()
		{
			var obj = new Object();
	
			if (this._e.clientX || this._e.clientY)
			{
				obj.x = this._e.clientX;
				obj.y = this._e.clientY;
			}
			else if (this._e.pageX || this._e.pageY)
			{
				obj.x = this._e.pageX;
				obj.y = this._e.pageY;
			}

			return obj;
		}
	}
	
function g(name)
{
	return document.getElementById(name);
}

function Callback(obj,method)
{
	this.obj = obj;
	this.method = method;
	this.signature = String(obj)+String(method);
}

Callback.prototype.call = function(params)
{
	if (params instanceof Array)
		return this.method.apply(this.obj,params);
	else
		return this.method.call(this.obj,params);
}

Utils.DOM.addLoadEvent = function(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function')
	{
		window.onload = func;
	}
	else
	{
		window.onload = function()
		{
			if (oldonload)
        		oldonload();
			
			func();
        }
    }
}