// JavaScript Document
var pe;
var MenuControl = {
    cmenu: null,
    hide: function(menuItem) {
        if (this.cmenu) {
            this.cmenu = null;
        }
        menuItem.hide();
        
    },
    show: function(menuItem) {
        if(this.cmenu && this.cmenu != menuItem) {
            this.cmenu.hide();
        }
        
        menuItem.show();
        
        this.cmenu = menuItem;
     }
}

var MenuItem = Class.create();
Object.extend(MenuItem.prototype, {
    menuItem: null,
    subMenu: null,
    initialize: function(el) {
        var defaults = {
            absolutize: true,
            top: '100%',
            left: '0px',
            detectEdgeToElement: null,
            onevent: 'mouseover',
            offevent: 'mouseout',
            showEffect: null,
            hideEffect: null,
            opens: 'bottom',
            positionTo: null,
            delay: 500
        };
        
        options = Object.extend(defaults, arguments[1] || {});
        this.options = options;
        
        
        el = $(el);
        //alert(el);
        this.menuItem = el;
            
        link = el.select('a')[0];
            
        this.collectSubNav();
        if (this.subMenu) {
            // attach link events
            link.observe(options.onevent, this.showMenu.bindAsEventListener(this));
            link.observe(options.offevent,  this.hideMenu.bindAsEventListener(this));
                
            // Attach to the submenu structure
            this.subMenu.observe(options.onevent, this.showMenu.bindAsEventListener(this));
            this.subMenu.observe(options.offevent,  this.hideMenu.bindAsEventListener(this));
        }
        
        return;
    },
    collectSubNav: function() {
        this.subMenu = this.menuItem.select('.submenu')[0];
        var container = null;
        
        if (this.subMenu) {
            //this.subMenu.hide();
            
            // If alternate "containing" element is specififed, use it
            if (this.options.positionTo) {
                container = $(this.options.positionTo);
            }
            
            // None, use the default
            if (!container) {
                container = this.menuItem;
            }
            
            container.makePositioned();
            
            if (this.options.absolutize) {
                this.subMenu.hide();
                this.subMenu.setStyle({'position':'relative'});
                this.subMenu.setStyle({'position':'absolute'});
                
                //var b_r = this.subMenu.getStyle('border-right-width');
                //var b_l = this.subMenu.getStyle('border-left-width');

                //var b_x = parseInt(b_r.substring(0, (b_r.length - 2))) + parseInt(b_l.substring(0, (b_l.length - 2)));
                var b_x = 0;
                if (this.options.positionTo) {
                    this.subMenu.clonePosition(this.menuItem,{'setWidth': false, 'setHeight': false});
                    var width = this.subMenu.getWidth();
                    var box = b_x + width;
                    var left = '-' + box + 'px';
                    this.subMenu.setStyle({'left': left});

                    return;
                }
                
                if (this.options.opens == 'bottom') {
                    this.subMenu.setStyle({'top': this.options.top});
                    this.subMenu.setStyle({'left':'0'});
                }
                
                if (this.options.opens == 'left') {
                    var width = this.subMenu.getWidth();
                    var box = b_x + width;
                    var left = '-' + box + 'px';
                    this.subMenu.setStyle({'left': left});
                    this.subMenu.setStyle({'top': '0px'});
                }
            }
            
        }
    },
    showMenu: function() {
        if (pe) {
            clearTimeout(pe);
        }
        
        MenuControl.show(this);
    },
    show: function() {
        //this.subMenu.setStyle({'z-index' : -100});
        if (!this.subMenu.visible()) {
            if (this.options.showEffect) {
              // Invoke the show effect 
              if (Effect) {
                Effect[this.options.showEffect](this.subMenu, { duration: .3, queue: {position: 'end', scope: 'showfx'} });
              }
              
            } else {
              this.subMenu.setStyle({'display': 'block'});
                //this.subMenu.show();
            }
            
            this.calculatePosition();
        }
    },
    hideMenu: function() {
        obj = this; // bind to pass
        pe = setTimeout(function() { MenuControl.hide(obj); }, this.options.delay);
    },
    hide: function() {
        if (this.subMenu.visible())
            if (this.options.hideEffect) {
              if (Effect) {
                // Invoke the hide effect
                Effect[this.options.hideEffect](this.subMenu, { duration: 1, queue: {position: 'end', scope: 'hidefx'}});
              }
            } else {
                this.subMenu.setStyle({'display': 'none'});
                this.subMenu.setStyle({'left': 0 + 'px'});
                //this.subMenu.hide();
            }
            
        if (pe) {
             clearTimeout(pe);
        }
    },
    calculatePosition: function() {
        var contains = this.subMenu.immediateDescendants();
        var totalWid = 0;
        
        // Edge right & view width
        var er = null;
        var vw = null;
        
        // Which viewport to use?
        var vp = (!this.options.detectEdgeToElement) ? document.viewport : $(this.options.detectEdgeToElement);
        
        contains.each(
          function(container) {
            var w = container.getWidth();
            totalWid += w;
          }
        );
          
        this.subMenu.setStyle({'width': totalWid + 'px'});
        
        // Now compute box location & move if appropriate
        vw = vp.getWidth();
        
        er = this.calculateOffset() + totalWid;
        
        if (er > vw) {
          var d = er - vw;
          
          this.subMenu.setStyle({'left': null, 'right': '0px'});
        }
    },
    
    calculateOffset: function() {
      
      if (!this.options.detectEdgeToElement) {
        return this.subMenu.cumulativeOffset().left;
      }
      
      return (this.subMenu.cumulativeOffset().left - $(this.options.detectEdgeToElement).cumulativeOffset().left);
    
    }  

});

document.observe("dom:loaded", function() {
  // create menu items from the DOM structure
  $$('li.menuitem').each ( 
    function(element) {
        new MenuItem(element);
    }
  );
  
  $$('div.menuitem').each ( 
    function(element) {
        new MenuItem(element, {top: '18px', detectEdgeToElement: 'container'});
    }
  );
});
