var menu;


function findChildItems(e, idPrefix, items) {
 if (!e.childNodes || !e.childNodes.length) return;
 for (var i=0; i<e.childNodes.length; i++) {
  var node=e.childNodes[i];
  findChildItems(node, idPrefix, items);
  if (node.id && node.id.match("^"+idPrefix+".+")) items.push(node);
 }
}


function NvMenu(name, id, itemIdPrefix, popupMenuSuffix) {
 this.name=name;
 this.id=id;
 this.itemIdPrefix=itemIdPrefix;
 this.popupMenuSuffix=popupMenuSuffix;
 this.items=[];
 this.rootItems=[];
 this.activeItem=null;
 this.hideTimer;
 
 
 this.createMenuItem=function(parent, e) {
  var idx=this.items.length++;
  this.items[idx]=new NvMenuItem(this, idx, parent, e);
  return this.items[idx];
 };

 
 this.findMenuItems=function(parent, e) {
  var eItems=[], r=[];
  findChildItems(e, this.itemIdPrefix, eItems);
  for (var i=0; i<eItems.length; i++) r.push(this.createMenuItem(parent, eItems[i]));
  return r;
 };
 
 
 this.setActiveItem=function(item) {
  if (item) { this.cancelDeactivate(); item.setSelected(true); }
  if (item==this.activeItem) return;
  
  var ci=this.activeItem;
  while (ci && ci!=(item!=null?item.parent:null)) {
   ci.setSelected(false); ci=ci.parent;
  }
  this.activeItem=item;
 };
 
 
 this.deactivate=function() {
  this.hideTimer=setTimeout(this.name+".doDeactivate();", 1000);
 };
 
 
 this.doDeactivate=function() {
  this.hideTimer=null; this.setActiveItem(null);
 };
 
 
 this.cancelDeactivate=function() {
  if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer=null; }
 };
 
 
 this.rootItems=this.findMenuItems(null, document.getElementById(id));
}



function NvMenuItem(menu, idx, parent, e) {
 this.menu=menu;
 this.idx=idx;
 this.parent=parent;
 this.e=e;
 this.className=e.className;
 this.popup=null;
 this.items=[];
 
 
 this.getGlobalIdent=function() {
  return this.menu.name+".items["+this.idx+"]";
 };
 
 
 this.setSelected=function(b) {
  this.e.className=b?"selected":this.className;
  if (this.popup) this.popup.setVisible(b);
 };
 
 e.nvOwner=this;
 e.onmouseover=function() { this.nvOwner.menu.setActiveItem(this.nvOwner); };
 e.onmouseout=function() { this.nvOwner.menu.deactivate(); };
 
 var ePopup=document.getElementById(e.id+this.menu.popupMenuSuffix);
 if (ePopup) {
  this.popup=new NvPopupMenu(this, ePopup);
  this.items=this.menu.findMenuItems(this, ePopup);
 }
}



function NvPopupMenu(owner, e) {
 this.owner=owner;
 this.e=e;
 this.state=0;
 this.co=0;
 this.so=0.9;
 this.stateTimer=null;
 
 
 this.isVisible=function() {
  return (this.e.style.visibility=="visible" && this.state>=0);
 };
 
 
 this.setVisible=function(b) {
  if (b==this.isVisible()) return;
  if (b) this.updatePosition();
  this.cancelStateChange();
  this.state=b?1:-1;
  this.stateTimer=setInterval(this.owner.getGlobalIdent()+".popup.updateState();", 10);
 };
 
 
 this.updateState=function() {
  this.co+=0.05*this.state;
  if (this.co<0) this.co=0; if (this.co>1) this.co=1;
  this.e.style.visibility=this.co>0?"visible":"hidden";
  if (this.e.filters) this.e.filters.alpha.opacity=this.so*this.co*100;
   else this.e.style.opacity=this.so*this.co;
  if (this.co==0 || this.co==1) this.cancelStateChange();
 };
 
 
 this.cancelStateChange=function() {
  this.state=0;
  if (this.stateTimer) { clearInterval(this.stateTimer); this.stateTimer=null; } 
 };
 
 
 this.updatePosition=function() {
  if (this.owner.parent) this.positionRight(); else this.positionBelow();
 };
 
 
 this.positionRight=function() {
  var oe=this.owner.e;
  var pos=new NvPos(oe, false);
  this.e.style.left=(pos.left+oe.offsetParent.offsetWidth-5)+"px";
  this.e.style.top=pos.top+"px";
 };
 
 
 this.positionBelow=function() {
  var oe=this.owner.e;
  var pos=new NvPos(oe, true);
  this.e.style.left=pos.left+"px";
  this.e.style.top=(pos.top+oe.offsetHeight)+"px";
 };
}


function NvPos(e, incScroll) {
 if (incScroll) {
  this.left=-window.scrollX; this.top=-window.scrollY;
  if (isNaN(window.scrollX)) { this.left=-document.documentElement.scrollLeft; this.top=-document.documentElement.scrollTop; } // IE
 } else {
  this.left=0;
  this.top=0;
 }
 
 do { this.left+=e.offsetLeft; this.top+=e.offsetTop; e=e.offsetParent; } while (e);
}


function initMenu() {
 menu=new NvMenu("menu", "navMenu", "navItem", "popup");
 return true;
}