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.isKonqueror = (ua.indexOf("konqueror") != -1); 
	this.isIcab      = (ua.indexOf("icab") != -1); 
	this.isAol       = (ua.indexOf("aol") != -1); 
	this.isWebtv     = (ua.indexOf("webtv") != -1); 
	this.isOmniweb   = (ua.indexOf("omniweb") != -1);
	this.isDreamcast   = (ua.indexOf("dreamcast") != -1);
	
	this.isIECompatible = ( (ua.indexOf("msie") != -1) && !this.isIE);
	this.isNSCompatible = ( (ua.indexOf("mozilla") != -1) && !this.isNS && !this.isMozilla);
	
	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.DOM");

Utils.DOM.isChildElement = function(el,parentEl)
{
	while(el != null)
	{
		//alert(el.nodeName);
		if (el.parentNode == parentEl)
			return true;
		el = el.parentNode;
	}
	return false;
}

Utils.EventManager = new function()
{
	var listeners = [];	

	function getListenerIndex(obj,eventName,cbSignature)
	{
		for (var i = 0; i < listeners.length; i++)
		{
			var item = listeners[i];
			/*alert(item[0]+" vs "+obj+" - "+(item[0] == obj));
			alert(item[1]+" vs "+eventName+" - "+(item[1] == eventName));
			alert(item[2]+" vs "+cbSignature+" - "+(item[2] == cbSignature));*/
			
			if (item[0] == obj && item[1] == eventName && item[2] == cbSignature)
				return i;
		}
		
		return -1;
	}
	
	this.addListener = function(obj,eventName,cb,capture)
	{
		if (!capture)
			capture = false;
		
		var func;
		
		if (cb instanceof Callback)
			func = function(e){ return cb.call(new Utils.Event(e)) };
		else
			func = function(e){ cb(new Utils.Event(e)) };
			
		if (obj.addEventListener)
			obj.addEventListener(eventName,func,capture)
		else if (obj.attachEvent)
			obj.attachEvent("on"+eventName,func);
	
		//cb.call();
	
		var i = listeners.length;
		listeners[i] = [obj,eventName,cb.signature,func];
		//alert(listeners.length);
		return i;
	}

	this.removeListener = function(obj,eventName,cb)
	{
		var index = getListenerIndex(obj,eventName,cb.signature);
		if (index == -1)
			return false;
		
		var item = listeners[index];
		
		listeners.splice(index,1);

		if (obj.removeEventListener)
			obj.removeEventListener(eventName,item[3],false);
		else if (obj.detatchEvent)
			obj.detatchEvent("on"+eventName,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;
}

function getStyle(obj,prop)
{
	if (window.getComputedStyle)
		return window.getComputedStyle(obj,null).getPropertyValue(prop);
	else
	{
		val = eval("obj.currentStyle."+prop);
		if ((isNaN(parseInt(val))) && (prop == "height"))
			return obj.offsetHeight
		else
			return val;
	}
}

Utils.Event = function(e)
{
	this._e = e;
}
	
	Utils.Event.prototype =
	{
		getType:function()
		{
			return this._e.type;	
		},
		
		getOriginalTarget:function()
		{
			return this._e.explicitOriginalTarget;
		},
		
		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;
			}

			//alert(this.x+","+this.y);

			return obj;
		}
	}
//}

Utils.startMouseCapture = function()
{
	Utils.EventManager.addListener(document,"mousemove",new Callback(this,this.onMouseMoveCapture));
}

Utils.stopMouseCapture = function()
{
	Utils.EventManager.removeListener(document,"mousemove",new Callback(this,this.onMouseMoveCapture));
	Utils.mousePos = null;
}

Utils.onMouseMoveCapture = function(e)
{
	//alert("mousemove");
	Utils.mousePos = e.getClientPos();
}

function hasClassName(obj,classname)
{
	pos = obj.className.indexOf(classname);

	if (pos != -1)
		return true;
	else
		return false;
}

function g(name)
{
	return document.getElementById(name);
}

function s(el,content)
{
	if (el != null && el.innerHTML != undefined)
		el.innerHTML = content;
}

function createEl(type,id,content)
{
	var el = document.createElement(type);

	if (id != null)
		el.setAttribute("id",id);

	if (content != null)
		s(el,content)
	
	return el;
}

function Callback(obj,method)
{
	this.obj = obj;
	this.method = method;
	this.signature = String(obj)+String(method);
	
	//alert('creating callback');
}

Callback.prototype.call = function(params)
{
	//alert("running callback");
	return this.method.call(this.obj,params);
}

Utils.LoadManager = new function()
{
	var loadCallbacks = [];
	var prevOnloadFunc = window.onload;
	var self = this;
	
	window.onload = function(){
		Utils.LoadManager.runCallbacks();
	}
	
	this.addLoadCallback = function(cb)
	{
		loadCallbacks[loadCallbacks.length] = cb;
	}
	
	this.runCallbacks = function()
	{
		for (var i = 0; i < loadCallbacks.length; i++)
			loadCallbacks[i].call();

		if (prevOnloadFunc) 
			prevOnloadFunc();
	}
}

function addLoadEvent(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function')
	{
		window.onload = func;
	}
	else
	{
		window.onload = function()
		{
			if (oldonload)
			{
        		oldonload();
        	}
        	func();
        }
    }
}