var menuroot_images_off={};
var menuroot_images_on={};
//var menuroot_images1={};
var cached_images_off={};
var cached_images_on={};
var loadedImagesCount=0;

isIE=ie();

// first entry must not be a separator
function PopupMenu(menu_name,opposite,opposite_align,style,z,start_offset,close_delay,resize,match_image_width)
{
	this.isReady=false;
	this.menuName="menu"+menu_name;
	this.oppositeX=opposite[0];
	this.oppositeY=opposite[1];
	this.oppositeAlignX=opposite_align[0];
	this.oppositeAlignY=opposite_align[1];
	this.menuHandle=null;
	this.saveState=false;
	this.closeTimer=null;
	this.closeBusy=false;
	this.style=style;
	this.detectEdges=true;
	this.updateSize=resize ? true : false;
	this.z=z;
	this.closeDelay=close_delay ? close_delay : 500;
	this.startOffset=start_offset;
//	this.snapToEntry
	this.hiddenControls=[];
	this.rootRollover=true;
	this.matchImageWidth=match_image_width ? true : false;
	this.debug=false;
}


PopupMenu.prototype.Initialize=function()
{
	if(!document.getElementById)
		return;
// calculate width for each submenu using specified containing element like <span> recognized by its classname
	this.menuHandle=document.getElementById(this.menuName);
//	this.menuHandle.style.zIndex=-10;
//	this.menuHandle.style.visibility='hidden';
//	this.menuHandle.style.position='relative';
	this.menuHandle.style.display='block';	

	if(this.debug)
	{
		this.console=document.createElement('div');
		if(!isIE)
			this.console.setAttribute('style','position:absolute;left:0;bottom:0;width:300px;height:250px;overflow:auto;background-color:#0a0;color:#000;');
		else
		{		
			this.console.setAttribute('style');
			this.console.style.position='absolute';
			this.console.style.left='0';
			this.console.style.bottom='0';
			this.console.style.width='300px';
			this.console.style.height='250px';
			this.console.style.overflow='auto';
			this.console.style.backgroundColor='#0a0';
			this.console.style.color='#000';		
		}
		document.getElementsByTagName('body')[0].appendChild(this.console);
		this.console.innerHTML='<div style="background-color:#00a;color:#fff;">Output</div><div><input type="button" value="Clear" onclick="this.parentNode.nextSibling.innerHTML=\'\';"></div><div></div>';
	}	
	
//	var k=0;
//	var submenus=[this.menuHandle];
//	var sm=document.getElementById(this.menuName+'_sm_'+k);
//	while(sm!=null)
//	{
//		submenus[submenus.length]=sm;
//		sm.style.position='absolute';
//		sm.style.visibility='hidden';
//		sm.style.zIndex=this.z;
//
//		k++;	
//		var sm=document.getElementById(this.menuName+'_sm_'+k);
//	}
	var submenus=[this.menuHandle];
	var sm=this.menuHandle.getElementsByTagName('div');
	for(var i=0;i<sm.length;i++)
	{
		if(sm[i].className!=this.menuName+'sm')
			continue;
		submenus[submenus.length]=sm[i];
		sm[i].style.position='absolute';
		sm[i].style.left='0px';
		sm[i].style.top='0px';
		sm[i].style.visibility='hidden';
		sm[i].style.zIndex=this.z;
	}
	for(var j=0;j<submenus.length;j++)
	{	
	//	this.write(submenus[j].id);
		this.UpdateSize(submenus[j]); 
		submenus[j].onmouseout=this.HideAllMenus;
		submenus[j].onmouseover=this.SetSubmenu;
	}
	for(var i=0;i<sm.length;i++)
	{	
		if(sm[i].parentNode.className!=this.menuName+'sm')
			continue;
//		this.write('submenu');
		if(this.style=='horizontal' || (sm[i].parentNode==this.menuHandle && this.style=='hybrid'))
		{	
			sm[i].style.cssFloat='left'; // mozilla
			sm[i].style.styleFloat='left'; // ie
		}	
		sm[i].menuObject=this;
		sm[i].onmouseover=this.ShowSubmenu;
		sm[i].onclick=this.ExecuteEntry;
	}	

//	k=0;	
//	var entry=document.getElementById(this.menuName+'_e_'+k);
//	while(entry!=null)
//	{	
//		if(this.style=='horizontal' || (entry.parentNode==this.menuHandle && this.style=='hybrid'))
//		{	
//			entry.style.cssFloat='left'; // mozilla
//			entry.style.styleFloat='left'; // ie
//		}	
//		entry.menuObject=this;
//		entry.onmouseover=this.ShowSubmenu;
//		entry.onclick=this.ExecuteEntry;
//		k++;	
//		entry=document.getElementById(this.menuName+'_e_'+k);
//	}	


	this.currentMenu=this.lastMenu=this.menuHandle;
// assumption that this is not a text node	and not a menu separator
	this.currentEntry=this.menuHandle.lastChild;
	
//	this.SetHighlightMenuBranch();
	this.menuHandle.style.visibility='visible';

//	if(isIE)
//		this.menuHandle.style.position='static';
	this.isReady=true;
}

