/*
This file is part of Ext JS 3.4

Copyright (c) 2011-2013 Sencha Inc

Contact:  http://www.sencha.com/contact

GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.

Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.

If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

Build date: 2013-04-03 15:07:25
*/
/*
 * Ext Core Library Examples 3.0 Beta
 * http://extjs.com/
 * Copyright(c) 2006-2009, Ext JS, LLC.
 * 
 * The MIT License
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */

Ext.ns('Ext.ux');

Ext.ux.Menu = Ext.extend(Ext.util.Observable, {
    direction: 'horizontal',
    delay: 0.2,
    autoWidth: true,
    transitionType: 'fade',
    transitionDuration: 0.3,
    animate: true,
    currentClass: 'current',

    constructor: function(elId, config) {
        config = config || {};
        Ext.apply(this, config);

        Ext.ux.Menu.superclass.constructor.call(this, config);

        this.addEvents(
            'show',
            'hide',
            'click'
        );

        this.el = Ext.get(elId);

        this.initMarkup();
        this.initEvents();

        this.setCurrent();
    },

    initMarkup: function(){
        this.container = this.el.wrap({cls: 'ux-menu-container', style: 'z-index: ' + --Ext.ux.Menu.zSeed});
        this.items = this.el.select('li');

        this.el.addClass('ux-menu ux-menu-' + this.direction);
        this.el.select('>li').addClass('ux-menu-item-main');

        this.el.select('li:has(>ul)').addClass('ux-menu-item-parent').each(function(item) {
            item.down('a')
                .addClass('ux-menu-link-parent')
                .createChild({tag: 'span', cls: 'ux-menu-arrow'});
        });
        
        this.el.select('li:first-child>a').addClass('ux-menu-link-first');
        this.el.select('li:last-child>a').addClass('ux-menu-link-last');

        // create clear fixes for the floating stuff
        this.container.addClass('ux-menu-clearfix');

        // if autoWidth make every submenu as wide as its biggest child;
        if(this.autoWidth) {
            this.doAutoWidth();
        }

        var subs = this.el.select('ul');
        subs.addClass('ux-menu-sub');
        
        //ie6 and ie7/ie8 quirksmode need iframes behind the submenus
        if(Ext.isBorderBox || Ext.isIE7) {
            subs.each(function(item) {
                item.parent().createChild({tag: 'iframe', cls: 'ux-menu-ie-iframe'})
                    .setWidth(item.getWidth())
                    .setHeight(item.getHeight());
            });
        }
        
        subs.addClass('ux-menu-hidden');
    },

    initEvents: function() {
        this.showTask = new Ext.util.DelayedTask(this.showMenu, this);
        this.hideTask = new Ext.util.DelayedTask(function() {
            this.showTask.cancel();
            this.hideAll();
            this.fireEvent('hide');
        }, this);

        this.el.hover(function() {
            this.hideTask.cancel();
        }, function() {
            this.hideTask.delay(this.delay*1000);
        }, this);

        // for each item that has a submenu, create a mouseenter function that shows its submenu
        // delay 5 to make sure enter is fired after mouseover
        this.el.select('li.ux-menu-item-parent').on('mouseenter', this.onParentEnter, false, {me: this, delay: 5});

        // listen for mouseover events on items to hide other items submenus and remove hovers
        this.el.on('mouseover', function(ev, t) {
            this.manageSiblings(t);
            // if this item does not have a submenu, the showMenu task for a sibling could potentially still be fired, so cancel it
            if(!Ext.fly(t).hasClass('ux-menu-item-parent')) {
                this.showTask.cancel();
            }
        }, this, {delegate: 'li'});

        this.el.on('click', function(ev, t) {
            return this.fireEvent('click', ev, t, this);
        }, this, {delegate: 'a'})
    },

    onParentEnter: function(ev, link, o) {
        var item = Ext.get(this),
            me = o.me;

        // if this item is in a submenu and contains a submenu, check if the submenu is not still animating
        if(!item.hasClass('ux-menu-item-main') && item.parent('ul').hasActiveFx()) {
            item.parent('ul').stopFx(true);
        }

        // if submenu is already shown dont do anything
        if(!item.child('ul').hasClass('ux-menu-hidden')) {
            return;
        }
        
        me.showTask.delay(me.delay*1000, false, false, [item]);   
    },

    showMenu : function(item) {
        var menu = item.child('ul'),
            x = y = 0;

        item.select('>a').addClass('ux-menu-link-hover');

        // some different configurations require different positioning
        if(this.direction == 'horizontal' && item.hasClass('ux-menu-item-main')) {
            y = item.getHeight()+1;
        }
        else {
            x = item.getWidth()+1;
        }

        // if its ie, force a repaint of the submenu
        if(Ext.isIE) {
            menu.select('ul').addClass('ux-menu-hidden');
            // ie bugs...
            if(Ext.isBorderBox || Ext.isIE7) {
                item.down('iframe').setStyle({left: x + 'px', top: y + 'px', display: 'block'});
            }
        }

        menu.setStyle({left: x + 'px', top: y + 'px'}).removeClass('ux-menu-hidden');

        if(this.animate) {
            switch(this.transitionType) {
                case 'slide':
                    if(this.direction == 'horizontal' && item.hasClass('ux-menu-item-main')) {
                        menu.slideIn('t', {
                            duration: this.transitionDuration
                        });
                    }
                    else {
                        menu.slideIn('l', {
                            duration: this.transitionDuration
                        });
                    }
                break;

                default:
                    menu.setOpacity(0.001).fadeIn({
                        duration: this.transitionDuration
                    });
                break
            }
        }
        
        this.fireEvent('show', item, menu, this);
    },

    manageSiblings: function(item) {
        var item = Ext.get(item);
        item.parent().select('li.ux-menu-item-parent').each(function(child) {
            if(child.dom.id !== item.dom.id) {
                child.select('>a').removeClass('ux-menu-link-hover');
                child.select('ul').stopFx(false).addClass('ux-menu-hidden');
                if (Ext.isBorderBox || Ext.isIE7) {
                    child.select('iframe').setStyle('display', 'none');
                }
            }
        });
    },

    hideAll: function() {
        this.manageSiblings(this.el);
    },
    
    setCurrent: function() {
        var els = this.el.query('.' + this.currentClass);
        if(!els.length) {
            return;
        }
        var item = Ext.get(els[els.length-1]).removeClass(this.currentClass).findParent('li', null, true);
        while(item && item.parent('.ux-menu')) {
            item.down('a').addClass(this.currentClass);
            item = item.parent('li');
        }
    },

    doAutoWidth: function() {
        var fixWidth = function(sub) {
            var widest = 0;
            var items = sub.select('>li');

            sub.setStyle({width: 3000 + 'px'});
            items.each(function(item) {
                widest = Math.max(widest, item.getWidth());
            });

            widest = Ext.isIE ? widest + 1 : widest;
            items.setWidth(widest + 'px');
            sub.setWidth(widest + 'px');
        }

        if(this.direction == 'vertical') {
            this.container.select('ul').each(fixWidth);
        }
        else {
            this.el.select('ul').each(fixWidth);
        }
        
    }
});

Ext.ux.Menu.zSeed = 10000;