// Version 1.1: 增加每個level可有不同寬度之功能

function PopupMenu_MouseDownHandler() {
	re=/(@@@menu)(_)(.+)(_item_)(.+)/g;			// e.g., @@@menumenu1_item_2
	r=window.event.srcElement.id.match(re);
	if (r==null) {
		for (name in __popupmenus) {
			__popupmenus[name].HideAll();
		}
		// Added 2002/6/17
		for (name in __popupmenus) {
			if (__popupmenus[name].toggleShowState=="hidden") continue;
			__popupmenus[name].ToggleShow();
		}	
		// end of add 2002/6/17						
	} else {
		info=new Array();
		info=window.event.srcElement.id.split("_");
		__popupmenus[info[1]].onMouseDown(info[3]);
	}	
}

function PopupMenu_MouseOverHandler() {
	re=/(@@@menu)(_)(.+)(_item_)(.+)/g;			// e.g., @@@menu_menu1_item_2
	r1=window.event.srcElement.id.match(re);

	re=/(@@@menu)(_)(.+)(_arrow_)(.+)/g;			// e.g., @@@menu_menu1_arrow_2
	r2=window.event.srcElement.id.match(re);
	
	if (r1!=null || r2!=null) {
		//window.status=window.event.srcElement.id;
		info=new Array();
		info=window.event.srcElement.id.split("_");

		for (name in __popupmenus) {
			if (name==info[1]) continue;
			__popupmenus[name].HideAll();
		}			

		id=info[3];
		__popupmenus[info[1]].onMouseOver(id);
		
	}
}

function PopupMenu_MouseOutHandler() {
	re=/(@@@menu)(_)(.+)(_item_)(.+)/g;			// e.g., @@@menu_menu1_item_2
	r1=window.event.srcElement.id.match(re);

	re=/(@@@menu)(_)(.+)(_arrow_)(.+)/g;			// e.g., @@@menu_menu1_arrow_2
	r2=window.event.srcElement.id.match(re);
	
	if (r1!=null || r2!=null) {
		//window.status=window.event.srcElement.id;
		info=new Array();
		info=window.event.srcElement.id.split("_");

		/*for (name in __popupmenus) {
			if (name==info[1]) continue;
			__popupmenus[name].HideAll();
		}*/		

		id=info[3];
		__popupmenus[info[1]].onMouseOut(id);
		
	}
}

function PopupMenu_onMouseOver(id) {
	currLevel=this.GetLevel(id);
	// Hide deeper level menus			
	for (level in this.submenu_HTML) {
		if (level < currLevel) continue;
		for (i in this.submenu_HTML[level]) {
			if (this.menu_Display[i]=="visible") {
				document.all("@@@menu_"+this.name+"_"+i).style.visibility="hidden";				
				this.menu_Display[i]="hidden";
			}	
		}
	}
		
	if (this.menu_HTML[id]!=null) {
		document.all("@@@menu_"+this.name+"_"+id).style.visibility="visible";
		this.menu_Display[id]="visible";
	}
	
	if (document.all("@@@@menu_"+this.name+"_item_"+id)!=null)
		document.all("@@@@menu_"+this.name+"_item_"+id).bgColor="#FFE034";
		
}

function PopupMenu_onMouseOut(id) {
	document.all("@@@@menu_"+this.name+"_item_"+id).bgColor="#cccccc";
}

function PopupMenu_onMouseDown(id) {
	alert(id);
}

function PopupMenu_HideAll() {
		try {
			document.all(this.renderArea).style.display="none";
		} catch (e) {
		}
	for (level in this.submenu_HTML) {
		if (level < this.HideAllBelowThisLevel) continue;
		for (id in this.submenu_HTML[level]) {
			if (this.menu_Display[id]=="visible") {
				document.all("@@@menu_"+this.name+"_"+id).style.visibility="hidden";								
				this.menu_Display[id]="hidden";
			}	
		}
	}	
}

function PopupMenu_ToggleShow() {
	if (this.toggleShowState=="visible") {
		try {
			document.all(this.renderArea).style.display="none";
		} catch (e) {
		}
		//document.all(this.renderArea).style.zIndex="-1";
		// Hide all
		this.toggleShowState="hidden"
		for (level in this.submenu_HTML) {
			for (id in this.submenu_HTML[level]) {
				document.all("@@@menu_"+this.name+"_"+id).style.visibility="hidden";				
				this.menu_Display[id]="hidden";
			}
		}
	} else {
		this.toggleShowState="visible"
		// Show root
		id="0";
		document.all(this.renderArea).style.display="";		
		//document.all(this.renderArea).style.zIndex="300";
		//document.all("@@@menu_"+this.name+"_"+id).style.display="";
		document.all("@@@menu_"+this.name+"_"+id).style.visibility="visible";				
		//this.menu_Display[id]="visible";
	}
}