PopupMenu.prototype.write=function(message)
{
	if(!this.debug)
		return;
	var div=document.createElement('div');
	div.innerHTML=message+'<hr>';
	this.console.lastChild.appendChild(div);
}

PopupMenu.prototype.SetSubmenu=function(e)
{

	var ev=new EventWrapper(e);

	var mh=this.firstChild.menuObject;
	if(!mh.isReady)
		return;
//	if(mh.menuHandle.style.position!='relative')
//		mh.menuHandle.style.position='relative';

	mh.currentMenu=this; // set this menu as active in case there is padding or margins between entries and submenu
	ev.StopPropagation();
}

PopupMenu.prototype.HideAllMenus=function(e)
{
	var mh=this.firstChild.menuObject;
	if(!mh.isReady)
		return;
	

	var ev=new EventWrapper(e);
	if(ev.toElement!=this  && !findDescendant(this,ev.toElement,mh.menuName+'sm'))
	{
		mh.currentMenu=mh.menuHandle; // set root menu to be current menu
		//debug.dump('scheduling close');
		if(!mh.closeTimer) // should be tested inside: menu overlap each other
			mh.closeTimer=setTimeout(mh.menuName+'.HideSubmenus(false)',mh.closeDelay);	
	}
	
	ev.StopPropagation();
}

PopupMenu.prototype.HideSubmenus=function(force)
{
	if(!this.closeBusy) // synchronize between forced and by timeout close
	{	
		this.closeBusy=true;
		clearTimeout(this.closeTimer);
		var cur = this.lastMenu;
		var defentry=this.currentEntry;
		var found=null;
		while(cur!=this.currentMenu)
		{
			cur.style.visibility='hidden';
//			cur.style.left='0px';
//			cur.style.top='0px';
			if(!force && !found && findChild(cur,this.currentEntry))
				found=this.currentEntry;
			defentry=cur.parentNode;
			cur=defentry.parentNode;
		}
		if(!force) // closed by timeout
			this.lastMenu=cur;
		
		if(!force && !found && findChild(cur,this.currentEntry))
			found=this.currentEntry;
			
		if(!force && this.currentEntry==found)
		{
			this.RemoveHighlightMenuBranch(defentry); // ensure to erase highlight
			currentEntry=defentry; // set current entry to be the entry of last closed submenu
//			this.SetHighlightMenuBranch();
		}
		if(this.currentMenu==this.menuHandle)
		{
			for(var i=0;i<this.hiddenControls.length;i++)
				this.hiddenControls	[i].style.visibility="visible";
			this.hiddenControls	=[];
		}
//		if(!force && isIE)
//			this.menuHandle.style.position='static';
		this.closeTimer=null;
		this.closeBusy=false;
	}	
}

