/****************************************************************************
 * Behaviour
 */
var Behaviour = {

    /**
     * Enter description here...
     *
     * @var Array
     */
	aRuleSet : new Array(),



    /**
     * Enter description here...
     *
     * @return void
     */
	register : function (_oRuleSet)
	{
		Behaviour.aRuleSet.push(_oRuleSet);
	},



    /**
     * Enter description here...
     *
     * @return void
     */
	apply : function ()
	{
	    var iLength = Behaviour.aRuleSet.length;
	    var iIndex  = 0;

		while (iLength--)
		{
		    var oRuleSet = Behaviour.aRuleSet[iIndex++];

			for (sSelector in oRuleSet)
			{
				var aElement = dom.get_element(sSelector);
				var iiLength = aElement.length;
				var iiIndex  = 0;

				if (iiLength == 0)
					continue;

				while (iiLength--)
					oRuleSet[sSelector](aElement[iiIndex++]);
			}
		}
	}
}





/****************************************************************************
 * Collection of miscellaneous useful functions
 */
var misc = {

    /**
     * Add to favorites
     *
     * @param string _sUrl
     * @param string _sTitle
     */
    add_favorite : function (_sUrl, _sTitle)
    {
        if (document.all)
            window.external.AddFavorite(_sUrl, _sTitle);

        else if (window.sidebar)
            window.sidebar.addPanel(_sTitle, _sUrl,"");

        else if (window.opera && window.print)
        {
            var eBm = document.createElement('a');
            eBm.setAttribute('rel'  , 'sidebar');
            eBm.setAttribute('href' , _sUrl);
            eBm.setAttribute('title', _sTitle);
            eBm.click();
        }
	},



    /**
     * Enter description here...
     *
     * @param  element _eElement
     * @return void
     */
    alpha_image : function (_eElement)
    {
        var sSource    = _eElement.src;
        var sNewSource = sSource.replace(
            /\/resources\/gfx\/.*$/,
            '/resources/gfx/alpha.gif'
        );

        _eElement.src = sNewSource;

        Element.setStyle(
            _eElement,
            {
                filter     : 'progid:DXImageTransform.Microsoft.AlphaImageLoader'
                           + '(src="' +sSource+ '", sizingMethod="scale")',
                visibility : 'visible'
            }
        );
    },



    /**
     * Enter description here...
     *
     * @param  element _eElement
     * @return void
     */
    alpha_background : function (_eElement)
    {
        if (!Element.getStyle(_eElement, 'backgroundImage').match(/url\("(.+)"\)/))
            return

        var sSource    = RegExp.$1.substr(RegExp.$1.indexOf('/resources/'))
        var oDimension = Element.getDimensions(_eElement)

        Element.setStyle(
            _eElement,
            {
                height     : oDimension.height,
                filter     : 'progid:DXImageTransform.Microsoft.AlphaImageLoader'
                           + '(src="' +(sSource)+ '", sizingMethod="scale")',
                background : 'none',
                visibility : 'visible'
            }
        );
    }
}





/****************************************************************************
 * Collection of useful dom functions
 */
