﻿//CONCEPTS2GO BV
/*
* Class with style definitions
*/
/*
.blue{color:#336699;background:transparent;} 
.red{color:#ff0000;background:transparent;} 
		
.ctr{text-align:center;} 
.rt{text-align:right;} 
		
And then anywhere where you wish to use the Multiple CSS Classes you can do this... 
		
<p class="blue ctr" >Blue centered text here.</p> 
		
<p class="red rt" >Red right aligned text here.</p>     
*/
var ListMenuUtils = new Class({

    min: function(intA, intB) {
        return (intA < intB) ? intA : intB;
    },
    max: function(intA, intB) {
        return (intA > intB) ? intA : intB;
    }
});
var ListMenuSize = new Class({
    initialize: function(x, y) {
        this.x = x;
        this.y = y;
    }
});

var ListMenuStyle = new Class({
    initialize: function(menuDepth, normalCss, overCss, clickCss, disableCss, headerObj, footerObj) {

        this.MenuDepth = menuDepth;
        this.NormalCss = normalCss;
        this.OverCss = overCss;
        this.ClickCss = clickCss;
        this.DisableCss = disableCss;

        this.HeaderObj = (headerObj) ? headerObj : null; // assign and remove from dom
        if (this.HeaderObj) {
            if (!this.HeaderObj.dispose)
                this.HeaderObj.each(function(item, index) { if (item) item.dispose() });
            else
                this.HeaderObj.dispose();
        }
        this.FooterObj = (footerObj) ? footerObj : null; // assign and remove from dom
        if (this.FooterObj) {
            if (!this.FooterObj.dispose)
                this.FooterObj.each(function(item, index) { item.dispose() });
            else
                this.FooterObj.dispose();
        }

    },
    _setClass: function(element, fromClass, toClass) {
        if (element) {
            if (fromClass && (fromClass != '') && (element.hasClass(fromClass)))
                element.removeClass(fromClass);
            if (toClass && (toClass != '') && (!element.hasClass(fromClass)))
                element.addClass(toClass);
        }
    },
    SetOutClass: function(element) {
        this._setClass(element, this.OverCss, this.NormalCss);
    },
    SetOverClass: function(element) {
        this._setClass(element, this.NormalCss, this.OverCss);
    },
    SetClickClass: function(element) {
        this._setClass(element, this.OverCss, this.ClickCss);
    },
    GetHeaderObject: function(index) {
        if (this.HeaderObj) {
            if (this.HeaderObj.each) {
                if (index < this.HeaderObj.length)
                    return this.HeaderObj[index];
                else
                    return this.HeaderObj[this.HeaderObj.length - 1];
            }
        }
        return this.HeaderObj;
    },
    GetFooterObject: function(index) {
        if (this.FooterObj) {
            if (this.FooterObj.each) {
                if (index < this.FooterObj.length)
                    return this.FooterObj[index];
                else
                    return this.FooterObj[this.FooterObj.length - 1];
            }
        }
        return this.FooterObj;
    }



});


