
var _Menu = new Class();

_Menu.prototype = {
	menus: {},
	layer: {},
	menuKey:{},
	ctrlKey:{},
	iframe:{}, 
	
	initialize: function (config){
		this.config = Object.extend({
			duration: 2,	//菜单持续方式：0，按时间显示、1，鼠标离开标题时关闭、2，离开标题及菜单时关闭、3，不关闭
			timeout: 1000,	//菜单显示时间
			layer: 0,
			onlyinit: 1,
			left: 0,
			top: 0,
			align: 3,		//对齐方式：0：中、1：上、2：右、3：下、4：左、5：按left及top的座标显示
			hoverclass: 'hover'
		},
		config||{});
		
	},
	
	init: function (config) {
		if (typeof config.menuid != 'string') {
			if (typeof config.menuid == 'object') {
				config.menuid = config.menuid.id;
			} else if (typeof config.ctrlid == 'string') {
				config.menuid = config.ctrlid + '_menu';
			} else if (typeof config.ctrlid == 'object') {
				config.menuid = config.ctrlid.id + '_menu';
			}
		}
		
		if (!config.menuid) return false;
		
		this.layer = config.layer ? config.layer : this.config.layer;
		var onlyinit = !isUndefined(config.onlyinit) ? config.onlyinit : this.config.onlyinit;
		var align = !isUndefined(config.align) ? config.align : this.config.align;
		
		if ((onlyinit && $(config.menuid).style.display != 'none') || (align < 5 && !$(config.ctrlid))) {
			return false;
		}

		if (this.menus[this.layer] && this.menus[this.layer].menuKey != config.menuid) {
			this.hide();
		}
		
		this.menus[this.layer] = {
			config: {},
			menuKey: config.menuid,
			menuobj: $(config.menuid),
			ctrlobj: $(config.ctrlid)
		}
		this.menuKey[this.menus[this.layer].menuobj.id] = this.layer;
		this.ctrlKey[this.menus[this.layer].ctrlobj.id] = this.layer;
		
		Object.extend(this.menus[this.layer].config, this.config);
		Object.extend(this.menus[this.layer].config, config || {});
		
		
		return true;
	},
	
	initCtrl: function () {
		var ctrlobj = this.menus[this.layer].ctrlobj;
		if(ctrlobj && !ctrlobj.initialized) {
			ctrlobj.initialized = true;
			if(this.menus[this.layer].config.duration < 3) {
				ctrlobj.onmouseout = this.mouseout.bind(this);
			}
			ctrlobj.onmouseover = this.mouseover.bindArguments(this, 'ctrlKey', ctrlobj.id);
		}
	},
	
	
	initMenu: function () {
		var menuobj = this.menus[this.layer].menuobj;
		if(menuobj && !menuobj.initialized) {
			menuobj.style.position = 'absolute';
			menuobj.initialized = true;
			if(this.menus[this.layer].config.duration < 3) {
				if(this.menus[this.layer].config.duration != 1) {
					menuobj.onmouseout = this.mouseout.bind(this);
				}
				if(this.menus[this.layer].config.duration > 1) {
					menuobj.onmouseover = this.mouseover.bindArguments(this, 'menuKey', menuobj.id);
				}
			}
			if(is_ie) {
				menuobj.style.filter += "progid:DXImageTransform.Microsoft.shadow(direction=135,color=#CCCCCC,strength=2)";
			}
		}
	},
	
	mouseover: function(k, i) {
		this.layer = this[k][i];
		for(layer in this.menus) {
			if(layer.toString(10) <= this.layer && this.menus[layer].timer) {
				clearTimeout(this.menus[layer].timer);
			}
		}
	},
	
	mouseout: function() {
		for (layer in this.menus) {
			if(layer.toString(10) > -1) {
				if (this.menus[layer].timer) {
					clearTimeout(this.menus[layer].timer);
				}
				this.menus[layer].timer = setTimeout(this.hideLayer.bindArguments(this, layer), this.menus[layer].config.timeout);
			}
		}
	},

	setPosition: function() {
		var align = this.menus[this.layer].config.align;
		var oLeft, oTop;
		
		if (align == 5) {
			oLeft = this.menus[this.layer].config.left;
			oTop = this.menus[this.layer].config.top;
		} else {
			var ctrlobj = this.menus[this.layer].ctrlobj;
			var menuobj = this.menus[this.layer].menuobj;
			var pos = this.fetchOffset(ctrlobj);
			menuobj.w = menuobj.offsetWidth;
			menuobj.h = menuobj.offsetHeight;
			oLeft = pos.left;
			oTop = pos.top;
			if (align == 0) {
				oLeft = pos.left + (ctrlobj.offsetWidth - menuobj.offsetWidth) / 2;
				oTop = pos.top + (ctrlobj.offsetHeight - menuobj.offsetHeight) / 2;
			}
			else if (align == 1) {
				oTop = pos.top - menuobj.h;
			}
			else if (align == 2) {
				oLeft = pos.left + ctrlobj.offsetWidth;
			}
			else if (align == 3) {
				oTop = pos.top + ctrlobj.offsetHeight;
			}
			else if (align == 4) {
				oLeft = pos.left - menuobj.w;
			}
		
			if ((oLeft + menuobj.w > body.clientWidth) && (pos.left + ctrlobj.offsetWidth - menuobj.w >= 0)) {
				oLeft = pos.left + ctrlobj.offsetWidth - menuobj.w;
				if (align == 2) {
					oLeft -= ctrlobj.offsetWidth;
				}
			}
			
			if (oTop + menuobj.h > body.scrollTop + body.clientHeight) {
				oTop = pos.top + ctrlobj.offsetHeight - menuobj.h;
				if (align == 3) {
					oTop -= ctrlobj.offsetHeight;
				}
			}
		}
		menuobj.style.zIndex = ++maxZIndex;
		menuobj.style.left = oLeft + 'px';
		menuobj.style.top = oTop + 'px';
		if(menuobj.style.clip && !is_opera) {
			menuobj.style.clip = 'rect(auto, auto, auto, auto)';
		}
	},
	
	fetchOffset: function (obj) {
		if (!obj) return;
		
		var left_offset = obj.offsetLeft;
		var top_offset = obj.offsetTop;
		while((obj = obj.offsetParent) != null) {
			left_offset += obj.offsetLeft;
			top_offset += obj.offsetTop;
		}
		return { 'left' : left_offset, 'top' : top_offset};
	},
	
	buildOverlay: function () {
		var iframe = this.iframe[this.layer];
		var menuobj = this.menus[this.layer].menuobj;
		if(!iframe) {
			var iframe = document.createElement('iframe');
			iframe.style.display = 'none';
			iframe.style.position = 'absolute';
			iframe.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
			menuobj.parentNode.appendChild(iframe);
			this.iframe[this.layer] = iframe;
		}
		with (iframe.style) {
			top = menuobj.style.top;
			left = menuobj.style.left;
			width = menuobj.w;
			height = menuobj.h;
			display = 'block';
		}
	},
	
	show: function (config) {
		if (!this.init(config)) return;
		
		if (this.menus[this.layer].ctrlobj) {
			this.initCtrl();
			this.menus[this.layer].ctrlobjclassName = this.menus[this.layer].ctrlobj.className;
			this.menus[this.layer].ctrlobj.className += ' '+ this.menus[this.layer].config.hoverclass;
		}
		this.initMenu();

		this.menus[this.layer].menuobj.style.display = '';
		this.setPosition();
		
		if(is_ie && is_ie < 7) {
			this.buildOverlay();
		}
	},
	
	hide: function () {
		for (layer in this.menus) {
			if(layer.toString(10) >= this.layer) {
				this.hideLayer(layer);
			}
		}
	},
	
	hideLayer: function (layer) {
		if (this.menus[layer] && this.menus[layer].menuobj) {
			try {
				this.menus[layer].ctrlobj.className = this.menus[this.layer].ctrlobjclassName;
			} catch(e) {}
			clearTimeout(this.menus[layer].timer);
	
			this.menus[layer].menuobj.style.display = 'none';
		//	this.menus[layer].ctrlobj.initialized = false;
		//	this.menus[layer].menuobj.initialized = false;
			
			if(is_ie && is_ie < 7 && this.iframe[this.layer]) {
				this.iframe[this.layer].style.display = 'none';
			}
		}
	}
}


