﻿// 注册事件
function AddEventHandler(oTarget,sEventType,fHandler)
{
	if(oTarget.addEventListener)
	{
		//alert('eDo1');
		oTarget.addEventListener(sEventType,fHandler,false);
	}
	else if(oTarget.attachEvent)
	{
		//alert('eDo2');
		oTarget.attachEvent('on'+sEventType,fHandler);
	}
	else
	{
		//alert('eDo3');
		oTarget['on'+sEventType]=fHandler;
	}
}

//取元素相对于body的坐标
function ZB() 
{
 	this.left=0;this.top=0;this.width=0;this.height=0;
};
 
function GetZB(obj)
{
	var o=obj;
	var oLTWH=new ZB();
	oLTWH.width=o.offsetWidth;
	oLTWH.height=o.offsetHeight;
	oLTWH.left=o.offsetLeft;
	oLTWH.top=o.offsetTop;
	while(true)
    {
       o=o.offsetParent;
       if(o==(document.body&&null))break;
       oLTWH.left+=o.offsetLeft;
       oLTWH.top+=o.offsetTop;
    }
    return oLTWH;
}
function GetScrollLeft(){return document.documentElement.scrollLeft;}
function GetScrollTop(){return document.documentElement.scrollTop;}

function MenuNode(eleId)
{
	this.ctnId=eleId;
	this.depth=0;
	this.parent=null;
	this.childs=null;
	
	this.AddChild=function(node)
	{
		if(this.childs==null)
			this.childs=new Array();
		this.childs[this.childs.length]=node;
		node.parent=this;
		node.depth=this.depth+1;
	}
	this.Add=function(eleId)
	{
		var node=new MenuNode(eleId);
		this.AddChild(node);
	}
	this.GetChild=function(eleId)
	{
		if(!this.childs)
			return null;
		for(var i=0;i<this.childs.length;i++)
		{
			if(this.childs[i].ctnId==eleId)
				return this.childs[i];
		}
		return null;
	}
}