var dom = {


    /**
     * Get element(s) by selector
     *
     * @param  string _sSelector
     * @param  window _oWindow
     * @return Array
     */
    get_element : function (_sSelector)
    {
        var aReturn = new Array(document);

        var aToken  = _sSelector.split(' ');
        var iLength = aToken.length;
        var iIndex  = 0;

        while (iLength--)
        {
            var sToken = aToken[iIndex++].replace(/^\s*/, "").replace(/\s*$/, "");

            // ~~~~~~~~~~~~~~~~~
            // Token contains id
            // ~~~~~~~~~~~~~~~~~
            if (sToken.indexOf('#') > -1)
            {
                var aPart    = sToken.split('#');
                var eElement = document.getElementById(aPart[1]);

                if (null == eElement || (aPart[0] && eElement.nodeName.toLowerCase() != aPart[0]))
                    return new Array();

                aReturn = new Array(eElement);

                continue;
            }

            // ~~~~~~~~~~~~~~~~~~~~
            // Token contains class
            // ~~~~~~~~~~~~~~~~~~~~
            if (sToken.indexOf('.') > -1)
            {
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // Token contains a class _sSelector
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                var aPart      = sToken.split('.');
                var sTagName   = aPart[0] ? aPart[0] : '*';
                var sClassName = aPart[1];

                var aTmpReturn = new Array();
                var iiLength   = aReturn.length;
                var iiIndex    = 0;

                while (iiLength--)
                {
                    var aElement  = aReturn[iiIndex++].getElementsByTagName(sTagName);
                    var iiiLength = aElement.length;
                    var iiiIndex  = 0;

                    while (iiiLength--)
                    {
                        if (aElement[iiiIndex].className.match(new RegExp('\\b'+sClassName+'\\b')))
                            aTmpReturn.push(aElement[iiiIndex]);

                        iiiIndex++;
                    }
                }

                aReturn = aTmpReturn;

                continue;
            }

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // Token is an element, check attribute
            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            if (sToken.match(/^(\w+|\*)\[(\w+)([=~]?)"?([^\]"]*)"?\]$/))
            {
                var oFunction  = null;
                var sTagName   = RegExp.$1;
                var sAttribute = RegExp.$2;
                var sOperator  = RegExp.$3;
                var sValue     = RegExp.$4;

                if (!sTagName)
                    sTagName = '*';

                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // Grab all of the tagName elements within current context
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                var aTmpReturn = new Array();
                var iiLength   = aReturn.length;
                var iiIndex    = 0;

                while (iiLength--)
                {
                    var aElement  = aReturn[iiIndex++].getElementsByTagName(sTagName);
                    var iiiLength = aElement.length;
                    var iiiIndex  = 0;

                    while (iiiLength--)
                        aTmpReturn.push(aElement[iiiIndex++]);
                }

                switch (sOperator)
                {
                    case '=' : // Equality
                        oFunction = function (_eElement)
                        {
                            var sAttributeValue = (sAttribute == 'class')
                                                ? _eElement.className
                                                : _eElement.getAttribute(sAttribute);

                            if (null == sAttributeValue)
                                return false;

                            return (sAttributeValue == sValue);
                        }
                    break

                    case '~' : // Match the pattern
                        oFunction = function (_eElement)
                        {
                            var sAttributeValue = (sAttribute == 'class')
                                                ? _eElement.className
                                                : _eElement.getAttribute(sAttribute);

                            if (null == sAttributeValue)
                                return false;

                            return (sAttributeValue.match(new RegExp(sValue)));
                        }
                    break

                    default : // Just test for existence of attribute
                        oFunction = function (_eElement)
                        {
                            var sAttributeValue = (sAttribute == 'class')
                                                ? _eElement.className
                                                : _eElement.getAttribute(sAttribute);

                            if (null == sAttributeValue)
                                return false;

                            return true;
                        }
                    break;
                }

                iiLength = aTmpReturn.length;
                iiIndex  = 0;

                aReturn = new Array();

                while (iiLength--)
                {
                    if (oFunction(aTmpReturn[iiIndex]))
                      aReturn.push(aTmpReturn[iiIndex]);

                    iiIndex++;
                }

                continue;
            }

            // ~~~~~~~~~~~~~~~~~~~~~~~~~
            // Token is a simple element
            // ~~~~~~~~~~~~~~~~~~~~~~~~~
            var aTmpReturn = new Array();
            var iiLength   = aReturn.length;
            var iiIndex    = 0;

            while (iiLength--)
            {
                var aElement  = aReturn[iiIndex++].getElementsByTagName(sToken);
                var iiiLength = aElement.length;
                var iiiIndex  = 0;

                while (iiiLength--)
                    aTmpReturn.push(aElement[iiiIndex++]);
            }

            aReturn = aTmpReturn;
        }


        return aReturn;
    }
}





/****************************************************************************
 * Collection of useful functions to handle global vars (eg. cookies)
 */
var vars = {


    /**
     * Set a cookie.
     *
     * @param  string  cookie name
     * @param  string  cookie value
     * @param  date    cookie expiring date
     * @param  string  path
     * @param  string  domain
     * @param  boolean secure
     * @return void
     */
    set_cookie : function  (_sName, _sValue, _iE, _sP, _iH, _iS)
    {
        _sP = _sP ? _sP : '/'

        document.cookie = escape(_sName) + '=' + escape(_sValue)
                        + (_iE ? '; expires=' + _iE.toGMTString() : '')
                        + (_sP ? '; path='    + _sP               : '')
                        + (_iH ? '; host='    + _iH               : '')
                        + (_iS ? '; secure'                       : '');
    },



    /**
     * Return value of given cookie name.
     *
     * @param  string _sName       Cookie name
     * @return string sCookieValue Cookie value
     */
    get_cookie : function (_sName)
    {
        var sCookieValue = '';
        var iPosName     = document.cookie.indexOf(escape(_sName) + '=');

        if (iPosName != -1)
        {
            var iPosVal = iPosName + (escape(_sName) + '=').length;
            var iEndPos = document.cookie.indexOf(';', iPosVal);

            sCookieValue = (iEndPos != -1)
                         ? unescape(document.cookie.substring(iPosVal, iEndPos))
                         : unescape(document.cookie.substring(iPosVal));
        }

        return sCookieValue;
    },



    /**
     * Clears given cookie.
     *
     * @param  string _sCookie Cookie name
     * @return void
     */
    clear_cookie : function (_sCookie)
    {
        var oNow       = new Date();
        var iYesterday = new Date(oNow.getTime() - 1000 * 60 * 60 * 24);

        this.set_cookie(_sCookie, '', iYesterday);
    }
}





/****************************************************************************
 * Collection of useful functions concerning environment
 */
var env = {


    /**
     * Returns array with page width, height and window width, height
     * Core code from - quirksmode.org
     * Edit for Firefox by pHaez
     *
     * @return Array
     */
    getPageSize : function ()
    {
    	var xScroll, yScroll;

    	if (window.innerHeight && window.scrollMaxY) {
    		xScroll = document.body.scrollWidth;
    		yScroll = window.innerHeight + window.scrollMaxY;
    	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
    		xScroll = document.body.scrollWidth;
    		yScroll = document.body.scrollHeight;
    	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
    		xScroll = document.body.offsetWidth;
    		yScroll = document.body.offsetHeight;
    	}

    	var windowWidth, windowHeight;
    	if (self.innerHeight) {	// all except Explorer
    		windowWidth = self.innerWidth;
    		windowHeight = self.innerHeight;
    	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
    		windowWidth = document.documentElement.clientWidth;
    		windowHeight = document.documentElement.clientHeight;
    	} else if (document.body) { // other Explorers
    		windowWidth = document.body.clientWidth;
    		windowHeight = document.body.clientHeight;
    	}

    	// for small pages with total height less then height of the viewport
    	if(yScroll < windowHeight){
    		pageHeight = windowHeight;
    	} else {
    		pageHeight = yScroll;
    	}

    	// for small pages with total width less then width of the viewport
    	if(xScroll < windowWidth){
    		pageWidth = windowWidth;
    	} else {
    		pageWidth = xScroll;
    	}


    	aSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
    	return aSize;
    },


    /**
     * Returns true if user agent is MSIE.
     *
     * @return boolean
     */
    is_ie : function ()
    {
        return (
            !window.opera
         && this.agent('lower').indexOf('msie') != -1
        );
    },



    /**
     * Returns true if user platform is mac.
     *
     * will not work with opera & internet explorer
     * @return boolean
     */
    is_mac : function ()
    {
        return (
            !window.opera
         && this.agent('lower').indexOf("mac") != -1
        );
    },



    /**
     * Return true if user agent is apple safari.
     *
     * @return boolean
     */
    is_safari : function ()
    {
        return (
            !window.opera
         && (this.product_sub() >= 20020000)
         && (this.vendor().indexOf("Apple Computer") != -1)
        );
    },



    /**
     * Returns user agent as string.
     *
     * @param  string _sCase Optional.
     * @return string
     */
    agent : function (_sCase)
    {
        var sUA = navigator.userAgent;

        if (!_sCase)
            return sUA;

        if (_sCase == 'lower')
            return sUA.toLowerCase();

        if (_sCase == 'upper')
            return sUA.toUpperCase();

        return sUA;
    },



    /**
     * Returns browser's vendor.
     *
     * @return string
     */
    vendor : function ()
    {
        return navigator.vendor;
    },



    /**
     * Returns naviagator productSub.
     *
     * @return string
     */
    product_sub : function ()
    {
        return parseInt(navigator.productSub);
    },



    /**
     * Returns query string.
     *
     * @return string
     */
    query_string : function ()
    {
        var sUrl = window.location.href;

        if (!sUrl.match(/\?/))
            return '';

        return sUrl.substring(sUrl.indexOf('?')+1);
    },



    /**
     * Redirect to given URL.
     *
     * @param  string _sUrl Optional. URL
     * @return void
     */
    redirect : function (_sUrl)
    {
        if (!_sUrl)
        {
            window.location.reload();
            return;
        }

        window.location.href = _sUrl;
    }
}