var ListMenuItem = new Class({
    initialize: function(listItem, listIndex, parentItem, rootItem, menuOwner, menuDepth) {

        this.ListIndex = listIndex    //the position of this item in the parent child nodes
        this.MenuDepth = menuDepth;   //level of current item
        this.ParentItem = parentItem; //parent menu item 
        this.Owner = menuOwner;       //the menu object
        this.IsClicked = false;
        this.RootItem = (menuDepth == 0) ? this : rootItem;
        this.Style = this.Owner.GetStyle(this.MenuDepth);
        // get some dom elements
        this.ListItem = listItem;
        this.LinkElement = listItem.getFirst('a'); 			// the menu item
        this.ChildList = listItem.getFirst('ul'); // the sub unordered list
        this.ChildItems = new Array();
        this.FirstShow = true;

        // prepare the sub-menu dom-elements
        if (this.ChildList) {
            // get the sub unordered list again and remove it from the dom
            this.ChildList = listItem.getFirst('ul').dispose();
            this.MenuContainer = new Element('div', {
                'class': 'menuContainer_Level' + this.MenuDepth + ' menuContainer_Item' + this.ListIndex,
                'styles': {
                    'width': this.ListItem.getSize().x,
                    'float': 'left',
                    'display': 'none'
                }
            });
            this.ChildContainer = new Element('div', {
                'class': 'childContainer_Level' + this.MenuDepth + ' childContainer_Item' + this.ListIndex,
                'styles': {
                    'width': this.ListItem.getSize().x,
                    'overflow': 'hidden',
                    'float': 'left'
                }
            });
        }
        // get some dimensions
        this.MenuContainerSize = null;
        this.ChildListSize = null;
        this.ChildContainerSize = null;

        // bind events
        if (this.LinkElement) {
            this.LinkElement.addEvent('mouseover', this.OnMouseOver.bindWithEvent(this));
            this.LinkElement.addEvent('mouseout', this.OnMouseOut.bindWithEvent(this));
            this.LinkElement.addEvent('click', this.OnClick.bindWithEvent(this));
        }
        // load child items
        if (this.ChildList) {
            var childListItems = this.ChildList.getChildren('li');
            for (var j = 0; j < childListItems.length; j++) {
                var newChild = new ListMenuItem(childListItems[j], j, this, this.RootItem, this.Owner, this.MenuDepth + 1)
                this.ChildItems[this.ChildItems.length] = newChild;
            }
        }
    },
    OnMouseOver: function(evt) {
        //if ((this.LinkElement) && (this.Style))
        //	this.Style.SetOverClass(this.LinkElement);
        if (this.ChildItems.length > 0)
            this.dropDown(evt);
        else
            this.removeDropDown(evt);
    },
    OnMouseOut: function(evt) {
        //if ((this.LinkElement) && (this.Style))
        //	this.Style.SetOutClass(this.LinkElement);
    },
    OnClick: function(evt) {
        this.dropDown(evt);
    },
    removeDropDown: function(evt) {
        this.ParentItem.ChildItems.each(function(item, index) {
            try {
                // remove all visible sub-menus
                item.MenuContainer.setStyle('display', 'none');
                item.MenuContainer.dispose();
                //item.LinkElement.setStyle('color', '');
                if (item.Style && (item.Style.ClickCss != '') && (item.LinkElement.hasClass(item.Style.ClickCss)))
                    item.LinkElement.removeClass(item.Style.ClickCss)
            }
            catch (err) { }
        });
    },
    dropDown: function(evt) {
        var utils = new ListMenuUtils();
        this.removeDropDown(evt);

        if (this.ChildItems && (this.ChildItems.length > 0)) {
            evt.stop(); // don't follow the link
            // prepare the parent ChildContainer
            if (!this.FirstShow) {
                this.ChildList.setStyle('height', this.ChildListSize.y);
                this.ChildContainer.setStyle('height', this.ChildContainerSize.y);
            }

            var rootItem = this.ParentItem;
            while (rootItem.ParentItem.MenuDepth > 0)
                rootItem = rootItem.ParentItem;
            var isLastRoot = (rootItem.ListIndex == rootItem.ParentItem.ChildItems.length - 1);

            if (this.Style && (this.Style.ClickCss != ''))
                this.LinkElement.addClass(this.Style.ClickCss)
            //this.LinkElement.setStyle('color', '#98D441');


            var childHeight = 0;
            //var selfWidth = this.LinkElement.getSize().x;
            var selfWidth = this.ListItem.getSize().x;

            var w = this.ParentItem.LinkElement.getSize().x + selfWidth;
            this.ParentItem.ChildContainer.setStyle('width', w);
            this.ParentItem.ChildContainer.setStyle('height', this.ParentItem.ChildContainerSize.y + 'px');
            this.ParentItem.ChildList.setStyle('height', this.ParentItem.ChildListSize.y + 'px');

            // prepare the MainContainer
            this.MenuContainer.setStyle('float', 'left');
            this.MenuContainer.setStyle('overflow', 'hidden');
            this.MenuContainer.setStyle('width', '0px');
            this.MenuContainer.setStyle('height', this.ParentItem.ChildContainerSize.y + 'px');
            this.MenuContainer.setStyle('display', 'block');
            this.MenuContainer.inject(this.ParentItem.ChildContainer);

            // we must have a header element to set the height
            var h = this.LinkElement.getCoordinates().top - this.ParentItem.LinkElement.getCoordinates().height - this.ParentItem.LinkElement.getCoordinates().top
            h = h - 10;
            //var h = 1;
            var hdrContainer = new Element('div', {
                'styles': {
                    'display': 'block',
                    'float': 'left',
                    'height': h
                }
            });
            hdrContainer.inject(this.MenuContainer);
            childHeight += hdrContainer.getSize().y;

            var hdr = this.Style.GetHeaderObject(this.ListIndex);
            if (hdr) {
                hdr.setStyle('float', 'left');
                hdr.inject(hdrContainer);
                hdr.setStyle('display', 'block');
                //hdrContainer.setStyle('padding-top', h - hdr.getSize().y);
            }

            this.ChildContainer.setStyle('width', selfWidth)
            this.ChildContainer.setStyle('float', 'left');
            this.ChildContainer.inject(this.MenuContainer);
            //this.ChildContainer.setStyle('border', '1px solid #00ffff');

            this.ChildContainer.setStyle('display', 'block');

            this.ChildList.setStyle('float', 'left');
            this.ChildList.inject(this.ChildContainer);
            this.ChildList.setStyle('display', 'block');
            childHeight += this.ChildList.getSize().y;

            var ftr = this.Style.GetFooterObject(this.ListIndex);
            if (ftr) {

                ftr.setStyle('float', 'left');
                ftr.inject(this.MenuContainer);
                ftr.setStyle('display', 'block');
                childHeight += ftr.getSize().y;
            }

            if (this.FirstShow) {
                this.FirstShow = false;
                this.ChildContainerSize = this.ChildContainer.getSize();
                //this.ChildContainerSize.y = endHeight;
                this.ChildListSize = this.ChildList.getSize();
                //this.ChildListSize.y = endHeight;
            }

            //this.ChildContainer.setStyle('height', this.MenuContainer.getSize().y - childHeight);
            // now determine who's the hightest, the sub menu or the current menu
            var subMenuTopAligned = false;
            var parentHeight = this.ParentItem.ChildContainer.getSize().y;
            var divHeight = childHeight - parentHeight;
            var hfHeight = childHeight - this.ChildList.getSize().y;

            var fxWidth = new Fx.Tween(this.MenuContainer);

            if (divHeight > 0) {
                if (subMenuTopAligned) {
                    //this will scale the parent menu to the same height
                    var fxHOuter = new Fx.Tween(this.ParentItem.ChildContainer);
                    fxHOuter.start('height', childHeight);
                    var fxHOuter1 = new Fx.Tween(this.ParentItem.ChildList);
                    fxHOuter1.start('height', childHeight).chain(function() { fxWidth.start('width', 0, selfWidth); });
                }
                else {
                    // normal pulldown behaviour
                    // offset issue: we willen dat links van het sub-menu precies op 
                    // rechts van de parent valt.
                    this.MenuContainer.setStyle('position', 'absolute');
                    this.MenuContainer.setStyle('left', selfWidth - 1);

                    fxWidth.start('width', 0, selfWidth);
                }
                this.MenuContainer.setStyle('height', childHeight);
                this.ChildContainer.setStyle('height', childHeight - hfHeight);
            }
            else {
                // normal pulldown behaviour
                this.MenuContainer.setStyle('height', parentHeight);
                this.ChildContainer.setStyle('height', parentHeight - hfHeight);
                this.ChildList.setStyle('height', parentHeight - hfHeight);

                if (isLastRoot) {
                    var iLeft = this.ParentItem.MenuContainer.getCoordinates().left;
                    this.MenuContainer.setStyle('position', 'absolute');
                    this.MenuContainer.setStyle('left', 0);

                    var fxLeft = new Fx.Tween(this.MenuContainer);
                    fxLeft.start('left', -selfWidth + 1);
                }
                else {
                    this.MenuContainer.setStyle('position', 'absolute');
                    this.MenuContainer.setStyle('left', selfWidth - 1);
                }
                fxWidth.start('width', 0, selfWidth);
            }
            this.DroppedDown = true;

        }
    },
    onDroppedDown: function(evt) {
        this.MenuContainer.setStyle('overflow', 'visible');
    }

});