PopupMenu.prototype.SetHighlightMenuBranch=function()
{
	var cur=this.currentEntry;
	var root=this.menuHandle;
	var re=new RegExp('(\s*)('+this.menuName+'me(p|l|r))(\s*)','i');
	while(cur.parentNode!=root)
	{
		cur.className=cur.className.replace(re,'$1$2c$4');
	//	if(this.updateSize)
	//		this.UpdateSize(cur.parentNode);
	//	this.CalculateSubmenuPosition(cur);
		cur=cur.parentNode.parentNode;
	}
	cur.className=cur.className.replace(re,'$1$2c$4');
	if(cur.parentNode==this.menuHandle && this.rootRollover)
	{
		if(cached_images_on[cur.id].complete)
			cur.getElementsByTagName("img")[0].src=cached_images_on[cur.id].src;
	}
//	if(this.updateSize)
//		this.UpdateSize(cur.parentNode);
//	this.CalculateSubmenuPosition(cur);
}

PopupMenu.prototype.RemoveHighlightMenuBranch=function(cur)
{
	var prev=this.currentEntry;
	var stopmenu=this.menuHandle;
	var re=new RegExp('(\s*)('+this.menuName+'me(p|l|r))c(\s*)','i');

	while(prev.parentNode!=stopmenu)
	{
		prev.className=prev.className.replace(re,'$1$2$4');
	//	if(this.updateSize)
	//		this.UpdateSize(prev.parentNode);
	//	this.CalculateSubmenuPosition(prev);
		prev=prev.parentNode.parentNode;
	}
	prev.className=prev.className.replace(re,'$1$2$4');
	if(prev.parentNode==this.menuHandle && this.rootRollover)
	{																			
			//alert(cached_images_off[prev.id].src);
		if(cached_images_off[prev.id].complete)
			prev.getElementsByTagName("img")[0].src=cached_images_off[prev.id].src;
	}
//	if(this.updateSize)
//		this.UpdateSize(prev.parentNode);
//	this.CalculateSubmenuPosition(prev);
	window.status='';

}

PopupMenu.prototype.ShowSubmenu=function(e)
{
	var mh=this.menuObject;
	
	if(!mh.isReady)
		return;
	
//	if(isIE && mh.menuHandle.style.position!='relative')
//		mh.menuHandle.style.position='relative';

	var ev=new EventWrapper(e);
	
//	if(this.className=='menuentrydisabled')
//		return;
	
// this.firstChild is wrapper for entry content
	//ev.StopPropagation();
	if(ev.fromElement==this || findDescendant(this.firstChild,ev.fromElement))
	{
		ev.StopPropagation();
		return;
	}

	mh.ProccessMenuEntry(this);
}

PopupMenu.prototype.ProccessMenuEntry=function(entry)
{
	var p=entry.parentNode; // submenu where this entry is
	var submenu=entry.childNodes.length>1 ? entry.lastChild : null; // nested submenu
	this.currentMenu=p;
	this.RemoveHighlightMenuBranch(entry);
	this.currentEntry=entry;
	this.SetHighlightMenuBranch();
	this.HideSubmenus(true); // ensure only single branch is visible 
	var anchors=this.currentEntry.firstChild.getElementsByTagName("a");
	if(anchors)
	{
		window.status=anchors[0].href;
	}
	if(submenu && submenu.style.visibility=="hidden")
	{	
		this.CalculateSubmenuPosition(this.currentEntry);
		this.HideWindowControls(submenu);
		this.lastMenu=submenu;
		submenu.style.visibility="visible";
	}
}

