MenuItem = Class.create({
  initialize: function(name, sub_menu_item_list, onclick) {
    this.name = name;
    this.sub_menu_item_list = sub_menu_item_list;
    this.onclick = onclick;
  },
  
  menuDOM: function(menu) {
    var li = new Element('li', { id: this.item_id });
    var link = new Element('a', { href: '' }).update(this.name);
    li.appendChild(link);
    return li;
  },
  
  addMenuListeners: function(menu) {
    Event.observe(this.item_id, 'click', this.click.bindAsEventListener(this));
  },
  
  click: function(event) {
    event.preventDefault();
    if (this.onclick) {
      this.onclick();
      closeMenu(true);  
    } else if (this.sub_menu_item_list) {
      
    }
  }
})

MenuItem.normal = function(name, onclick) {
  return new MenuItem(name, null, onclick);
}

MenuItem.subMenu = function(item_id, name, sub_menu_item_list) {
  return new MenuItem(name, sub_menu_item_list, null);
}

Menu = Class.create({
  initialize: function(menu_id, small, items) {
    this.menu_id = menu_id;
    this.menu_button_id = "menu_button_" + menu_id;
    this.small = small;
    this.items = items;
    this.items.each(function(item, index) {
      item.item_id = menu_id + "_item_" + index;
    })
  },
  
  menuDOM: function() {
    var element = new Element('div', { id: this.menu_id, 'class': 'inline_menu',
                                       style: 'display:none' });
    var container = new Element('div', { 'class': 'menu_container' });
    element.appendChild(container);
    
    container.appendChild(new Element('div', { 'class': 'menu_header' }));
    var list_container = new Element('div', { 'class': 'menu_items_container' });
    container.appendChild(list_container);
    var list = new Element('ul');
    list_container.appendChild(list);
    
    this.items.each(function(item) {
      list.appendChild(item.menuDOM(this));
    }.bind(this));
    
    var footer = new Element('div', { 'class': 'menu_footer'});
    footer.appendChild(new Element('div', { 'class': 'left'}));
    element.appendChild(footer);
    
    return element;
  },
  
  addDOM: function() {
    var current_menu = $$('#popup_menu_container .inline_menu').first();
    if (current_menu) {
      $('popup_menu_container').replaceChild(this.menuDOM(), current_menu);
    } else {
      $('popup_menu_container').appendChild(this.menuDOM());
    }
  },
  
  buttonDOM: function(buttonText) {
    var element = new Element('a', { id: this.menu_button_id,
                                     'class': 'more_button', href: '' });
    var content = new Element('span', {id: this.menu_button_id + '_content'})
    content.update(buttonText)
    element.appendChild(content);
    return element;
  },
  
  updateButtonText: function(buttonText) {
    var element = $(this.menu_button_id + '_content');
    if (element) {
      element.update(buttonText);
    }
  },
  
  addMenuListeners: function() {
    this.items.each(function(item) {
      item.addMenuListeners(this);
    }.bind(this));
  },
  
  addButtonListener: function() {
    Event.observe('menu_button_' + this.menu_id, 'click', this.show.bindAsEventListener(this));
  },
  
  show: function(event) {
    event.preventDefault();
    if (!$(this.menu_id)) {
      this.addDOM();
      this.addMenuListeners();
    }
    showMenu(this.menu_id, 'menu_button_' + this.menu_id, this.small);
  }
});

var active_menu_id = null;
function showMenu(menu_id, position_element_id, small) {
  $(menu_id).style.visibility = 'hidden';
  $(menu_id).style.display = 'block';
  moveElement(menu_id, 0, 0);
  var width = $(menu_id).offsetWidth;
  var height = small ? 20 : 24
  closeMenu(false);
  var pos = position($(position_element_id));
  var x = pos[0] + 3;
  var y = pos[1] + height;
  var viewportWidth = document.viewport.getWidth() - 13;
  if (viewportWidth < 983) {
    viewportWidth = 983;
  }
  if (x + width > viewportWidth) {
    x = viewportWidth - width;
  }
  moveElement(menu_id, x, y);
  // $(menu_id).style.width = "" + width + "px";
  Element.show('popup_menu_overlay');
  if (isIE()) { toggleSelectVisibility(false); }
  // Effect.SlideDown(menu_id, {duration: 0.2});
  $(menu_id).style.visibility = 'visible';
  active_menu_id = menu_id;
}