var ListTopMenuItem = new Class({
    Extends: ListMenuItem,
    initialize: function(listItem, listIndex, parentItem, rootItem, menuOwner, menuDepth) {
        // base constructor
        this.parent(listItem, listIndex, parentItem, rootItem, menuOwner, menuDepth);

    },
    OnClick: function(evt) {
        this.Owner.fadeBackground();
        this.dropDown(evt);
    },
    OnMouseOver: function(evt) {
        //if ((this.LinkElement) && (this.Style))
        //	this.Style.SetOverClass(this.LinkElement);
        if (this.Owner.DroppedDown) {
            this.dropDown(evt);
        }
    },
    dropDown: function(evt) {
        // kill the popup if any
        this.Owner.CloseMenu(evt);
        this.ChildItems.each(function(item, index) {
            try {
                // remove all visible sub-menus
                item.MenuContainer.dispose();
                if (item.Style && (item.Style.ClickCss != '') && (item.LinkElement.hasClass(item.Style.ClickCss)))
                    item.LinkElement.removeClass(item.Style.ClickCss)
            }
            catch (err) { }
        });

        this.outerCloseEvent = this.OnOuterMenuClick.bindWithEvent(this);
        document.addEvent('click', this.outerCloseEvent);

        if (this.ChildItems && (this.ChildItems.length > 0)) {
            evt.stop(); // don't follow the link
            var initHeight = 0;
            //reset some properties 
            if (!this.FirstShow) {
                this.ChildList.setStyle('height', this.ChildListSize.y);
                this.ChildContainer.setStyle('height', this.ChildContainerSize.y);
            }
            var isLast = (this.ListIndex == this.ParentItem.ChildItems.length - 1);

            this.MenuContainer.setStyle('width', this.LinkElement.getSize().x);
            this.MenuContainer.setStyle('height', '1px');
            //debug
            //this.MenuContainer.setStyle('border', '1px solid #ff00ff');

            this.ChildContainer.setStyle('overflow', 'hidden');
            this.ChildContainer.setStyle('width', this.LinkElement.getSize().x);
            this.ChildContainer.setStyle('height', '1px');
            // inject some stuff
            var hdr = this.Style.GetHeaderObject(this.ListIndex);
            if (hdr) {
                initHeight += hdr.getStyle('height').toInt();
                hdr.setStyle('float', 'left');
                hdr.setStyle('display', 'block');
                hdr.addEvent('click', this.OnHeaderClick.bindWithEvent(this));
                hdr.inject(this.MenuContainer);
            }
            this.MenuContainer.setStyle('height', initHeight);
            this.ChildList.setStyle('float', 'left');
            this.ChildList.inject(this.ChildContainer);
            this.ChildList.setStyle('display', 'block');

            this.ChildContainer.setStyle('float', 'left');
            //this.MenuContainer.setStyle('float', isLast ? 'right' : 'left');
            this.ChildContainer.inject(this.MenuContainer);

            var ftr = this.Style.GetFooterObject(this.ListIndex);
            if (ftr) {
                initHeight += ftr.getStyle('height').toInt();
                ftr.setStyle('float', 'left');
                ftr.setStyle('display', 'block');
                ftr.inject(this.MenuContainer);

            }
            // modal popup	            
            /*
            this.Owner.popup = new StickyWinModal({
            content: this.MenuContainer, 
            position: 'topLeft',
            relativeTo: this.LinkElement,
            offset: {
            x: 0,
            y: 0
            },
            modalOptions: {
            modalStyle: {
            'background-color':'#000000',
            'opacity': 0.01
            }
            }                            
            });
            */
            this.Owner.popup = new StickyWin({
                content: this.MenuContainer,
                position: 'topLeft',
                relativeTo: this.LinkElement,
                offset: {
                    x: 0,
                    y: 0
                }
            });
            this.MenuContainer.setStyle('display', 'block');

            // backup original initial sizes
            var endHeight = this.ChildList.getSize().y;
            // min-height
            // check if we want the min-height
            var elem = $('FlashHeader');
            if ($('FlashHeader') && (endHeight < 240)) {
                endHeight = 240;
                this.ChildList.setStyle('height', endHeight);
            }

            if (this.FirstShow) {
                this.FirstShow = false;
                this.ChildContainerSize = this.ChildContainer.getSize();
                this.ChildContainerSize.y = endHeight;
                this.ChildListSize = this.ChildList.getSize();
                this.ChildListSize.y = endHeight;
            }
            this.Owner.DroppedDown = true;
            this.Owner.popup.position();
            var fxHeight = new Fx.Tween(this.ChildContainer);
            fxHeight.addEvent('complete', this.onDroppedDown.bindWithEvent(this));
            fxHeight.start('height', 0, endHeight);
        }
    },
    onDroppedDown: function(evt) {
        this.ChildContainer.setStyle('overflow', 'visible');
        this.Owner.DroppedDown = true;
    },
    OnHeaderClick: function(evt) {
        this.Owner.CloseMenu();
        this.Owner.unfadeBackground();
        return false;
    },
    OnOuterMenuClick: function(evt) {
        this.Owner.CloseMenu();
        this.Owner.unfadeBackground();
        if (this.outerCloseEvent) {
            document.removeEvent('click', this.outerCloseEvent);
            this.outerCloseEvent = null;
        }
        //return false;		
    }
});