PopupMenu.prototype.CalculateSubmenuPosition=function(entry)
{	
	var windowsize=windowInnerSize();
	
	p=entry.parentNode;
	submenu=entry.lastChild;
	var menu_offs=findAbsoluteOffset(p);
	var entry_offs=findAbsoluteOffset(entry);
	if(p==this.menuHandle)
	{
		
	}
	// coordinate origin begins where padding ends
	var blw=!isNaN(getActualStyle(entry,"border-left-width")) ? getActualStyle(entry,"border-left-width") : 0;
	var btw=!isNaN(getActualStyle(entry,"border-top-width")) ? getActualStyle(entry,"border-top-width") : 0;
	var bbw=!isNaN(getActualStyle(entry,"border-bottom-width")) ? getActualStyle(entry,"border-bottom-width") : 0;
	
	if(this.style=='vertical' || (this.style=='hybrid' && p!=this.menuHandle))
	{	
		var top=this.oppositeAlignX ? (p!=this.menuHandle ? entry.offsetTop : entry_offs[1])+entry.offsetHeight-submenu.offsetHeight : (p!=this.menuHandle ? entry.offsetTop : entry_offs[1]);
		var left=this.oppositeX ? (p!=this.menuHandle ? 0:menu_offs[0])-(submenu.offsetWidth+blw)-1: (p!=this.menuHandle ? 0 : menu_offs[0]) + p.offsetWidth-blw-1;
	}
	else
	{
		var top=this.oppositeY && this.style!='hybrid' ? (p!=this.menuHandle ? 0:menu_offs[1])-(submenu.offsetHeight+btw)-1 : (p!=this.menuHandle ? 0:menu_offs[1])+p.offsetHeight-btw;
		var left=this.oppositeAlignY ? (p!=this.menuHandle ? entry.offsetLeft : entry_offs[0])+entry.offsetWidth-submenu.offsetWidth : (p!=this.menuHandle ? entry.offsetLeft : entry_offs[0])-1;		
	}
	left+=this.oppositeAlignX ? -this.startOffset[0] : this.startOffset[0];
	top+=this.oppositeAlignY ? -this.startOffset[1] : this.startOffset[1];
	submenu.style.left=left+'px';
	submenu.style.top=top+'px';
	var submenu_offs=findAbsoluteOffset(submenu);
	if(this.detectEdges)
	{		
		var dy=this.oppositeY ? entry_offs[1]-submenu.offsetHeight : windowsize[1]-(submenu_offs[1]+submenu.offsetHeight);
		if(dy<0)
		{		
//			this.write('here');
			top=this.oppositeY ? top-dy+btw : top+dy-bbw;
		}	
		var dx=this.oppositeX ? entry_offs[0]-submenu.offsetWidth : windowsize[0]-(submenu_offs[0]+submenu.offsetWidth);
		if(dx<0)
		{		
			left=this.oppositeX ? left-dx : left+dx;
		}	
				
	}			
		submenu.style.left=left+'px';
		submenu.style.top=top+'px';
}	

PopupMenu.prototype.HideWindowControls=function(submenu)
{
	var inputs=document.getElementsByTagName("input");
	var textareas=document.getElementsByTagName("textarea");
	var selects=document.getElementsByTagName("select");

	
	var submenu_coords=findAbsoluteOffset(submenu);
	var min_x=submenu_coords[0];
	var min_y=submenu_coords[1];
	var max_x=min_x+submenu.offsetWidth;
	var max_y=min_y+submenu.offsetHeight;
	var controls=[];
	if(inputs)
		controls[controls.length]=inputs;
	if(textareas)
		controls[controls.length]=textareas;
	if(selects)
		controls[controls.length]=selects;

	
	for(var j=0;j<controls.length;j++)
	{
		var ctrl=controls[j];
		for(var i=0;i<ctrl.length;i++)
		{
			if(ctrl[i].type=="hidden" || getActualStyle(ctrl[i],"visibility")=="hidden")
				continue;
			var coords=findAbsoluteOffset(ctrl[i]);
			var minx=coords[0];
			var miny=coords[1];
			var maxx=minx+ctrl[i].offsetWidth;
			var maxy=miny+ctrl[i].offsetHeight;
			var c1=min_x<=minx && minx<=max_x && min_y<=miny && miny<=max_y
			var c2=min_x<=minx && minx<=max_x && min_y<=maxy && maxy<=max_y
			var c3=min_x<=maxx && maxx<=max_x && min_y<=miny && miny<=max_y
			var c4=min_x<=maxx && maxx<=max_x && min_y<=maxy && maxy<=max_y
			
			//alert(minx+','+miny+','+maxx+','+maxy+'\n'+min_x+','+min_y+','+max_x+','+max_y);
			//alert("w="+ctrl[i].offsetWidth+" h="+ctrl[i].offsetHeight);
			if(c1 || c2 || c3 || c4)
			{
				this.hiddenControls	[this.hiddenControls.length]=ctrl[i];
				ctrl[i].style.visibility="hidden";
			}
		}
	}
}