var menu = new _Menu();


function showMenu(ctrlid, align, layer, duration, timeout) {
	var config = {};
	if(!isUndefined(ctrlid)) config.ctrlid = ctrlid;
	if(!isUndefined(align)) config.align = align;
	if(!isUndefined(duration)) config.duration = duration;
	if(!isUndefined(timeout)) config.timeout = timeout;
	if(!isUndefined(layer)) config.layer = layer;
	menu.show(config);
}








/*
var _Menu = new Class();
_Menu.prototype = {
	menu: {active:{}, timer:{}, iframe:{}},
	ctrlobj: null,
	menuobj: null,
	
	
	initialize: function (config){
		this.config = Object.extend({
			duration: 2,	//菜单持续方式：0，按时间显示、1，鼠标离开标题时关闭、2，离开标题及菜单时关闭、3，不关闭
			timeout: 500,	//菜单显示时间
			layer: 0,
			left: 0,
			top: 0,
			align: 3		//对齐方式：0：中、1：上、2：右、3：下、4：左，可以两个相加，比如3为右上角
		},
		config||{});
		
	},
	
	initCtrl: function () {
		if(this.ctrlobj && !this.ctrlobj.initialized) {
			this.ctrlobj.initialized = true;
			if(this.config.duration < 3) {
				Event.observe(this.ctrlobj, 'mouseout', this.mouseout.bind(this), false);
			}
			
			Event.observe(this.ctrlobj, 'mouseover', this.mouseover.bind(this), false);
		}
	},
	
	initMenu: function () {
		this.menuobj.style.position = 'absolute';
		if(this.menuobj && !this.menuobj.initialized) {
			this.menuobj.initialized = true;
			this.menuobj.ctrlkey = this.ctrlid;
			if(this.config.duration < 3) {
				if(this.config.duration != 1) {
					Event.observe(this.menuobj, 'mouseout', this.mouseout.bind(this), false);
				}
				if(this.config.duration > 1) {
					Event.observe(this.menuobj, 'mouseover', this.mouseover.bind(this), false);
				}
			}
			if(is_ie) {
				this.menuobj.style.filter += "progid:DXImageTransform.Microsoft.shadow(direction=135,color=#CCCCCC,strength=3)";
			}
		}
	},
	clearTime: function () {
		clearTimeout(this.menu['timer'][this.ctrlid]);
		var d = this.ctrlobj;
		
		/*
		while (d.parentNode) {
			if (d.id.indexOf('_menu') > 0) {
				clearTimeout(this.menu['timer'][d.id.substring(0, d.id.length - 5)]);
			}
			d = d.parentNode;
		}
		* /
		for(var id in this.menu['timer']) {
			
		}
	},
	
	mouseover: function() {
		//doane(e);
		for(var id in this.menu['timer']) {
			if(this.menu['timer'][id]) {
				clearTimeout(this.menu['timer'][id]);
			}
		}
	},
	
	mouseout: function() {
		this.menu['timer'][this.ctrlid] = setTimeout(this.hide.bind(this), this.config.timeout);
	},
	
	setPosition: function() {
		if (this.ctrlid) {
			if (this.ctrlobj) {
				this.ctrlobj.pos = this.fetchOffset(this.ctrlobj);
			}
			this.menuobj.w = this.menuobj.offsetWidth;
			this.menuobj.h = this.menuobj.offsetHeight;
			if (this.config.left && this.config.top) {
				var oLeft = this.config.left;
				var oTop = this.config.top;
			}
			else {
				var oLeft = this.ctrlobj.pos.left;
				var oTop = this.ctrlobj.pos.top;
				if (!this.config.align) {
					oLeft = this.ctrlobj.pos.left + (this.ctrlobj.offsetWidth - this.menuobj.offsetWidth) / 2;
					oTop = this.ctrlobj.pos.top + (this.ctrlobj.offsetHeight - this.menuobj.offsetHeight) / 2;
				}
				else if (this.config.align == 1) {
					oTop = this.ctrlobj.pos.top - this.menuobj.h;
				}
				else if (this.config.align == 2) {
					oLeft = this.ctrlobj.pos.left + this.ctrlobj.offsetWidth;
				}
				else if (this.config.align == 3) {
					oTop = this.ctrlobj.pos.top + this.ctrlobj.offsetHeight;
				}
				else if (this.config.align == 4) {
					oLeft = this.ctrlobj.pos.left - this.menuobj.w;
				}
			
				if ((oLeft + this.menuobj.w > body.clientWidth) && (this.ctrlobj.pos.left + this.ctrlobj.offsetWidth - this.menuobj.w >= 0)) {
					oLeft = this.ctrlobj.pos.left + this.ctrlobj.offsetWidth - this.menuobj.w;
					if (this.config.align == 2) {
						oLeft -= this.ctrlobj.offsetWidth;
					}
				}
				
				if (oTop + this.menuobj.h > body.scrollTop + body.clientHeight) {
					oTop = this.ctrlobj.pos.top + this.ctrlobj.offsetHeight - this.menuobj.h;
					if (this.config.align == 3) {
						oTop -= this.ctrlobj.offsetHeight;
					}
				}
			}
			if (oTop < 0) oTop = 0;
			if (oLeft < 0) oLeft = 0;
			
		//	return;
			this.menuobj.style.zIndex = ++maxZIndex;
			this.menuobj.style.left = oLeft + 'px';
			this.menuobj.style.top = oTop + 'px';
			if(this.menuobj.style.clip && !is_opera) {
				this.menuobj.style.clip = 'rect(auto, auto, auto, auto)';
			}
		}
	},

	fetchOffset: function (obj) {
		if (!obj) return;
		
		var left_offset = obj.offsetLeft;
		var top_offset = obj.offsetTop;
		while((obj = obj.offsetParent) != null) {
			left_offset += obj.offsetLeft;
			top_offset += obj.offsetTop;
		}
		return { 'left' : left_offset, 'top' : top_offset};
	},
	
	show: function (config) {
		Object.extend(this.config, config || {});

		e = window.event ? window.event : this.ctrlid;
		this.ctrlobj = $(this.ctrlid);
		this.menuobj = $(this.ctrlid + '_menu');
		if(!(this.ctrlobj || (this.config.left && this.config.top)) || !this.menuobj) return;
		if (this.menu['active'][this.config.layer] != null && this.menu['active'][this.config.layer].ctrlkey == this.ctrlid) {
			return;
		}
		
		this.hide(this.config.layer);
	
		for(var id in this.menu['timer']) {
			if(this.menu['timer'][id]) clearTimeout(this.menu['timer'][id]);
		}
		
		if (this.ctrlobj) {
			this.initCtrl();
			this.ctrlobjclassName = this.ctrlobj.className;
			this.ctrlobj.className += ' hover';
		}
		this.initMenu();
		
		this.menuobj.style.display = '';
		if(!is_opera) {
			this.menuobj.style.clip = 'rect(auto, auto, auto, auto)';
		}
		this.setPosition();

		if(is_ie && is_ie < 7) {
			if(!this.menu['iframe'][this.config.layer]) {
				var iframe = document.createElement('iframe');
				iframe.style.display = 'none';
				iframe.style.position = 'absolute';
				iframe.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
				$('append_parent') ? $('append_parent').appendChild(iframe) : this.menuobj.parentNode.appendChild(iframe);
				this.menu['iframe'][this.config.layer] = iframe;
			}
			this.menu['iframe'][this.config.layer].style.top = this.menuobj.style.top;
			this.menu['iframe'][this.config.layer].style.left = this.menuobj.style.left;
			this.menu['iframe'][this.config.layer].style.width = this.menuobj.w;
			this.menu['iframe'][this.config.layer].style.height = this.menuobj.h;
			this.menu['iframe'][this.config.layer].style.display = 'block';
		}

		this.menu['active'][this.config.layer] = this.menuobj;
		//this.initialize();
	},
	
	hide: function() {
		if(this.menu['active'][this.config.layer]) {
			try {
				$(this.menu['active'][this.config.layer].ctrlkey).className = this.ctrlobjclassName;
			} catch(e) {}
			clearTimeout(this.menu['timer'][this.menu['active'][this.config.layer].ctrlkey]);
			this.menu['active'][this.config.layer].style.display = 'none';
			if(is_ie && is_ie < 7 && this.menu['iframe'][this.config.layer]) {
				this.menu['iframe'][this.config.layer].style.display = 'none';
			}
			this.menu['active'][this.config.layer] = null;
		}
	}
}

var menu = new _Menu();

function showMenu(ctrlid, align, duration, timeout, layer) {
	var menu = new _Menu();
	menu.ctrlid = ctrlid;
	if(!isUndefined(align)) menu.config.align = align;
	if(!isUndefined(duration)) menu.config.duration = duration;
	if(!isUndefined(timeout)) menu.config.timeout = timeout;
	if(!isUndefined(layer)) menu.config.layer = layer;
	menu.show();
}
*/
