
function Menu (target, props) {
	
	if (target == undefined) return;
	
	this.target = (typeof target == "object") ? target : document.getElementById(target);
	
	if (props != undefined) {
		this.properties.evt = (props.evt == undefined) ? this.properties.evt : props.evt;
		this.properties.type = (props.type == undefined) ? this.properties.type : props.type;
		this.properties.autoHide = (props.autoHide == undefined) ? this.properties.autoHide : props.autoHide;
	}
	
	this.evtTarget = (this.userAgent.isIEStrict()) ? "srcElement" : "target";
	
	this.applyCSSClass(this.properties.type);
	
	this.onfocus();
	if (this.properties.autoHide) this.autoHide();
	
	var classPointer = this;
	var evtMouse = (this.userAgent.isIEStrict()) ? this.properties.evt : "event";
	
	this.target[this.properties.evt] = function (evtMouse) {
		classPointer.showHide((classPointer.userAgent.isIEStrict()) ? event : evtMouse);
	}
	
}

Class(Menu);

Menu.prototype.target = new Object();
Menu.prototype.properties = {evt: "onmousedown", type: "", autoHide: true};
Menu.prototype.currFocus = new Object();
Menu.prototype.prevFocus = new Object();
Menu.prototype.evtTarget = new Object();
Menu.prototype.className = "menu-list";
Menu.prototype.userAgent = new UADetector();

Menu.prototype.applyCSSClass = function (name) {
	
	var hasClassName = new RegExp(this.className).test(this.target.className);
	
	if (this.target.className == "") {
		this.target.className = this.className + " " + name;
	} else if (this.target.className != "" && !hasClassName) {
		this.target.className = this.className + " " + name + " " + this.target.className;
		
	} else if (this.target.className != "" && hasClassName) {
		this.target.className = this.target.className + " " + name;
	}
	
}

Menu.prototype.show = function (target) {
	//target.state = !target.state;
	target.className = target.className.replace(/\s?hide|hide\s?/gi, "");
}

Menu.prototype.hide = function (target) {
	target.className = (target.className == "" && target.className == undefined) ? "hide" : target.className + " " + "hide";
	//target.state = false;
}

Menu.prototype.showHide = function (evt) {
	
	var list = new Array();
	
	if (evt[this.evtTarget].tagName.toLowerCase() == "a") {
		list = evt[this.evtTarget].parentNode.childNodes;
	} else if (evt[this.evtTarget] != undefined && evt[this.evtTarget].hasChildNodes) {
		list = evt[this.evtTarget].childNodes;
	}
	
	for (var items = 0; items < list.length; items++) {
		//var t = new RegExp(/\s?hide|hide\s?/).test(list[items].className);
		//alert(list[items].tagName + " = " + t);
		if (new RegExp(/\s?hide|hide\s?/).test(list[items].className)) {
			//alert(this.currFocus.tagName);
			//this.prevFocus = this.currFocus;
			//this.hide(this.prevFocus);
			/*
			var children = this.target.getElementsByTagName(list[items].tagName);
			if (!this.isChild(children, list[items])) {
				
			}
			*/
			this.hide(this.currFocus);
			this.currFocus = list[items];
			this.show(this.currFocus);
			
			break;
			
		}
		
	}
}

Menu.prototype.autoHide = function () {
	
	var classPointer = this;
	
	this.target.onmouseout = function (evt) {
		
		var evt = (classPointer.userAgent.isIEStrict()) ? event : evt;
		var currItem = (classPointer.userAgent.isIEStrict()) ? evt.toElement : evt.relatedTarget;
		var children = new Array();
		
		if (currItem == this || currItem == undefined) return;
		
		if (currItem.tagName == null || currItem.tagName.toLowerCase() == "html" || currItem.tagName.toLowerCase() == "body") {
			classPointer.hide(classPointer.currFocus);
		} else {
			children = classPointer.getChildren(this, true);
			for (var items = 0; items < children.length; items++) {
				if (children[items] == currItem) {
					break;
				} else if (children[items] != currItem && items == children.length - 1) {
					classPointer.hide(classPointer.currFocus);
					classPointer.currFocus.state = true;
				}
			}
		}
		
	}
}

Menu.prototype.onfocus = function (evt) {
	
	//if (this.properties.evt != "onmouseover") return;
	
	var classPointer = this;
	
	if (this.userAgent.isIEStrict()) {
		this.target.onfocusin = function (onfocusin) {
			classPointer.showHide(event);
			
		}
		this.target.onfocusout = function (onfocusout) {
				
			var evt = event;
			var currItem = evt.toElement;
			var children = new Array();
			
			if (currItem == this || currItem == undefined) return;
			
			if (currItem.tagName == null || currItem.tagName.toLowerCase() == "html" || currItem.tagName.toLowerCase() == "body") {
				classPointer.hide(classPointer.currFocus);
			} else {
				children = classPointer.getChildren(this, true);
				for (var items = 0; items < children.length; items++) {
					if (children[items] == currItem) {
						break;
					} else if (children[items] != currItem && items == children.length - 1) {
						classPointer.hide(classPointer.currFocus);
					}
				}
			}
			
		}
	} else {
		this.target.onfocus = function (evt) {
			classPointer.showHide(evt);
		}
		this.target.onblur = function (evt) {
			
			var currItem = evt.explicitOriginalTarget;
			var children = new Array();
			
			if (currItem == this || currItem == undefined) return;
			
			if (currItem.tagName == null || currItem.tagName.toLowerCase() == "html" || currItem.tagName.toLowerCase() == "body") {
				classPointer.hide(classPointer.currFocus);
			} else {
				children = classPointer.getChildren(this, true);
				for (var items = 0; items < children.length; items++) {
					if (children[items] == currItem) {
						break;
					} else if (children[items] != currItem && items == children.length - 1) {
						classPointer.hide(classPointer.currFocus);
					}
				}
			}
			
		}
	}
	
}

Menu.prototype.getChildren = function (target, multiDepth) {
	var child = new Array();
	
	if (target.hasChildNodes()) {
		
		for (var items = 0; items < target.childNodes.length; items++) {
			child.push(target.childNodes[items]);
			if (multiDepth && target.childNodes[items].hasChildNodes()) child = child.concat(this.getChildren(target.childNodes[items], multiDepth));
		}
		
	} else {
		
		for (var items in target) {
			if (target instanceof Array) {
				for (var children in target[items]) {
					child.push(target[items][children]);
				}
				child.reverse();
			} else if (target[items]) {
				child.push(target[items]);
			}
		}
		
	}
	
	child.reverse();
	
	return child;
}

Menu.prototype.isChild = function (list, target) {
	
	for (var items = 0; items < list.length; items++) {
		
		if (list[items] == target) {
			return true;
		}
		
	}
	
	return false;
	
}
