// +------------------------------------------------------------------------+
// | GLOBALS                                                                |
// +------------------------------------------------------------------------+
try {
    GLOBALS.ie6 == GLOBALS.ie7;
}
catch (eExc)
{
    var GLOBALS = {
        ie6: false,
        ie7: false,
		ie8: false
    };
}



// +------------------------------------------------------------------------+
// | Page                                                                   |
// +------------------------------------------------------------------------+
var Page = {

    /**
     * @var integer
     */
    iScope : 0,

    /**
     * @var element
     */
    eSection : null,

    /**
     * Initialize website.
     *
     * @return void
     */
    init : function ()
    {
        Object.extend(
            GLOBALS,
            {
                path: '/',
                page: env.getPageSize(),
                ajaxSuffix: '_1'
            }
        );

        // ~~~~~~~~~~~~~~~~
        // Google analytics
        // ~~~~~~~~~~~~~~~~
        //_uacct = "UA-XXXXXX-X";
        //urchinTracker();

        // ~~~~~~~~~~~~~~~~~~~~~~~
        // Initialize product list
        // ~~~~~~~~~~~~~~~~~~~~~~~
        try
        {
            ProductList.init();
        }
        catch (eExc) {
            alert(eExc.message);
        }

        Behaviour.apply();

        window.scrollTo(0,0);
        Page.scrolling();

        if (document.location.hash.match(/^#([a-z0-9_-]+)/i))
        {
            Page.scrollToAnchor(RegExp.$1);
        }
    },

    /**
     * Transform given URL to AJAX request target.
     *
     * @param  string         _sUrl
     * @return string|boolean
     */
    getRequestTarget : function (_sUrl)
    {
        if (!_sUrl.match(new RegExp('^(.*)' +GLOBALS.path+ '([a-z]{2})/(.*)\.html$')))
            return false;

        var sTarget = RegExp.$1
                    + GLOBALS.path
                    + RegExp.$2 + GLOBALS.ajaxSuffix
                    + '/'
                    + RegExp.$3
                    + '.php';

        return sTarget;
    },

    /**
     * Open external links in a new window.
     *
     * @param  object _oEvent Fired event
     * @return void
     */
    externalLinks : function (_oEvent)
    {
        if (GLOBALS.ie6 || GLOBALS.ie7 || GLOBALS.ie8)
            window.open(Event.element(_oEvent));
        else
            window.open(this.href);

        if (_oEvent)
            Event.stop(_oEvent);
    },

    /**
     * Window resize event handler.
     *
     * @return void
     */
    resize : function ()
    {
        GLOBALS.page = env.getPageSize();

        Page.scrolling();
    },

    /**
     * Check page scrolling. Fix header and footer if neccessary.
     *
     * @return void
     */
    scrolling : function ()
    {
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Best pal IE6 needs special treatment
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        if (GLOBALS.ie6)
        {
            Page.scrollingIE6();
            return;
        }

        var eBody      = document.getElementsByTagName('body')[0];
        var eFooter    = $('footer');
        var iScope     = Element.getHeight($('container'));

        if (iScope <= GLOBALS.page[3] || GLOBALS.page[2] < 1004)
        {
            Element.removeClassName(eBody, 'fixItems');
            Element.setStyle(eFooter, {top: 'auto'});
        }
        else
        {
            var iTop = GLOBALS.page[3] - Element.getHeight(eFooter);

            Element.addClassName(eBody, 'fixItems');
            Element.setStyle(eFooter, {top: iTop+'px'});

        }
    },

    /**
     * Check page scrolling for IE6. Fix header and footer if neccessary.
     *
     * @return void
     */
    scrollingIE6 : function ()
    {
        var eHtml      = document.getElementsByTagName('html')[0];
        var eBody      = document.getElementsByTagName('body')[0];

        var eContainer = $('container');
        var eFooter    = $('footer');

        var bFixed = Element.hasClassName(eHtml, 'fixItems');
        var iScope = 0;

        if (!bFixed)
        {
            iScope = Element.getHeight(eContainer)
                   + Element.getHeight(eFooter);
        }
        else
        {
            iScope = Element.getHeight($('top'))
                   + Element.getHeight($('center'))
                   + Element.getHeight(eFooter);
        }

        var iLeft = Position.cumulativeOffset(eFooter)[0];

        if (iScope > GLOBALS.page[3])
        {
            if (GLOBALS.page[2] < 1004)
                return;

            Element.setStyle($('center'), {left: iLeft+'px', marginLeft:0});

            if (bFixed)
                return;

            Element.addClassName(eHtml, 'fixItems');
            Element.addClassName(eBody, 'fixItems');

            eBody.insertBefore($('top'), eContainer);
            eBody.insertBefore(eFooter, eContainer);
        }

        else if (bFixed)
        {
            Element.removeClassName(eHtml, 'fixItems');
            Element.removeClassName(eBody, 'fixItems');

            eContainer.insertBefore($('top'), $('center'));
            eContainer.appendChild(eFooter);
        }
    },
    
    /**
     * Scroll to element
     *
     * @param string
     * @return void
     */
    scrollToAnchor : function (_sIdentifier)
    {
        var eTarget = $(_sIdentifier);
        var aOffset = Position.cumulativeOffset(eTarget);
        
        document.location.hash = _sIdentifier;

        var iNewOffset = aOffset[1] - 132;
        
        if (Element.hasClassName(document.getElementsByTagName('body')[0], 'fixItems'))
        {        
          if (GLOBALS.ie6)
            $('container').scrollTop = iNewOffset;
          else  
            window.scrollTo(0, iNewOffset);
        }
    },

    /**
     * Update content of given element represented by given identifier.
     *
     * @param  string _sIdentifiery
     * @param  string _sUrl         Optional.
     * @param  object _oCallback    Optional.
     * @return void
     */
    updateSection : function (_sIdentifier, _sUrl, _oCallback)
    {
        Page.eSection = $(_sIdentifier);
        Page._hideSectionContent();

        if (!_sUrl)
            return;

		new Ajax.Updater(
		    _sIdentifier,
		    _sUrl,
		    {
		        onComplete : function ()
		        {
		            Page._showSectionContent();

                    if (null != _oCallback)
                        _oCallback();
		        }
		    }
		);
    },

    /**
     * Show section content
     *
     * @return void
     * @access private
     */
    _showSectionContent : function ()
    {
        Element.removeClassName(Page.eSection, 'indicator');

        Page.scrolling();

        if (GLOBALS.ie6 && 'productDetail' == Page.eSection.id)
        {
            var aChild   = Page.eSection.childNodes;
            var iLength  = aChild.length;
            var iIndex   = 0;

            while (iLength--)
            {
                var eChild = aChild[iIndex++];

                if (1 == eChild.nodeType)
                    break;
            }

            Element.setStyle(eChild, {paddingLeft:'20px', marginRight:0, width:'624px'});
        }
    },


    /**
     * Hide section content.
     *
     * @return void
     * @access private
     */
    _hideSectionContent : function ()
    {
        var aChild   = Page.eSection.childNodes;
        var iLength  = aChild.length;
        var iIndex   = 0;

        while (iLength--)
        {
            var eChild = aChild[iIndex++];

            if (1 == eChild.nodeType)
                break;
        }

        Element.setStyle(eChild, {display:'none'});
        Element.addClassName(Page.eSection, 'indicator');

        Page.resize();
    }
}



// +------------------------------------------------------------------------+
// | DropDown                                                               |
// +------------------------------------------------------------------------+
var DropDown = {

    /**
     * DropDown box stack.
     *
     * @var array
     */
    aBox : new Array(),

    /**
     * Document event observer registered or not.
     *
     * @var boolean
     */
    bDocumentEvent : false,

    /**
     * Push box to DropDown stock.
     *
     * @param  element _eLabel
     * @param  element _eItem
     * @return void
     */
    pushBox : function (_eLabel, _eItem)
    {
        Event.observe(
            _eLabel,
            'click',
            DropDown.check
        );

        DropDown.aBox.push(
            {
                label  : _eLabel,
                item   : _eItem,
                active : false
            }
        );
    },

    /**
     * Returns the stock-index of given box.
     *
     * @param  element         _eLabel
     * @return integer|boolean
     */
    getIndex : function (_eLabel)
    {
        var iLength = DropDown.aBox.length;
        var iIndex  = 0;

        while (iLength--)
        {
            if (DropDown.aBox[iIndex++].label == _eLabel)
                return iIndex;
        }

        return false;
    },

    /**
     * Open external links in a new window.
     *
     * @param  object _oEvent Fired event
     * @return void
     */
    check : function (_oEvent)
    {
        var eTarget = Event.element(_oEvent);
        var iIndex  = DropDown.getIndex(eTarget);

        if (iIndex && false == DropDown.aBox[iIndex-1].active)
        {
            DropDown.close(null);
            Event.stop(_oEvent);

            DropDown.show(iIndex-1);
        }
    },

    /**
     * Show DropDown items
     *
     * @param  integer _iIndex
     * @return void
     */
    show : function (_iIndex)
    {
        // ~~~~~~~~~~~~~~~~~
        // Show DropDown box
        // ~~~~~~~~~~~~~~~~~
        DropDown.aBox[_iIndex].active = true;

        Element.setStyle(DropDown.aBox[_iIndex].item,{display:'block'});

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // If not already registered, register document event observer
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        if (!DropDown.bDocumentEvent)
        {
            DropDown.bDocumentEvent = true;

            Event.observe(document, 'click', DropDown.close);
        }
    },

    /**
     * Hide all DropDown items
     *
     * @param  object _oEvent
     * @return void
     */
    close : function (_oEvent)
    {
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Unregister document event observer
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        DropDown.bDocumentEvent = false;

        Event.stopObserving(document, 'click', DropDown.close);

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Run all boxes to close them
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var iLength = DropDown.aBox.length;
        var iIndex  = 0;

        while (iLength--)
        {
            if (false == DropDown.aBox[iIndex++].active)
                continue;

            DropDown.aBox[iIndex-1].active = false;

            Element.setStyle(
                DropDown.aBox[iIndex-1].item,
                {display : 'none'}
            );
        }
    }
}



// +------------------------------------------------------------------------+
// | ProductList                                                            |
// +------------------------------------------------------------------------+
var ProductList = {

    /**
     * Product list element
     *
     * @var element
     */
    eSelf : null,

    /**
     * Product list filter element
     *
     * @var element
     */
    eFilter : null,

    /**
     * Initialize product list.
     *
     * @param  object _oEvent
     * @return void
     */
    init : function (_oEvent)
    {
        this.eSelf   = $('productListItems');
        this.eFilter = $('productListFilter');

        var aButton = dom.get_element('#productListFilter fieldset.button input');
        var iLength = aButton.length;
        var iIndex  = 0;

        while (iLength--)
            Element.setStyle(aButton[iIndex++], {display:'none'});
    },

    /**
     * Handle product list filter event.
     *
     * @param  object _oEvent
     * @return void
     */
    filterEvent : function (_oEvent)
    {
        var oGroup    = {};
        var aInput    = ProductList.eFilter.getElementsByTagName('input');
        var iLength   = aInput.length;
        var iIndex    = 0;

        while (iLength--)
        {
            var eInput = aInput[iIndex++];

            if (!Element.hasClassName(eInput, 'checkbox') || !eInput.checked)
                continue;

            var sGroup = eInput.name.replace(/\[\]/, "");

            try
            {
                oGroup[sGroup].opt.length;
            }
            catch (eExc)
            {
                eInput.className.match(/rel:(and|or)/)

                oGroup[sGroup] = {
                    rel : RegExp.$1,
                    opt : new Array()
                };
            }

            oGroup[sGroup].opt.push(eInput.value);
        }


        var aFilter = new Array();

        for (sGroup in oGroup)
        {
            if ('or' == oGroup[sGroup].rel)
            {
                aFilter.push(
                    sGroup+ ':(' +oGroup[sGroup].opt.join('|')+ ')'
                );
            }

            else
            {
                var sJoin = '(' +sGroup+ ':' 
                          + oGroup[sGroup].opt.join('|' +sGroup+ ':')
                          + ')';

                for (var i=0 ; i<oGroup[sGroup].opt.length ; i++)
                    aFilter.push(sJoin);
            }
        }

        ProductList.applyFilter(aFilter);
    },

    /**
     * Apply product list filter.
     *
     * @param  array _aFilter
     * @return void
     */
    applyFilter : function (_aFilter)
    {
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Build regular expression from filter constraints.
        // Requires the same order for keys in list filter
        // and key-value-pairs in element's class name
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var oRegExp = new RegExp(
            _aFilter.join('\\ ([a-z]+:[a-zA-Z0-9]+\\ )*?')
        );


        var aProduct = ProductList.eSelf.getElementsByTagName('li');
        var iLength  = aProduct.length;
        var iIndex   = 0;

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Run each element and if key-value-pairs in class names
        // match filter constraints in regular expression
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        while (iLength--)
        {
            var eProduct = aProduct[iIndex++];

            if (!Element.hasClassName(eProduct, 'product'))
                continue;

            var sDisplay = eProduct.className.match(oRegExp) ? 'inline' : 'none';

            Element.setStyle(eProduct, {display: sDisplay});
        }

        Page.resize();
    }
}



// +------------------------------------------------------------------------+
// | AjaxTabFactory                                                         |
// +------------------------------------------------------------------------+
var AjaxTabFactory = {

    /**
     * Registered AJAX tabs.
     *
     * @var object
     */
    oTab : {},

    /**
     * Register new AJAX tab.
     *
     * @param  string  _sIdentifier
     * @param  boolean _bHilite     Optional.
     * @param  object  _oCallback   Optional.
     * @return void
     */
    register : function (_sIdentifier, _bHiliting, _oCallback)
    {
        if (window.location.href.match(/preview/))
            return;

        this.oTab[_sIdentifier] = new AjaxTab(
            _sIdentifier,
            (_bHiliting || false),
            (_oCallback || null)
        );
    }
}



// +------------------------------------------------------------------------+
// | AjaxTab                                                                |
// +------------------------------------------------------------------------+
var AjaxTab = Class.create();

AjaxTab.prototype = {

    /**
     * Tab content identifier.
     *
     * @var string
     */
    sIdentifier : null,

    /**
     * Use tab hiliting.
     *
     * @var boolean
     */
    bHiliting : null,

    /**
     * On complete callback function.
     *
     * @var object
     */
    oCallback : null,

    /**
     * Initialize AJAX tab. Set tab hiliting.
     *
     * @param  string  _sIdentifier
     * @param  boolean _bHilite     Optional.
     * @param  object  _oCallback   Optional.
     * @return void
     */
    initialize : function (_sIdentifier, _bHiliting, _oCallback)
    {
        this.sIdentifier = _sIdentifier;
        this.bHiliting   = _bHiliting || false;
        this.oCallback   = _oCallback

        this.collectTabs();
    },

    /**
     * Collect tab items and register event handler.
     *
     * @return void
     */
    collectTabs : function ()
    {
        var aTab    = $(this.sIdentifier+ 'Tabs').getElementsByTagName('a');
        var iLength = aTab.length;
        var iIndex  = 0;

        while (iLength--)
        {
			// marktierte Tabs ausschliessen
			if (!aTab[iIndex].parentNode.className.match(/greyTab/))
			{
	            Event.observe(
	                aTab[iIndex],
	                'click',
	                this.tabEvent
	            );
			}
			iIndex++;
        }
    },

    /**
     * Handle tab change on product detail view.
     *
     * @param  object _oEvent
     * @return void
     */
    tabEvent : function (_oEvent)
    {
        Event.stop(_oEvent);

        var eTarget = Event.element(_oEvent), sTarget;

        if ('img' == eTarget.nodeName.toLowerCase())
            eTarget = eTarget.parentNode;

        var eTab    = eTarget.parentNode;
        var oSelf   = AjaxTabFactory.oTab[
            eTab.parentNode.parentNode.id.replace(/Tabs$/, "")
        ];

        if (!GLOBALS.ie6)
            sTarget = eTarget.href;
        else
            {
            sTarget = eTarget.readAttribute('href').replace(
                /^(\.\.\/)+/, GLOBALS.path
            );
        }

        if (
                (oSelf.bHiliting &&  Element.hasClassName(eTab, 'active'))
            ||  false == (sTarget = Page.getRequestTarget(sTarget))
        )
            return;

        Page.updateSection(oSelf.sIdentifier, sTarget, oSelf.oCallback);

        if (!oSelf.bHiliting)
            return;

        // ~~~~~~~~~~~~~~~~~
        // Switch active tab
        // ~~~~~~~~~~~~~~~~~
        var aTab    = dom.get_element('#' +oSelf.sIdentifier+ 'Tabs li');
        var iLength = aTab.length;
        var iIndex  = 0;

        while (iLength--)
            Element.removeClassName(aTab[iIndex++], 'active');

        Element.addClassName(eTarget.parentNode, 'active');
    }
}



// +------------------------------------------------------------------------+
// | Table                                                                  |
// +------------------------------------------------------------------------+
Table = {

    /**
     * Table row order direction.
     *
     * @var string
     */
    sDirection : 'asc',

    /**
     * Initialize sortable table.
     *
     * @param  element _eElement
     * @return void
     */
    init : function (_eElement)
    {
        var eThead  = _eElement.getElementsByTagName('thead')[0];
        var aCell   = eThead.getElementsByTagName('td');
        var iLength = aCell.length;
        var iIndex  = 0;

        while (iLength--)
        {
            if (Element.hasClassName(aCell[iIndex++], 'ignore'))
                continue;

            Event.observe(aCell[iIndex-1], 'click', Table.changeOrder);
        }
    },

    /**
     * Set order direction.
     *
     * @param  element _eCaption
     * @return void
     */
    setDirection : function (_eCaption)
    {
        if (Element.hasClassName(_eCaption, 'asc'))
        {
            Element.removeClassName(_eCaption, 'asc');
            Element.addClassName(_eCaption, 'desc');

            this.sDirection = 'desc';
        }
        else if (Element.hasClassName(_eCaption, 'desc'))
        {
            Element.removeClassName(_eCaption, 'desc');
            Element.addClassName(_eCaption, 'asc');

            this.sDirection = 'asc';
        }
        else
        {
            Element.addClassName(_eCaption, 'asc');

            this.sDirection = 'asc';
        }
    },

    /**
     * Change order of selected column.
     *
     * @param  object _oEvent
     * @return void
     */
    changeOrder : function (_oEvent)
    {
        var eCaption = Event.element(_oEvent);
        
        Table.setDirection(eCaption);

        var aCaption   = eCaption.parentNode.getElementsByTagName('td');
        var iRowLength = aCaption.length;
        var bNumeric   = eCaption.hasClassName('num');

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Run table head's cells to get current column index
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var iColIndex = 0;
        var iLength   = iRowLength;
        var iIndex    = 0;

        while (iLength--)
        {
            var eTemp = aCaption[iIndex];

            if (aCaption[iIndex++] != eCaption)
            {
                Element.removeClassName('desc');
                Element.removeClassName('asc');

                continue;
            }

            iColIndex = --iIndex;
            break;
        }

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Run table body's cells and fetch current column cells
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        var aColumn = new Array();
        var eTbody  = Element.next(eCaption.parentNode.parentNode);
        var aCell   = eTbody.getElementsByTagName('td');

        iLength = aCell.length;
        iIndex  = 0;

        while (iLength--)
        {
            if ((iIndex++ - iColIndex) % iRowLength)
                continue;

            var mValue = null;
            var eCell  = aCell[iIndex-1];

            if (bNumeric)
            {
                if (!eCell.className.match(/\bnum:([0-9]+(\.[0-9]+)?)\b/))
                    mValue = 0;
                else
                    mValue = parseFloat(RegExp.$1);
            }
            else
                mValue = eCell.innerHTML;

            aColumn.push(new Array(mValue, eCell.parentNode));
        }

        aColumn.sort(Table.compareValue);

        iLength = aColumn.length;
        iIndex  = 0;

        while (iLength--)
        {
            var aCol = aColumn[iIndex++];

            Element.removeClassName(aCol[1], 'even');
            Element.removeClassName(aCol[1], 'odd');

            Element.addClassName(aCol[1], (iIndex%2 ? 'odd' : 'even'));

            eTbody.appendChild(aCol[1]);
        }
    },

    /**
     * Helper function for sorting table rows.
     * Defines comparision mode applied on table rows.
     *
     * @param  Array   _aThis
     * @param  Array   _aThat
     * @return boolean
     */
    compareValue : function (_aThis, _aThat)
    {
        var iReturn = (
            (_aThis[0] == _aThat[0]) ? 0 : (_aThis[0] > _aThat[0]) ? 1 : -1
        );

        return ('desc' == Table.sDirection ? iReturn * -1 : iReturn);
    },

    /**
     * Re-locate all sortable tables.
     *
     * @return void
     */
    rehash : function ()
    {
        var aTable  = dom.get_element('table.sortable');
        var iLength = aTable.length;
        var iIndex  = 0;

        while (iLength--)
            Table.init(aTable[iIndex++]);

        myLightWindow._setupLinks();
    }
}



// +------------------------------------------------------------------------+
// | Timeline                                                               |
// +------------------------------------------------------------------------+
var Timeline = {

    /**
     * Timeline element.
     *
     * @var element
     */
    eSelf : null,

    /**
     * Timeline list.
     *
     * @var element
     */
    eList : null,

    /**
     * Timeline scope
     *
     * @var integer
     */
    iScope : 0,

    /**
     * Summed up width of all years.
     *
     * @var integer
     */
    iWidth : 0,

    /**
     * Timeline element position in document.
     *
     * @var integer
     */
    iPosition : 0,

    /**
     * Timeline scrolling start.
     *
     * @var object
     */
    iStart : null,

    /**
     * Timline scrolling interval in milliseconds.
     *
     * @var integer
     */
    iInterval : 25,

    /**
     * Timeline scrolling direction.
     *  1 forward (right)
     * -1 backward (left)
     *
     * @var integer
     */
    iDirecton : 1,

    /**
     * Difference between Timeline width and Timeline scope.
     *
     * @var integer
     */
    iDiff : 0,

    /**
     * First year of history timeline.
     *
     * @var integer
     */
    iFirstYear : 1878,

    /**
     * Timeline scrolling indicator.
     *
     * @var object
     */
    oTimeout : null,

    /**
     * Initialize timeline.
     *
     * @return void
     */
    init : function ()
    {
        Timeline.eSelf = $('historyNavigation');
        Timeline.eList = Timeline.eSelf.getElementsByTagName('ul')[0];

        Element.setStyle(Timeline.eList, {position:'relative'});

        // ~~~~~~~~~~~~~~~~~
        // Set tab positions
        // ~~~~~~~~~~~~~~~~~
        var aDate   = Timeline.eSelf.getElementsByTagName('li');
        var iLength = aDate.length;
        var iIndex  = 0;

        while (iLength--)
        {
            var eDate = aDate[iIndex++];

            eDate.className.match(/([0-9]{4})$/)
            var iLeft = 40 * (parseInt(RegExp.$1) - Timeline.iFirstYear);

            Element.setStyle(
                eDate,
                {
                    position: 'absolute',
                    top: '0px',
                    left: iLeft+'px'
                }
            );

            if (!iLength)
                Timeline.iWidth = Element.getWidth(eDate) + iLeft;
        }

        Element.setStyle(Timeline.eList, {width: (Timeline.iWidth+11)+'px'});

        Timeline.iScope    = Element.getWidth(Timeline.eSelf) - 50;
        Timeline.iPosition = Position.cumulativeOffset(Timeline.eSelf)[0];
        Timeline.iDiff     = Timeline.iWidth - Timeline.iScope;

        if (Timeline.iDiff <= 0)
            return;

        Element.setStyle(Timeline.eList, {left: (-1 * Timeline.iDiff)+'px'});

        Event.observe($('historyBackward'), 'mouseover', Timeline.start);
        Event.observe($('historyBackward'), 'mouseout',  Timeline.stop);

        Event.observe($('historyForward') , 'mouseover', Timeline.start);
        Event.observe($('historyForward') , 'mouseout',  Timeline.stop);

        if (GLOBALS.ie6)
            Timeline.iInterval = 100;
    },

    /**
     * Start Timeline scrolling.
     *
     * @param  object _oEvent
     * @return void
     */
    start : function (_oEvent)
    {
        var eTarget = Event.element(_oEvent);
        var oStart = new Date();

        Timeline.iStart     = 0;
        Timeline.iDirection = eTarget.id.match(/backward/i) ? 1 : -1;

        Timeline.oTimeout   = window.setTimeout(
            'Timeline.scroll()',
            Timeline.iInterval
        );
    },

    /**
     * Stop Timeline scrolling
     *
     * @param  object _oEvent
     * @return void
     */
    stop : function (_oEvent)
    {
        window.clearTimeout(Timeline.oTimeout);

        Timeline.oTimeout = null;
    },

    /**
     * Execute Timeline scrolling.
     *
     * @return void
     */
    scroll : function ()
    {
        var iLeft = parseInt(
            Element.getStyle(Timeline.eList, 'left').replace(/[a-z]+/,"")
        ) + Math.round(Timeline.iDirection * ++Timeline.iStart);

        if (iLeft < Timeline.iDiff * -1)
            iLeft = (Timeline.iDiff * -1);
        else if (iLeft > 0)
            iLeft = 0;

        Element.setStyle(Timeline.eList, {left : iLeft+ 'px'});

        Timeline.oTimeout = window.setTimeout(
            'Timeline.scroll()',
            Timeline.iInterval
        );
    }
}



// +------------------------------------------------------------------------+
// | Gallery                                                                |
// +------------------------------------------------------------------------+
var Gallery = {

    /**
     * Switch image.
     *
     * @param  object _oEvent
     * @return void
     */
    switchImage : function (_oEvent)
    {
        Event.stop(_oEvent);

        var eTarget     = Event.element(_oEvent);
        var sIdentifier = eTarget.getAttribute('rel');

        var eNavigation = eTarget.parentNode.parentNode;
        var aNavigation = eNavigation.getElementsByTagName('a');
        var iLength     = aNavigation.length;
        var iIndex      = 0;

        while (iLength--)
        {
            var eItem = aNavigation[iIndex++];

            if (eItem == eTarget && Element.hasClassName(eItem, 'active'))
                return;

            Element.removeClassName(eItem, 'active');

            if (eItem == eTarget)
                Element.addClassName(eItem, 'active');
        }

        $(sIdentifier+ 'Title').innerHTML = eTarget.getAttribute('title');
        $(sIdentifier).src = eTarget;
    }
};



// +------------------------------------------------------------------------+
// | Rule set of behaviour for several elements                             |
// +------------------------------------------------------------------------+
var RuleSet = {

    /**
     * Search field events.
     *
     * @param  element _eElement Anchor element.
     * @return void
     */
    '#qsQuery' : function (_eElement)
    {
        Event.observe(
            _eElement,
            'focus',
            function (_oEvent)
            {
                var eTarget = Event.element(_oEvent);

                eTarget.value = '';
            }
        );
    },

    /**
     * Open external links in a new window.
     *
     * @param  element _eElement Anchor element.
     * @return void
     */
    'a.ext' : function (_eElement)
    {
        Event.observe(_eElement, 'click', Page.externalLinks);
    },

    /**
     * Drop down boxes
     *
     * @param  element _eElement Drop down label.
     * @return void
     */
    'span.dropDownLabel' : function (_eElement)
    {
        DropDown.pushBox(
            _eElement,
            Element.next(_eElement, 'div.dropDownItems')
        );
    },

    /**
     * Product list filter options.
     *
     * @param  element _eElement Product list filter option.
     * @return void
     */
    '#productListFilter input.checkbox' : function (_eElement)
    {
        Event.observe(
            _eElement,
            (GLOBALS.ie6 || GLOBALS.ie7 ? 'click' : 'change'),
            ProductList.filterEvent
        );
    },

    /**
     * Product detail view tab navigation.
     *
     * @param  element _eElement Product detail view tab.
     * @return void
     */
    '#productDetail' : function (_eElement)
    {
        AjaxTabFactory.register('productDetail', true);
    },

    /**
     * History tab navigation
     *
     * @param  element _eElement Product detail view tab.
     * @return void
     */
    '#history' : function (_eElement)
    {
        AjaxTabFactory.register('history', false);

        Timeline.init();
    },

    /**
     * Second hand machinces tab navigation.
     *
     * @param  element _eElement Product group tab.
     * @return void
     */
    '#usedMachines' : function (_eElement)
    {
        AjaxTabFactory.register('usedMachinesList', true, Table.rehash);
    },

    /**
     * Intitialize sortable tables.
     *
     * @param  element _eElement Sortable table.
     * @return void
     */
    'table.sortable' : function (_eElement)
    {
        Table.init(_eElement);
    },

    /**
     * Intitialize galleries.
     *
     * @param  element _eElement Sortable table.
     * @return void
     */
    'div.contentGallery a' : function (_eElement)
    {
        Event.observe(_eElement, 'click', Gallery.switchImage);
    },

    /**
     * Intitialize product list filter.
     *
     * @param  element _eElement.
     * @return void
     */
    '#productListFilter' : function (_eElement)
    {
        ProductList.filterEvent();
    }
}

Behaviour.register(RuleSet);



Event.observe(window , 'load', Page.init);
Event.observe(window , 'resize', Page.resize);

/* click event to switch metric and imperial measures in section technical specs */
$j(document).ready(function(){

	$j(".measureFlip").live("click", function(){
		$j("#productSpecs .imp").toggleClass("show");
		$j("#productSpecs .met").toggleClass("show");
		$j(".measureFlip.toMet").toggleClass("show");
		$j(".measureFlip.toImp").toggleClass("show");				
	});

});