// +------------------------------------------------------------------------+
// | 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 miscellaneous 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 true if user agent is MSIE.
     *
     * @return boolean
     */
    is_ie : function ()
    {
        return (GLOBALS.ie6 || GLOBALS.ie7)
    },

    /**
     * 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;
    },

    /**
     * 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;
    }
}