PopupMenu.prototype.UpdateSize=function(submenu)
{
	var p=submenu.firstChild;
	var blw=!isNaN(getActualStyle(p,"border-left-width")) ? getActualStyle(p,"border-left-width") : 0;
	var brw=!isNaN(getActualStyle(p,"border-right-width")) ? getActualStyle(p,"border-right-width") : 0;
	var pl=!isNaN(getActualStyle(p,"padding-left")) ? getActualStyle(p,"padding-left") : 0;
	var pr=!isNaN(getActualStyle(p,"padding-right")) ? getActualStyle(p,"padding-right") : 0;
	var ml=!isNaN(getActualStyle(p,"margin-left")) ? getActualStyle(p,"margin-left") : 0;
	var mr=!isNaN(getActualStyle(p,"margin-right")) ? getActualStyle(p,"margin-right") : 0;
	var m_max=Math.max(ml,mr);

	var btw=!isNaN(getActualStyle(p,"border-top-width")) ? getActualStyle(p,"border-top-width") : 0;
	var bbw=!isNaN(getActualStyle(p,"border-bottom-width")) ? getActualStyle(p,"border-bottom-width") : 0;
	var pt=!isNaN(getActualStyle(p,"padding-top")) ? getActualStyle(p,"padding-top") : 0;
	var pb=!isNaN(getActualStyle(p,"padding-bottom")) ? getActualStyle(p,"padding-bottom") : 0;
	var mt=!isNaN(getActualStyle(p,"margin-top")) ? getActualStyle(p,"margin-top") : 0;
	var mb=!isNaN(getActualStyle(p,"margin-bottom")) ? getActualStyle(p,"margin-bottom") : 0;

	var entry=submenu.firstChild;
	var max=0;
	if(this.style=='horizontal' || (submenu==this.menuHandle && this.style=='hybrid'))
	{
		var width=0;
		while(entry)
		{
			//var size=document.getElementById(this.menuName+'_s_'+entry.id.substr(entry.id.lastIndexOf('_')+1));
			var size=entry.firstChild;
			//this.write(entry.firstChild.className);
			width+=size.offsetWidth;
			entry.style.width=size.offsetWidth+'px'; // floats require specific width
			if(size.offsetHeight>max)
				max=size.offsetHeight;
			entry=entry.nextSibling;
		}
		var moreWidth=(blw+brw)*submenu.childNodes.length+(pl+pr)*submenu.childNodes.length+(ml+mr)*submenu.childNodes.length+(isIE ? mr : 0);
//		var moreWidth=0;//(ml+mr)*submenu.childNodes.length+(isIE ? 0 : 0);
		var moreHeight=btw+bbw+pt+pb+mt+mb;
		submenu.style.height=(max+moreHeight)+'px';
		submenu.style.width=(width+moreWidth)+'px';	
		
	}
	else
	{		
		while(entry)
		{
		//	var size=document.getElementById(this.menuName+'_s_'+entry.id.substr(entry.id.lastIndexOf('_')+1));
			var size=entry.firstChild;
		//	this.write(entry.firstChild.className);
			if(size.offsetWidth>max)
				max=size.offsetWidth;
			entry=entry.nextSibling;
		}
		var more=blw+brw+pl+pr+ml+mr;
		if(this.rootRollover && this.matchImageWidth && submenu.parentNode.parentNode==this.menuHandle && submenu.parentNode.offsetWidth>max+more)
		{
			max=submenu.parentNode.offsetWidth;
			more=0;
		}	
		submenu.style.width=(max+more)+'px';
		
		if(isIE)
		{
			var entry=submenu.firstChild;
		
			while(entry)
			{
				entry.style.width=(max+more)+'px'; 
				entry=entry.nextSibling;
			}
		}
	}
}

PopupMenu.prototype.ExecuteEntry=function(e)
{
	var mh=this.menuObject;
	
	if(!mh.isReady)
		return;

	var ev=new EventWrapper(e);
	ev.StopPropagation();
	
	mh.currentMenu=mh.menuHandle; // set root menu to be current menu
	mh.HideSubmenus(true);
	var anchors=this.firstChild.getElementsByTagName("a");
	if(anchors && anchors[0].href.indexOf("javascript:")!=0)
	{
		if(anchors[0].target.length>0)
			window.open(anchors[0].href,anchors[0].target)
		else
			document.location=anchors[0].href;
		ev.PreventDefault();
	}
	
}

	