LibJs.Menu = Class.create({
    id: '',
    menuEl: null,
    binder: Array(),
    hiddenBinder: Array(),
    itemPos: Array(),
    menuPos: Array(),

    checkWithin: function(pos, pointX, pointY) {
        /*
        LibJs.Manager.log('lowX: ' + pos.lowX + ' lowY: ' + pos.lowY + ' maxX: ' + pos.maxX + ' maxY: ' + pos.maxY +
            ' pointX: ' + pointX + ' pointY: ' + pointY); */
        if ((pointX >= pos.lowX) && (pointY >= pos.lowY) && (pointX <= pos.maxX) && (pointY <= pos.maxY)) {
            return true
        } else {
            return false;
        }
    },

    initialize: function(id) {
        this.id = id;

        if ($(id)) {
            this.menuEl = $(id);
            this.init();
        }
    },

    init: function() {
        var barItem = this.menuEl.down('ul').childElements();
        var barHeight = this.menuEl.getHeight();

        var onItem = this.onItem;
        var onOut = this.onOut;
        var obj = this;

        barItem.each(function(item, index) {
            if (item.hasClassName('hassubmenu')) {
                var pos = item.positionedOffset();
                var dim = item.getDimensions();

                var childDiv = item.down('.yuimenu');
                childDiv.style.top = (pos[1] + barHeight - 2) + 'px';
                childDiv.style.zIndex = 5;
                childDiv.style.left = pos[0] + 'px';
                //childDiv.style.width = '145px';

                var posMenu = childDiv.positionedOffset();
                var dimMenu = childDiv.getDimensions();
                this.menuPos[index] = {lowX: posMenu[0], lowY: posMenu[1],
                    maxX: posMenu[0] + dimMenu.width, maxY: posMenu[1] + dimMenu.height}

                childDiv.style.visibility = 'hidden';
                childDiv.style.overflow = 'visible';

                this.binder[index] = this.menuMove.bindAsEventListener(this, item, childDiv, index);
                this.itemPos[index] = {lowX: pos[0], lowY: pos[1], maxX: pos[0] + dim.width, maxY: pos[1] + dim.height}

                Event.observe(item, 'mouseover', this.binder[index]);

                childDiv.select('.yuimenuitem').each(function(el, idx) {
                    Event.observe(el, 'mouseover', onItem.bind(obj, el));
                    Event.observe(el, 'mouseout', onOut.bind(obj, el));
                });
            }
        }, this)
    },

    onItem: function(el) {
        el.addClassName('hover');
    },

    onOut: function(el) {
        el.removeClassName('hover');
    },

    menuMove: function(e, item, menu, idx) {
        e.stopPropagation();
        Event.stopObserving(item, 'mouseover', this.binder[idx])


        var childDiv = menu.down('.bd');
        menu.up('li').addClassName('selected');
        menu.previous('a').addClassName('selected');

        var movement = this.menuPos[idx].maxY - this.menuPos[idx].lowY;
        childDiv.style.top = -(movement) + 'px';

        new Effect.Move(childDiv, {y: movement, afterSetup: this.beforeStart.bind(this, menu),
                afterFinish: this.prepareMenuOut.bind(this, item, menu, idx), duration: 0.4
            });

    },

    beforeStart: function(menu) {
        menu.style.visibility = 'visible';
        menu.style.overflow = 'hidden';

    },

    prepareMenuOut: function(item, menu, idx) {
        this.hiddenBinder[idx] = this.menuOut.bindAsEventListener(this, item, menu, idx);

        if (!this.menuPos[idx]) {

        }
        Event.observe(document, 'mousemove', this.hiddenBinder[idx]);
    },

    menuOut: function(e, item, menu, idx) {

        var x = e.pointerX();
        var y = e.pointerY();

        if (this.checkWithin(this.itemPos[idx], x, y) ||
            this.checkWithin(this.menuPos[idx], x, y)) {
        } else {

            e.stopPropagation();
            Event.stopObserving(document, 'mousemove', this.hiddenBinder[idx]);
            menu.style.visibility = 'hidden';
            menu.style.overflow = 'visible';
            menu.up('li').removeClassName('selected');
            menu.previous('a').removeClassName('selected');
            Event.observe(item, 'mouseover', this.binder[idx]);
        }
    }
});

LibJs.MenuStatic = {
    prepareMenu: function(id, hoverClass) {
        Event.observe(window, 'load', LibJs.MenuStatic.initMenu.bind(LibJs.MenuStatic, id, hoverClass));
    },

    initMenu: function(id, hoverClass) {
        if ($(id)) {
            var onItem = LibJs.MenuStatic.onItem;
            var onOut = LibJs.MenuStatic.onOut;
            var obj = LibJs.MenuStatic;
            
            $(id).select('.nav-itemwrap').each(function(el, idx) {
                Event.observe(el, 'mouseover', onItem.bind(obj, el, hoverClass));
                Event.observe(el, 'mouseout', onOut.bind(obj, el, hoverClass));
            });
        }
    },

    onItem: function(el, hoverClass) {
        el.addClassName(hoverClass);
    },

    onOut: function(el, hoverClass) {
        el.removeClassName(hoverClass);
    }
}