var ListMenu = new Class({
    initialize: function(topElement, styleArray) {
        this.elem = topElement;
        this.StyleArray = styleArray;
        this.ChildItems = new Array();
        this.popup = null;
        this.DroppedDown = false;
        // load top items
        var list = this.elem.getChildren('li');
        list.each(this._processTopNode, this);

        window.addEvent('resize', this.onWindowResize.bindWithEvent(this));
    },
    _processTopNode: function(item, index) {
        var newItem = new ListTopMenuItem(item, index, this, null, this, 0);
        this.ChildItems[index] = newItem;
    },
    GetStyle: function(menuDepth) {

        var result = null;
        if (this.StyleArray && (this.StyleArray.length > 0)) {
            if (menuDepth < this.StyleArray.length)
                result = this.StyleArray[menuDepth];
            else
                result = this.StyleArray[this.StyleArray.length - 1];
        }
        if (!result)
            result = new ListMenuStyle(menuDepth, "", "", "", "", null, null);


        return result;
    },
    CloseMenu: function(evt) {
        if (this.popup) {
            this.popup.hide();
            this.popup.destroy();
            this.popup = null;
        }
        this.DroppedDown = false;
    },
    onWindowResize: function(evt) {
        if (this.popup)
            this.popup.position();
    },
    fadeBackground: function() {
        var elem = $('FlashHeader');
        if (elem) elem.fade(0.3);
    },
    unfadeBackground: function() {
        var elem = $('FlashHeader');
        if (elem) elem.fade(1);
    }
});




