var MenuItem = Class.create();
MenuItem.prototype = {
	initialize: function (obj, cont) {
		this.obj = obj;
		this.container = cont;
		this.div = { };
		this.parentDiv = this.container.div;
		this.childCont = { };
		this.config = cont.config || {styleNames:new Array('menuDiv','menuItem','menuItemHover')};
		if (!this.config.styleNames) {
			this.config.styleNames = new Array('menuDiv','menuItem','menuItemHover');
		}
		this.build();
	},
	build: function () {
		this.div = Builder.node('div',{className:this.config.styleNames[1]});
		if (this.container.parentClass instanceof dynMenu) {
			if (this.config.vertical) {
				if (Prototype.Browser.IE) {
					this.div.style.display='inline';
				} else if (Prototype.Browser.Gecko) {
					this.div.style.display='-moz-inline-box';
				} else {
					this.div.style.display='inline-table';
				}
				$(this.div).removeClassName(this.config.styleNames[1]);
			}
		}
		this.parentDiv.appendChild(this.div);
		var item = this.obj.firstChild;
		this.div.appendChild(item.cloneNode(true));
		if (this.obj.childNodes.length>1) {
			for (var i=0;i<this.obj.childNodes.length; i++ ) {
				var item = $(this.obj.childNodes.item(i));
				if (item.nodeName.toLowerCase()=='ul') {
					this.childCont = new Container($(item), $(this.container.parentDiv),this);
				}
			}
		}
		Event.observe(this.div,'mouseover',this.mouseOver.bindAsEventListener(this));
		Event.observe(this.div,'mouseout',this.mouseOut.bindAsEventListener(this));
		Event.observe(this.div,'click',this.mouseClick.bindAsEventListener(this));
	},
	mouseOver: function () {
		if (this.childCont instanceof Container) {
			this.childCont.clearTimer();
		}
		this.container.clearTimer();
		$(this.div).addClassName(this.config.styleNames[2]);
		if (this.childCont instanceof Container) {
			this.childCont.show();
		}
	},
	mouseOut: function () {
		$(this.div).removeClassName(this.config.styleNames[2]);
		if (this.childCont instanceof Container) {
			this.childCont.setTimer();
		} else {
			this.container.setTimer();
		}
	},
	mouseClick: function () {
		this.container.hideAll();
	}
}

var Container = Class.create();
Object.extend(Container.prototype, Enumerable);
Object.extend(Container.prototype, {
	initialize: function (obj, parentDiv,parentClass) {
		this.obj = obj || { };
		this.items = { };
		this.div = { };
		this.parent = this.obj.parentNode || { };
		this.parentDiv = $(parentDiv) || $(document.body);
		this.parentClass = parentClass;
		this.config = parentClass.config || {styleNames:new Array('menuDiv','menuItem','menuItemHover')};
		if (!this.config.styleNames) {
			this.config.styleNames = new Array('menuDiv','menuItem','menuItemHover');
		}
		this.build();
		this.timer = 0;
	},
	build: function () {
		if (this.obj.hasChildNodes() ) {
			this.div = Builder.node('div',{				
				style:'position:absolute;visibility:hidden;'
			});
			if (this.parentClass instanceof MenuItem) {
				this.div.className = this.config.styleNames[0];
				if (this.config.opacity) {
					$(this.div).setStyle('opacity:0.' + this.config.opacity + ';filter: alpha(opacity=' + this.config.opacity + ');');
				}
			}
			this.parentDiv.appendChild(this.div);
			for (var i=0;i<this.obj.immediateDescendants().length;i++) {
				this.items[i]=new MenuItem(this.obj.immediateDescendants()[i],this);
			}
		}
	},
	setTimer: function () {
		this.timer = window.setTimeout(this.hide.bind(this),500);
		if (this.parentClass instanceof MenuItem) {
			this.parentClass.container.setTimer();
		}
	},
	clearTimer: function () {
		window.clearTimeout(this.timer);
		if (this.parentClass instanceof MenuItem) {
			this.parentClass.container.clearTimer();
		}
	},
	show: function () {
		if (this.parentClass instanceof MenuItem) {
			var obj=this.parentClass.container.items
			for (var i in obj ) {
				if (obj[i].childCont instanceof Container) {
					obj[i].childCont.hide();
				}
			}
		}
		this.div.style.visibility='visible';
	},
	hide: function () {
		for (var i in this.items ) {
			if (this.items[i].childCont instanceof Container) {
				this.items[i].childCont.hide();
			}
		}
		if (!(this.parentClass instanceof dynMenu)) {
			this.div.style.visibility='hidden';
		}
	},
	hideAll: function () {
		this.hide();
		if (this.parentClass instanceof MenuItem) {
			this.parentClass.container.hideAll();
		}
	}
})