var _fMenus=new Array();
function FreeMenu(varName)
{
	this.objIdx=_fMenus.length;
	_fMenus[this.objIdx]=this;
	this.node=new MenuNode(null);
	this.ctns=new Array();
	this.inShow=false;
	this.hideHandler=null;
	this.ctnCss='';
	this.menuCss='';
	this.menuSelCss='';
	this.sign='&nbsp;&nbsp;&nbsp;&gt;';
	this.direction='d';
	this.hideDelay=3000;
	this.leftOffset=-5;
	this.topOffset=0;
	this.tempDepth=1;
	
	this.Add=function(eleId)
	{
		this.node.Add(eleId);
	}
	this.AddMenus=function(arrMenu)
	{
		for(var item in arrMenu)
		{
			var n=new MenuNode(item);
			this.node.AddChild(n);
			var ctn=document.getElementById(item);
			ctn.style.zIndex=10+this.tempDepth;
			
			eval('ctn.onmouseover=function(){_fMenus['+this.objIdx+'].OnOver();}');
			eval('ctn.onmouseout=function(){_fMenus['+this.objIdx+'].OnOut();}');
			if(arrMenu[item])
			{
				this.AppendMenu(n,arrMenu[item],ctn);
			}
		}
	}
	this.AppendMenu=function(node,arr,pCtn)
	{
		if(!arr)
			return;
		this.tempDepth++;
		//alert(arr.length);
		var i=0;
		for(var i=0;i<arr.length;i++)
		{
			var arr2=arr[i];
			//alert(arr2);
			var childItem=this.GetItemByPos(arr2,0);
			var n=new MenuNode(arr2?childItem:null);
			node.AddChild(n);
			var ctn=null;
			if(arr2)
				{ctn=document.getElementById(childItem);if(!ctn){alert(childItem+'不存在');return;}}
			var eleItem=pCtn.getElementsByTagName('li')[i];
			if(ctn)
			{
				ctn.style.zIndex=10+this.tempDepth;
				eval('ctn.onmouseover=function(){_fMenus['+this.objIdx+'].OnOver();}');
				eval('ctn.onmouseout=function(){_fMenus['+this.objIdx+'].OnOut();}');
				eval('eleItem.onmouseover=function(){_fMenus['+this.objIdx+'].OnOver();_fMenus['+this.objIdx+'].Show("'+childItem+'",this,'+this.tempDepth+');}');
				eval('eleItem.onmouseout=function(){_fMenus['+this.objIdx+'].OnItemOut(this);}');
				eleItem.getElementsByTagName('a')[0].innerHTML+=this.sign;
				//alert(eleItem.firstChild.innerHTML);
				this.AppendMenu(n,arr2[childItem],ctn);
			}
			else
			{
				eval('eleItem.onmouseover=function(){_fMenus['+this.objIdx+'].OnOver();_fMenus['+this.objIdx+'].Show(null,this,'+this.tempDepth+');}');
				eval('eleItem.onmouseout=function(){_fMenus['+this.objIdx+'].OnItemOut(this);}');
			}
			if(this.menuCss)
				eleItem.className=this.menuCss;
		}
		this.tempDepth--;
	}
	this.GetItemByPos=function(arr,idx)
	{
		var i=0;
		for(var item in arr)
		{
			if(i==idx)
				return item;
			i++;
		}
		return null;
	}
	this.Show=function(id,ele,depth)
	{
		if(!depth || depth<1)
			depth=1;
		if(!id)
		{
			this.Hide(depth);
			return;
		}
		var item=document.getElementById(id);
		if(!item)
			{//alert('不存在'+id+'菜单项'; 
					 return;};
		//eval('AddEventHandler(ele,"mouseover",function(){'+this.varName+'.OnOver();})');
		if(depth<=1)
			eval('ele.onmouseout=function(){_fMenus['+this.objIdx+'].OnOut();}');
		this.OnOver();
		this.Hide(depth);
		//定位坐标
		var zb=GetZB(ele);
		var ctn=item;
		//alert(zb.left);
		var minHeight=GetScrollTop();
		var maxHeight=minHeight+document.documentElement.clientHeight;
		var minLeft=GetScrollLeft();
		var maxLeft=minLeft+document.documentElement.clientWidth;
		var left,top;
		if(this.direction=='d' && depth==1)
		{
			if(zb.left+ctn.offsetWidth>maxLeft)
				left=maxLeft-ctn.offsetWidth;
			else
				left=zb.left;
			left=Math.max(minLeft,left);
			var _topOffset=this.topOffset;
			if(zb.top+zb.height+ctn.offsetHeight+_topOffset>maxHeight)
				top=maxHeight-ctn.offsetHeight-_topOffset;
			else
				top=zb.top+zb.height+_topOffset;
			top=Math.max(top,minHeight);
		}
		else
		{
			var _offset=depth>0?this.leftOffset:0;
			var _topOffset=this.topOffset;
			if(zb.left+zb.width+ctn.offsetWidth+_offset>maxLeft)
				left=zb.left-ctn.offsetWidth-_offset;
			else
				left=zb.left+zb.width+_offset;
			left=Math.max(minLeft,left);
			var _topOffset=this.topOffset;
			if(zb.top+ctn.offsetHeight+_topOffset>maxHeight)
				top=maxHeight-ctn.offsetHeight-_topOffset;
			else
				top=zb.top+_topOffset;
			top=Math.max(minHeight,top);
		}
		//alert('zb.top='+zb.top+'&ctn='+ctn);
		//alert('top='+top+'&left='+left);
		//alert(ele.id);
		//alert(depth);
		ctn.style.display='block';
		ctn.style.top=top+'px';
		ctn.style.left=left+'px';
		//alert(ctn.innerHTML);
		this.InShow=true;
		this.ctns[this.ctns.length]=ctn;
	}
	this.Hide=function(depth)
	{
		if(!depth)
			depth=0;
		//alert('length='+this.ctns.length);
		for(var i=depth-1;i<this.ctns.length;i++)
		{
			//alert('depth='+depth+'i='+i);
			if(this.ctns[i])
				this.ctns[i].style.display='none';
		}
		this.ctns.length=depth<=0?0:depth-1;
	}
	this.OnItemOver=function(ele)
	{
		if(this.menuSelCss)
			ele.className=this.menuSelCss;
	}
	this.OnItemOut=function(ele)
	{
		if(this.menuCss)
			ele.className=this.menuCss;
	}
	this.OnOver=function()
	{
		//alert('over');
		this.inShow=true;
		if(this.hideHandler)
		{
			clearTimeout(this.hideHandler);
			//this.hideHandler=null;
		}
	}
	this.OnOut=function()
	{
		//alert('out');
		this.inShow=false;
		this.hideHandler=setTimeout('if(!_fMenus['+this.objIdx+'].isShow) _fMenus['+this.objIdx+'].Hide();',this.hideDelay);
	}
}

var myMenu = new FreeMenu();//定义一个无限级菜单类实例
myMenu.ctnCss = 'tlmBox';//菜单项容器的样式名,默认为空
myMenu.menuCss = 'mOut';//未选中菜单项的样式名,默认为空
myMenu.menuSelCss = 'mOver';//选中菜单项的样式名,默认为空
myMenu.sign = '<span class="childs">&raquo;</span>';//当有子菜单项时在后面加上的文本,默认为>
myMenu.direction = 'd';//第一级菜单展示的位置,右边值为r,下边值为d,默认为d
myMenu.hideDelay = 2000;//鼠标移开菜单后菜单消失的延迟时间,单位为毫秒,默认为3000
myMenu.leftOffset = -5;//下一级菜单对应上一级菜单显示位置的左偏移量,单位为px,默认为-5
myMenu.topOffset = 0;//下一级菜单对应上一级菜单显示位置的上偏移量,单位为px,默认为0
myMenu.AddMenus(menus);//把菜单数据加入组件内