var active_submenu_id = null;
function showSubmenu(submenu_id, parent_menu_element_id) {
  closeSubmenu(); 
  var x = position($(parent_menu_element_id))[0];
  var y = getScrolledY() + $(parent_menu_element_id).viewportOffset()[1];
  var width = $(parent_menu_element_id).offsetWidth;
  moveElement(submenu_id, x + width, y - 4);
  Element.show(submenu_id);
  active_submenu_id = submenu_id;
}

function closeSubmenu() {
  if (active_submenu_id != null) {
    Element.hide(active_submenu_id);
    active_submenu_id = null;
  }
}

function closeMenu(hideOverlay) {
  closeSubmenu();
  if (active_menu_id != null) {
    closeNamedMenu(active_menu_id);
  }
  if (hideOverlay) {
    hideMenuOverlay();
  }
}

function hideMenuOverlay() {
  Element.hide('popup_menu_overlay');
  actionMenuActive = false;
  $$('.menu_active').each(function(el) {hideObjectActions(el)});
  if (isIE()) { toggleSelectVisibility(true); }
}

function closeNamedMenu(menu_id) {
  inputs = $$('#' + menu_id + ' input');
  inputs.each(function(input) {
    Event.stopObserving(input, 'focus');
    Event.stopObserving(input, 'blur');
  });
  Element.hide(menu_id);
  if (active_menu_id == menu_id) {
    active_menu_id = null;
  }
}

function toggleMenu(button_id, url, menu_id, container_id) {
  if (active_menu_id != null) {
    if (active_menu_id == menu_id) {
      // menu is already active; close it
      closeMenu(true);
      return;
    } else {
      // another menu is active; close it and open this one
      closeMenu(false);
    }
  }
  new Ajax.Updater('popup_menu_container', url,
   {asynchronous:true, evalScripts:true,
      onComplete:function(request){
        hideActivityIndicator(button_id);
        showMenu(menu_id, button_id, $(container_id).hasClassName('tile'));
      },
      onLoading:function(request) {
        $(container_id).addClassName('menu_active');
        actionMenuActive = true;
        showActivityIndicator(button_id);
      }
   });
}

function toggleHiddenSelectMenu(button_id, menu_id, container_id) {
  toggleHiddenMenu(button_id, menu_id, container_id);
  activateSelectMenuListeners(menu_id, container_id);
  focusMenu(menu_id);
  Element.hide('popup_menu_overlay');
}

function toggleHiddenMenu(button_id, menu_id, container_id) {
  if (active_menu_id != null) {
    if (active_menu_id == menu_id) {
      // menu is already active; close it
      closeMenu(true);
      return;
    } else {
      // another menu is active; close it and open this one
      closeMenu(false);
    }
  }
  
  showMenu(menu_id, button_id, $(container_id).hasClassName('tile'));
  $(container_id).addClassName('menu_active');
  actionMenuActive = true;
}

function activateSelectMenuListeners(menu_id, container_id) {
  inputs = $$('#' + menu_id + ' input');
  inputs.each(function(input) {
    Event.observe(input, 'focus', function() {
      input.addClassName('focussed')
    });
    Event.observe(input, 'blur', function() {
      input.removeClassName('focussed');
      setTimeout(function() {
        blurMenu(menu_id, container_id);
      }, 100);
    });
  });
}

function focusMenu(menu_id) {
  $$('#' + menu_id + ' input').first().focus();
}

function blurMenu(menu_id, container_id) {
  if ($$('#' + menu_id + ' input.focussed').length == 0) {
    closeNamedMenu(menu_id);
    deactivateMenuContainer($(container_id));
    actionMenuActive = ($$('.menu_active').length > 0);
  }
}