var dynMenu = Class.create();
dynMenu.prototype = {
	initialize: function () {
		this.mUl=$(arguments[0]);
		this.mDiv=$(arguments[1]) || $(document.body);
		this.config = arguments[2] || { };
		this.mainCont = new Container(this.mUl, this.mDiv, this, this.config);
		this.mainCont.show();
		this.calcPos(this.mainCont);
	},
	calcPos: function(obj) {
		var mainCont = obj.parentClass instanceof dynMenu;
		if (!(mainCont)) {
			var d=obj.parentClass.container.div,s=obj.div.style;
			if (!(obj.parentClass.container.parentClass instanceof dynMenu)) {
				s.left = d.offsetLeft + d.offsetWidth;
				s.top = d.offsetTop + obj.parentClass.div.offsetTop;
			} else {
				s.left = d.offsetLeft + obj.parentClass.div.offsetLeft;
				if (obj.parentClass.container.parentClass.config.upside==true) {
					//s.top = d.offsetTop - obj.div.offsetHeight;
					s.bottom = d.offsetTop;
				} else {
					s.top = d.offsetTop + d.offsetHeight;
				}
			}
		}
		var w=parseInt(obj.div.offsetWidth);
		w -= (parseInt($(obj.div).getStyle('border-left-width'))+parseInt($(obj.div).getStyle('border-right-width')));
		var desw,comp=0;
		if (mainCont) {
			if (obj.parentClass.config.fullWidth) {
				if (!Prototype.Browser.Gecko) {
					for (var i in obj.items ) {
						var d = $(obj.items[i].div);
						d.setStyle({width:0});
					}
				}
				desw = obj.parentClass.mDiv.offsetWidth - obj.parentClass.mainCont.div.offsetWidth;
				desw -= (parseInt($(obj.parentClass.mDiv).getStyle('border-left-width'))+parseInt($(obj.parentClass.mDiv).getStyle('border-right-width')));
				comp = desw;
				desw /= $H(obj.parentClass.mainCont.items).size();
				desw = Math.floor(desw);
				comp -= desw * $H(obj.parentClass.mainCont.items).size();
			}
		}
		for (var i in obj.items ) {
			var d = $(obj.items[i].div);
			if (!(mainCont) || ((mainCont) && (obj.parentClass.config.vertical==false))) {
				if (d.offsetWidth<w) {
					d.style.width = w;
				}				
			} else {
				var parsedWidth=parseInt(d.offsetWidth + desw);
				d.setStyle({width:parsedWidth});
				if (Prototype.Browser.Gecko) {
					$(d.firstChild).style.display='block';
					$(d.firstChild).setStyle({width:parsedWidth});
				}
			}
			if (obj.items[i].childCont instanceof Container) {
				this.calcPos(obj.items[i].childCont);				
			}
		}
		if (mainCont  && obj.parentClass.config.vertical) {
			var d = $(obj.items[i].div);
			var parsedWidth=parseInt(d.offsetWidth + comp);
			d.setStyle({width:parsedWidth});
			if (Prototype.Browser.Gecko) {
				$(d.firstChild).setStyle({width:parsedWidth});
			}
		}
	}
};