var Toolbox = 
{
	ArrayContainsValue: function( aArray, sValue )
	{
		for( var key in aArray )
		{
			if ( aArray[ key ] == sValue )
				return true;
		}
		
		return false;
	},

	AttachEvent: function( eElement, sEventName, fHandler )
	{
		// Clean event name
		if ( sEventName.indexOf( 'on' ) != 0 )
			sEventName = 'on' + sEventName;
		sEventName.toLowerCase();

		// Initialize events list
		if ( eElement.eventsList == null ) 
			eElement.eventsList = new Array();
		if ( eElement.eventsList[ sEventName ] == null )
			eElement.eventsList[ sEventName ] = new Array();

		// Add the default event to event list
		var defaultEvent = eElement[ 'on' + sEventName ];
		if ( defaultEvent != null )
		{
			eElement[ 'on' + sEventName ] = null;
			eElement.AttachEvent( eElement, sEventName, defaultEvent )
		}

		// Check if handler was set before
		for ( var i=0; i<eElement.eventsList[ sEventName ].length; i++ )
		{
			if ( eElement.eventsList[ sEventName ][ i ] == fHandler )
				return;
		}

		// Push event
		eElement.eventsList[ sEventName ].push( fHandler );

		// Set handler
		if ( eElement.addEventListener )
			eElement.addEventListener( sEventName.substring( 2 ), top.Toolbox.HandleEvent, false );
		else if ( eElement.attachEvent )
			eElement.attachEvent( sEventName, top.Toolbox.HandleEvent );
	},

	CenterAbsoluteElement: function( eElement )
	{
		if ( eElement == null )
			return;

		eElement.style.top = ( Toolbox.GetViewportHeight() / 2 ) - ( eElement.clientHeight / 2 ) + 'px';
		eElement.style.left = ( Toolbox.GetViewportWidth() / 2 ) - ( eElement.clientWidth / 2 ) + 'px';
	},

	ClipText: function( pText, pLength )
	{
		return ( pText.length > pLength ) ? pText = pText.substring( 0, pLength - 3 ) + "..." : pText;
	},

	DetachEvent: function( eElement, sEventName )
	{
		if ( eElement.eventsList != null && eElement.eventsList[ sEventName ] != null )
			eElement.eventsList[ sEventName ].pop();
	},
	
	GetChildNodesRecursive: function( eTopElement )
	{
		var aElements = new Array();
		for ( var i=0; i<eTopElement.childNodes.length; i++ )
		{
			aElements.push( eTopElement.childNodes[ i ] );
			var aChildElements = Toolbox.GetChildNodesRecursive( eTopElement.childNodes[ i ] );
			for ( var j=0; j<aChildElements.length; j++ )
				aElements.push( aChildElements[ j ] );
		}
		return aElements;
	},
	
	GetElementOffsetBottom: function( eTargetElement )
	{
		var offsetTop = Toolbox.GetElementOffsetTop( eTargetElement );
		return offsetTop + eTargetElement.offsetHeight;
	},
	
	GetElementOffsetLeft: function( eTargetElement )
	{
		var xPos = eTargetElement.offsetLeft - Toolbox.GetElementScrollLeft( eTargetElement );
		var tempEl = eTargetElement.offsetParent;
		while ( tempEl != null )
		{
			xPos += tempEl.offsetLeft - Toolbox.GetElementScrollLeft( tempEl );

			var tempParentEl = tempEl.parentNode;
			tempEl = ( tempEl.offsetParent != null && tempEl.offsetParent.tagName != null ) ? tempEl.offsetParent : Toolbox.GetParentFrame( tempEl );
			while ( tempParentEl != null && tempParentEl != tempEl )
			{
				xPos -= Toolbox.GetElementScrollLeft( tempParentEl );
				tempParentEl = tempParentEl.parentNode;
			}
		}
		
		return xPos;
	},
	
	GetElementOffsetRight: function( eTargetElement )
	{
		var offsetLeft = Toolbox.GetElementOffsetLeft( eTargetElement );
		return offsetLeft + eTargetElement.offsetWidth;
	},

	GetElementOffsetTop: function( eTargetElement )
	{
		var yPos = eTargetElement.offsetTop - Toolbox.GetElementScrollTop( eTargetElement );
		var tempEl = eTargetElement.offsetParent;
		while ( tempEl != null )
		{
			yPos += tempEl.offsetTop - Toolbox.GetElementScrollTop( tempEl );

			var tempParentEl = tempEl.parentNode;
			tempEl = ( tempEl.offsetParent != null && tempEl.offsetParent.tagName != null ) ? tempEl.offsetParent : Toolbox.GetParentFrame( tempEl );
			while ( tempParentEl != null && tempParentEl != tempEl )
			{
				yPos -= Toolbox.GetElementScrollTop( tempParentEl );
				tempParentEl = tempParentEl.parentNode;
			}
		}
		return yPos;
	},
	
	GetElementScrollLeft: function( eElement )
	{
		if ( eElement.pageXOffset )
			return eElement.pageXOffset;
		if ( eElement.scrollLeft )
			return eElement.scrollLeft;

		return 0;
	},
	
	GetElementScrollTop: function( eElement )
	{
		if ( eElement.pageYOffset )
			return eElement.pageYOffset;
		if ( eElement.scrollTop )
			return eElement.scrollTop;
		
		return 0;
	},
	
	GetParentFrame: function( eElement )
	{
		var oWindow = ( eElement.ownerDocument.defaultView != null ) ? eElement.ownerDocument.defaultView : eElement.ownerDocument.parentWindow;
		return oWindow.frameElement;
	},

        GetRangeIntersectsElement: function( rRange, eElement )
        {
            if ( rRange.intersectsNode != null )
                return rRange.intersectsNode( eElement );

            var rNodeRange = eElement.ownerDocument.createRange();
            try { rNodeRange.selectNode( eElement ); } catch ( e ) { rNodeRange.selectNodeContents( eElement ); }
            return rRange.compareBoundaryPoints( Range.END_TO_START, rNodeRange ) == -1
                    && rRange.compareBoundaryPoints( Range.START_TO_END, rNodeRange ) == 1;
        },

        GetSelectedElements: function( rRange )
        {
            if ( !rRange )
                return [];

            var eContainerElement = rRange.commonAncestorContainer;
            if ( eContainerElement.nodeType != 1 )
                eContainerElement = eContainerElement.parentNode;

            var tTreeWalker = document.createTreeWalker
            (
                eContainerElement,
                NodeFilter.SHOW_ELEMENT,
                function( eNode ) { return Toolbox.GetRangeIntersectsElement( rRange, eNode ) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; },
                false
            );

            var aList = [tTreeWalker.currentNode];
            while (tTreeWalker.nextNode())
                aList.push( tTreeWalker.currentNode );

            return aList;
        },
	
	GetViewportHeight: function( oWindow )
	{
		if ( oWindow == null )
			oWindow = window;

		if ( oWindow.innerHeight != oWindow.undefined )
			return oWindow.innerHeight;
		if ( oWindow.document.compatMode == 'CSS1Compat' )
			return oWindow.document.documentElement.clientHeight;
		if ( oWindow.document.body )
			return oWindow.document.body.clientHeight;

		return oWindow.undefined;
	},
	
	GetViewportWidth: function( oWindow )
	{
		if ( oWindow == null )
			oWindow = window;

		if ( oWindow.innerWidth != oWindow.undefined )
			return oWindow.innerWidth;
		if ( oWindow.document.compatMode == 'CSS1Compat' )
			return oWindow.document.documentElement.clientWidth;
		if ( oWindow.document.body )
			return oWindow.document.body.clientWidth;

		return oWindow.undefined;
	},
	
	HandleEvent: function( e )
	{
		var e = ( window.event != null ) ? window.event : e;
		var eTarget = ( e.srcElement != null ) ? e.srcElement : e.currentTarget;
		var returnValue = Toolbox.LaunchNamedEvent( eTarget, e.type, e )
		if ( returnValue == false )
			return false;
	},

	HtmlEncode: function ( sString )
	{
		alert( 'TODO' );
	},

	HtmlDecode: function ( sString )
	{
		var entities = [
			[ '&amp;', '&' ],
			[ '&nbsp;', ' ' ],
			[ '&lt;', '<' ],
			[ '&gt;', '>' ],
			[ '&quot;', '"' ]
		];

		var limit = entities.length;
		for ( var i = 0; i < limit; ++i )
			sString = sString.replace( new RegExp( entities[ i ][ 0 ], "ig" ), entities[ i ][ 1 ] );

		return sString;
	},
	
	IsBlank: function( sValue )
	{
		if ( sValue != null )
			sValue = sValue.replace( / /g, '' );
		return ( sValue == null || sValue == '' )
	},
	
	IsEmpty: function( sValue )
	{
		return ( sValue == null || sValue == '' )
	},
	
	LaunchEvent: function( eElement, e )
	{
		var e = ( window.event != null ) ? window.event : e;
		var returnValue = Toolbox.LaunchNamedEvent( eElement, e.type, e )
		if ( returnValue == false )
			return false;
	},
	
	LaunchNamedEvent: function( eElement, sEventName, e )
	{
		// Clean event name
		if ( sEventName.indexOf( 'on' ) != 0 )
			sEventName = 'on' + sEventName;

		if ( eElement.eventsList == null || eElement.eventsList[ sEventName ] == null )
			return;

		for ( var i=0; i<eElement.eventsList[ sEventName ].length; i++ )
		{
			eElement.LaunchEvent = eElement.eventsList[ sEventName ][ i ];
			var returnValue = eElement.LaunchEvent( e );
			if ( returnValue == false )
			{
				eElement.LaunchEvent = null;
				return returnValue;
			}
		}
		eElement.LaunchEvent = null;
	}
}