function PopupMenu_AddRoot(str) {
	index=this.treeinfo.length;
	this.treeinfo[index]=str;
	this.parent[index]=index;
	this.id++;
	return 0;
}

function PopupMenu_EditCategory(id, str, content) {
	this.treeinfo[id]=str;

	/*if (str.length > this.abbr_length) {
		this.abbreviate[id]=str.substring(0, this.abbr_length)+"...";
	} else {
		this.abbreviate[id]=str;
	}*/
	if (this.doAbbreviate) {
		numAscii=0;
		this.abbreviate[id]="";
		for (i=0; i<str.length; i++) {
			this.abbreviate[id]+=str.substring(i,i+1);
			if (str.charCodeAt(1) > 128) {
				numAscii+=2;
			}	else {
				numAscii++;
			}	
			if (numAscii >= this.abbr_length) {
				this.abbreviate[id]+="...";
				break;
			}	
		}
	} else {
		this.abbreviate[id]=str;
	}	

	if (arguments.length>=4) {
		this.attr[id].bgcolor=arguments[3];
	}
		
	this.content[id]=content;
}

function PopupMenu_AddCategory(parent_id, str, content) {
	newid=this.id;
	str=="" ? str="Category "+newid : null;
	this.id++;
	if (this.tree[parent_id]==null) {
		this.tree[parent_id]=new Array();
	}
	this.tree[parent_id][this.tree[parent_id].length]=newid;
	this.treeinfo[newid]=str;

	// 計算str相當在螢幕上所佔的英文字數(一個中文佔2個英文字空間)
	if (this.doAbbreviate) {
		numAscii=0;
		this.abbreviate[newid]="";
		for (i=0; i<str.length; i++) {
			this.abbreviate[newid]+=str.substring(i,i+1);
			if (str.charCodeAt(1) > 128) {
				numAscii+=2;
			}	else {
				numAscii++;
			}	
			if (numAscii >= this.abbr_length) {
				this.abbreviate[newid]+="...";
				break;
			}	
		}
	} else {
		this.abbreviate[newid]=str;
	}	
	/*strLen=numAscii+numNonAscii*2;
	if (strLen > this.abbr_length) {
		this.abbreviate[newid]=str.substring(0, this.abbr_length)+"...";
	} else {
		this.abbreviate[newid]=str;
	}*/
	//alert(str+"\n"+strLen+"\n"+this.abbreviate[newid]);
	
	this.content[newid]=content;

	if (this.rank[parent_id]==null) {
		this.rank[parent_id]=new Array();
	}
	
	this.attr[newid]=new Object();
	if (arguments.length>=4) {
		this.attr[newid].bgcolor=arguments[3];
	}
	
	this.type[newid]="Category";
			
	this.rank[parent_id][this.rank[parent_id].length]=newid;
	this.parent[newid]=parent_id;
	return newid;		
}

function PopupMenu_AddLink(parent_id, str, content) {
	newid=this.id;
	str=="" ? str="Link "+newid : null;
	this.id++;
	if (this.tree[parent_id]==null) {
		this.tree[parent_id]=new Array();
	}
	this.tree[parent_id][this.tree[parent_id].length]=newid;
	this.treeinfo[newid]=str;
	this.content[newid]=content;

	if (this.rank[parent_id]==null) {
		this.rank[parent_id]=new Array();
	}
	
	this.attr[newid]=new Object();
	this.type[newid]="Link";
			
	this.rank[parent_id][this.rank[parent_id].length]=newid;
	this.parent[newid]=parent_id;
	return newid;		
}

