var app =
{
	addEventListener: function( dispatcher, type, listener )
	{
		if( dispatcher.addEventListener )
		{
			dispatcher.addEventListener( type, listener, false );
		}
		else if( dispatcher.attachEvent )
		{
			dispatcher.attachEvent( "on" + type, listener );
		}
	},

	removeEventListener: function( dispatcher, type, listener )
	{
		if( dispatcher.removeEventListener )
		{
			dispatcher.removeEventListener( type, listener, false );
		}
		else if( dispatcher.detachEvent )
		{
			dispatcher.detachEvent( "on" + type, listener );
		}
	},

	normaliseEvent: function( domEvent )
	{
		var e = {};

		if( domEvent.target )
		{
			e.target = domEvent.target;

			if( e.target.nodeType == 3 )
			{
				e.target = e.target.parent;
			}

			e.button = 0;

			if( isNaN( domEvent.button ) == false )
			{
				if( domEvent.button == 0 )
				{
					e.button = 1;
				}
				else if( domEvent.button == 1 )
				{
					e.button = 2;
				}
				else if( domEvent.button == 2 )
				{
					e.button = 3;
				}
			}

			e.preventDefault = function()
			{
				domEvent.preventDefault();
			}

			e.stopPropagation = function()
			{
				domEvent.stopPropagation();
			}
		}
		else
		{
			e.target = domEvent.srcElement;
			e.button = 0;

			if( isNaN( domEvent.button ) == false )
			{
				if( domEvent.button == 1 )
				{
					e.button = 1;
				}
				else if( domEvent.button == 4 )
				{
					e.button = 2;
				}
				else if( domEvent.button == 2 )
				{
					e.button = 3;
				}
			}

			e.preventDefault = function()
			{
				domEvent.returnValue = false;
			}

			e.stopPropagation = function()
			{
				domEvent.cancelBubble = true;
			}
		}

		return e;
	},

	encodeVariables: function( obj )
	{
		var pairs = [];

		for( var name in obj )
		{
			pairs.push( name + "=" + escape( obj[ name ] ) );
		}

		return pairs.join( "&" );
	},

	decodeVariables: function( str )
	{
		var obj = {};
		var pairs = str.split( "&" );

		while( pairs.length )
		{
			var nv = pairs.pop().split( "=" );
			obj[ nv[ 0 ] ] = unescape( nv[ 1 ] );
		}

		return obj;
	},

	delegate: function( scope, func )
	{
		var args = [];

		if( arguments.length > 2 )
		{
			var i = 2;

			while( i < arguments.length )
			{
				args.push( arguments[ i ++ ] );
			}
		}

		return function()
		{
			if( arguments.length )
			{
				var i = arguments.length;

				while( i -- )
				{
					args.unshift( arguments[ i ] );
				}
			}

			return func.apply( scope, args );
		}
	},

	setCookie: function( name, value, expires )
	{
	},

	getCookie: function( name )
	{
	},

	deleteCookie: function( name )
	{
	},

	getElement: function( elementID )
	{
		return document.getElementById( elementID );
	},

	getElements: function()
	{
		if( arguments.length == 0 )
		{
			return document.getElementsByTagName( "*" );
		}

		var list = [];
		var i = 0;

		while( i < arguments.length )
		{
			var elements = document.getElementsByTagName( arguments[ i ++ ] );
			var j = 0;

			while( j < elements.length )
			{
				list.push( elements[ j ++ ] );
			}
		}

		return list;
	},

	getElementsIn: function( parentElement )
	{
		if( arguments.length == 0 )
		{
			return parentElement.getElementsByTagName( "*" );
		}

		var list = [];
		var i = 0;

		while( i < arguments.length )
		{
			var elements = parentElement.getElementsByTagName( arguments[ i ++ ] );
			var j = 0;

			while( j < elements.length )
			{
				list.push( elements[ j ++ ] );
			}
		}

		return list;
	},

	getHTML: function( elementID )
	{
		return this.getElement( elementID ).innerHTML;
	},

	setHTML: function( elementID, html )
	{
		this.getElement( elementID ).innerHTML = html;
	},

	getSize: function( element )
	{
		var o =
		{
			width: element.offsetWidth,
			height: element.offsetHeight
		}

		return o;
	},

	getPosition: function( element )
	{
		var o =
		{
			x: 0,
			y: 0
		}

		var p = element.offsetParent;

		while( p )
		{
			o.x += p.offsetLeft;
			o.y += p.offsetTop;

			p = p.offsetParent;
		}

		return o;
	},

	load: function( uri, data, resultHandler, errorHandler )
	{
		var req = null;

		if( window.ActiveXObject )
		{
			try
			{
				req = new ActiveXObject( "Microsoft.XMLHTTP" );
			}
			catch( err ){}
		}
		else if( window.XMLHttpRequest )
		{
			try
			{
				req = new XMLHttpRequest();
			}
			catch( err ){}
		}

		if( req )
		{
			req.open( "POST", uri, true );
			req.setRequestHeader( "User-Agent", "JavaScript/XMLHTTP" );
			req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
			req.onreadystatechange = function()
			{
				if( req.readyState == 4 )
				{
					if( req.status < 400 )
					{
						if( resultHandler )
						{
							resultHandler( req.responseText );
						}
					}
					else
					{
						if( errorHandler )
						{
							errorHandler( req.statusText );
						}
					}

					req.abort();
					req = null;
				}
			}
			req.send( data );

			return true;
		}

		return false;
	}
}