function PopupMenu_Write(id) {
	if (this.treeinfo.length==0) {
		alert("No root defined!");
		return;
	}

	// render submenu
	result="";
	level=this.GetLevel(id);

	width_bak=this.width;
	this.width=this.GetLevelWidth(level);
	
	result="<table id=\"@@@menu_"+this.name+"_"+id+"\" border=\"1\" width=\""+this.width+"\" style=\"z-index:"+level+";cursor:hand;position:relative;left:0px;top:0px;visibility:visible;\" bgcolor=\""+this.bgcolor+"\" cellspacing=0 cellpadding=0 bordercolorlight=\"black\" bordercolordark=\"white\">";
	item_num=0;
	if (this.tree[id]!=null) {
		if (this.tree[id].length>0) {
			for (i in this.rank[id]) {
				child_id=this.rank[id][i];
				this.attr[child_id].bgcolor!=null ? bgcolor=this.attr[child_id].bgcolor : bgcolor=this.bgcolor;
				result+="\t<tr id=\"@@@@menu_"+this.name+"_item_"+child_id+"\" bgcolor=\""+bgcolor+"\">\n";
				if (this.tree[child_id]!=null) {
					if (this.tree[child_id].length!=0) {
						td="<table cellspacing=0 cellpadding=0 width=\"100%\" border=\"0\" style=\"cursor:hand;z-index"+(level+1)+"\"><tr><td width=\""+(this.width-13)+"\" id=\"@@@menu_"+this.name+"_item_"+child_id+"\" align=\"left\">"+this.abbreviate[child_id]+"</td><td width=\"13\" id=\"@@@menu_"+this.name+"_arrow_"+child_id+"\" align=\"right\">&nbsp;<img src=\""+this.root_dir+"clientside/popupmenu/rarrow.gif\"></td></tr></table>";
						result+="\t\t<td height=\""+this.height+"\">"+td+"</td>\n";
					} else {
						td="<table cellspacing=0 cellpadding=0 width=\"100%\" border=\"0\" style=\"cursor:hand;z-index"+(level+1)+"\"><tr><td width=\""+(this.width-13)+"\" id=\"@@@menu_"+this.name+"_item_"+child_id+"\" align=\"left\">"+this.abbreviate[child_id]+"</td><td width=\"13\" id=\"@@@menu_"+this.name+"_arrow_"+child_id+"\" align=\"right\">&nbsp;</td></tr></table>";
						result+="\t\t<td height=\""+this.height+"\">"+td+"</td>\n";
					} 
				} else {
					td="<table cellspacing=0 cellpadding=0 width=\"100%\" border=\"0\" style=\"cursor:hand;z-index"+(level+1)+"\"><tr><td width=\""+(this.width-13)+"\" id=\"@@@menu_"+this.name+"_item_"+child_id+"\" align=\"left\">"+this.abbreviate[child_id]+"</td><td width=\"13\" id=\"@@@menu_"+this.name+"_arrow_"+child_id+"\" align=\"right\">&nbsp;</td></tr></table>";
					result+="\t\t<td height=\""+this.height+"\">"+td+"</td>\n";
				}
				result+="\t</tr>\n";
				item_num++;
			}	
		}
	}	
	result+="</table>";
	if (this.submenu_HTML[level]==null) {
		this.submenu_HTML[level]=new Array();
	}
	this.submenu_HTML[level][id]=new Object();
	this.submenu_HTML[level][id].html=result;
	this.submenu_HTML[level][id].item_num=item_num;

	this.menu_HTML[id]=result;
	this.menu_Display[id]="visible";
	//document.all(this.renderArea).innerHTML+=result;
	
	this.width=width_bak;

	// traverse submenus
	if (this.tree[id]!=null) {
		if (this.tree[id].length>0) {
			// 按rank traverse 所有child，若其為category且有child，則recursive traverse
			for (i in this.rank[id]) {
				child_id=this.rank[id][i];
				//alert(child_id+"="+this.type[child_id]);
				if (this.type[child_id]=="Category") 
					if (this.tree[child_id]!=null) 
						if (this.tree[child_id].length>0) 
							this.Write(child_id);
			}	
		}
	}
}

function PopupMenu_Arrange() {
	accu_y=-parseInt(this.submenu_HTML[0][0].item_num);
	base_y=parseInt(this.submenu_HTML[0][0].item_num);
	counter=0;

	//document.all(this.renderArea).style.display="";
	document.all(this.renderArea).innerHTML="";
	for (level in this.submenu_HTML) {
		for (id in this.submenu_HTML[level]) {
			// 按照Level及順序將每個menu依序排列在rendering area
			document.all(this.renderArea).innerHTML+=this.submenu_HTML[level][id].html;
			// X軸offset
			//document.all("@@@menu_"+this.name+"_"+id).style.left=(this.width-this.menu_overlap_x)*level;
			document.all("@@@menu_"+this.name+"_"+id).style.left=this.GetLevelAccumWidth(level)-this.menu_overlap_x*level;
			
			// 將每個menu垂直對齊(counter*2為考慮menu之上下border高度:1px)
			offset_y=0-(parseInt(this.height)*(accu_y+base_y))-counter*2;
			
			// 將每個menu垂直向下拉至正確位置
			offset_y=offset_y+parseInt(this.GetAccumRank(id))*parseInt(this.height);
			document.all("@@@menu_"+this.name+"_"+id).style.top=offset_y;
			counter++;
			//if (id!=0) {
			if (level >= this.HideAllBelowThisLevel) {
				document.all("@@@menu_"+this.name+"_"+id).style.visibility="hidden";
				//document.all("@@@menu_"+this.name+"_"+id).style.display="none";
				this.menu_Display[id]="hidden";
			}	

			// 目前menu之前所有item數目之累積
			if (level==0 && id==0) {
				accu_y=0;
			} else {	
				accu_y=accu_y+this.submenu_HTML[level][id].item_num;
			}
		}
	}
}

function PopupMenu_SeqShowMenu(id) {
	if (id==0) return 0;
	level=1;
	cur_id=id;
	bCont=true;
	do {
		if (this.parent[cur_id]!=0) {
			level++;
			cur_id=this.parent[cur_id];
			//document.all("@@@menu_"+this.name+"_"+cur_id).style.display="";
			document.all("@@@menu_"+this.name+"_"+cur_id).style.visibility="visible";
			this.menu_Display[cur_id]="visible";			
		} else {
			bCont=false;
		}	
	} while(bCont);
	
	return level;	
}
	
function PopupMenu_GetLevel(id) {
	// 取得item的level
	if (id==0) return 0;
	level=1;
	cur_id=id;
	bCont=true;
	do {
		if (this.parent[cur_id]!=0) {
			level++;
			cur_id=this.parent[cur_id];
		} else {
			bCont=false;
		}	
	} while(bCont);
	
	return level;
}

function PopupMenu_GetRank(id) {
	// 取得item在同一層之rank
	if (id==0) return 0;
	parent_id=this.parent[id];
	//if (parent_id==0) return 0;
	for (i in this.rank[parent_id]) {
		if (this.rank[parent_id][i]==id) return i;
	}
}

function PopupMenu_GetAccumRank(id) {	
	if (id==0) return 0;
	parent_id=this.parent[id];
	for (i in this.rank[parent_id]) {
		if (this.rank[parent_id][i]==id) {
			return parseInt(i)+parseInt(this.GetAccumRank(parent_id));
		}	
	}
}

function PopupMenu_GetLevelWidth(level) {
	if (this.level_width[level]==null)
		return this.width;
	else
		return parseInt(this.level_width[level]);	
}

function PopupMenu_GetLevelAccumWidth(level) {
	width=0;
	
	for (i=1; i<=level; i++) {
		width=width+parseInt(this.GetLevelWidth(i-1));
	}	
	//alert(level+" "+width);
	return parseInt(width);
}

function PopupMenu_SetLevelWidth(level, width) {
	this.level_width[level]=width;
}

var __popupmenus=new Array();
function PopupMenu(name, renderArea, root_dir) {
	this.name=name;
	this.treeinfo		=new Array();
	this.abbreviate	=new Array();
	this.content		=new Array();
	this.tree				=new Array();
	this.node_status=new Array();
	this.parent			=new Array();
	this.rank				=new Array();
	this.attr				=new Array();		// For item customized attributes
	this.type				=new Array();
	this.level			=new Array();
	this.level_width=new Array();
	this.doAbbreviate=true;
	this.root_dir=root_dir;
	this.bgcolor="#cccccc";
	this.width="214";
	this.height="25";
	this.fontSize="12";
	this.HideAllBelowThisLevel=0;
	this.abbr_length=Math.floor(this.width/this.fontSize)*2-5;
	//alert(this.abbr_length);
	
	this.menu_overlap_x=0;
	this.submenu_HTML=new Array();
	this.menu_Display=new Array();
	this.menu_HTML=new Array();
	
	this.id=0;
	this.genResult="";
	this.active_id=0;
	this.toggleShowState="visible";
	
	this.renderArea=renderArea;

	this.AddRoot		=PopupMenu_AddRoot;
	this.EditCategory=PopupMenu_EditCategory;
	this.AddCategory=PopupMenu_AddCategory;
	this.AddLink		=PopupMenu_AddLink;
	this.Write			=PopupMenu_Write;
	this.Arrange		=PopupMenu_Arrange;
	this.GetLevel		=PopupMenu_GetLevel;
	this.GetRank		=PopupMenu_GetRank;
	this.HideAll		=PopupMenu_HideAll;
	this.ToggleShow	=PopupMenu_ToggleShow;
	this.onMouseOver	=PopupMenu_onMouseOver;
	this.onMouseOut	=PopupMenu_onMouseOut;
	this.onMouseDown	=PopupMenu_onMouseDown;
	this.SeqShowMenu=PopupMenu_SeqShowMenu;
	this.GetAccumRank		=PopupMenu_GetAccumRank;
	this.GetLevelWidth=PopupMenu_GetLevelWidth;
	this.SetLevelWidth=PopupMenu_SetLevelWidth;
	this.GetLevelAccumWidth=PopupMenu_GetLevelAccumWidth;

	//this.WriteRoot	=PopupMenu_WriteRoot;
			
	__popupmenus[this.name]=this;

}