//Konstruktor der "menu"-Klasse
function menu(name,horizontal,top_correction,left_correction) {
	//Zuerst alles sehr streng setzen
	this.has_dom = false;
	this.proper_w3c_dom = false;
	this.proper_msie_dom = false;

	//iCab iCab kennt beide DOMs
	if(document.getElementById || document.all) this.iCab = /iCab/i;

	//Wenn der Browser das W3C-DOM unterstützt
	if(document.getElementById) {
		//Zuerst wahr
		this.proper_w3c_dom = true;
		//iCab rendert schlecht und die Positionierung funktioniert nicht (getestet mit iCab 2.9.8 http://www.icab.de)
		if(this.iCab.test(navigator.userAgent)) this.proper_w3c_dom = false;
		//Alle Bowser, die das MSIE-DOM unterstützen ausklammern (Speziell der Opera rendert besser im MSIE-Modus)
		this.opera = /Opera/i;
		if(document.all || this.opera.test(navigator.userAgent)) this.proper_w3c_dom = false;
	}

	//Wenn der Browser das MSIE-DOM versteht
	if(document.all) {
		this.proper_msie_dom = true;
		//iCab ausklammern (siehe oben)
		if(this.iCab.test(navigator.userAgent)) this.proper_msie_dom = false;
	}

	//Wenn der Browser ein W3C- oder MSIE-DOM hat (Das alte Netscape-DOM wird ignoriert)
	if(this.proper_msie_dom || this.proper_w3c_dom) this.has_dom = true;

	if(this.has_dom) {
		//Hiermit finden wir Macs
		this.mac_regexp = /mac|ppc|powerpc/i;

		//Hiermit finden wir den Safari-Browser von Apple
		this.safari_regexp = /safari/i;

		//Dieser Ausdruck findet die Layer und Links, die feuern
		this.bubble_regexp = new Array(/^(div|a)$/i,/_menu_[0-9]/);

		//Objekt für den Status der Layer initialisieren
		this.layers = new Object();

		//Name des Menüsystems (zur Mehrfachverwendung)
		this.name = name;

		//Handelt es sich um ein horizontales Menü?
		this.horizontal = horizontal;

		//Benötigen wir einen Korrekturwert?
		this.top_correction = top_correction;
		this.left_correction = left_correction;

		//Das Event-Bubbling stoppen
		this.bubbling();
	}
}

menu.prototype.showMenu = function(id,depth,new_menu) {
	if(this.has_dom) {
		//Falls das Objekt noch nicht existiert, erzeugen wir es
		if(!this.layers[id]) {
			this.layers[id] = {
				'depth' : depth
			};
		}

		//Wir finden heraus, welche Objekte auf dieser Stufe der Hierarchie geschlossen werden müssen
		if(new_menu) for(var name in this.layers) if(depth == 0 || this.layers[name].depth >= depth) this.layers[name].status = 'closed';

		//Unser Menü auf "offen" setzen
		this.layers[id].status = 'open';

		//Nun wird das aktuelle Menü eingeblendet
		for(var name in this.layers) {
			if(this.layers[name].status == 'open') {
				//Korrekturwerte für Tiefe errechnen
				top_correction = ((this.layers[name]['depth'] < this.top_correction.length) ? this.top_correction[this.layers[name]['depth']] : this.top_correction[(this.top_correction.length-1)]);
				left_correction = ((this.layers[name]['depth'] < this.left_correction.length) ? this.left_correction[this.layers[name]['depth']] : this.left_correction[(this.left_correction.length-1)]);

				if(this.proper_msie_dom) {
					if(document.all[name]) {
						//Koordinaten berechnen
						if(this.layers[name]['depth'] == 0 && this.horizontal) {
							document.all[name].style.top = this.bubbleTop(document.all[name+'_caller'])+document.all[name+'_caller'].offsetHeight+top_correction+'px';
							document.all[name].style.left = this.bubbleLeft(document.all[name+'_caller'])+left_correction+'px';
						}
						else {
							document.all[name].style.top = this.bubbleTop(document.all[name+'_caller'])+top_correction+'px';
							document.all[name].style.left = this.bubbleLeft(document.all[name+'_caller'])+document.all[name+'_caller'].offsetWidth+left_correction+'px';
						}
						//DIV anzeigen
						document.all[name].style.display = 'block';
					}
				}
				else if(this.proper_w3c_dom) {
					if(document.getElementById(name)) {
						//Koordinaten berechnen
						if(this.layers[name]['depth'] == 0 && this.horizontal) {
							document.getElementById(name).style.top = this.bubbleTop(document.getElementById(name+'_caller'))+document.getElementById(name+'_caller').offsetHeight+top_correction+'px';
							document.getElementById(name).style.left = this.bubbleLeft(document.getElementById(name+'_caller'))+left_correction+'px';
						}
						else {
							document.getElementById(name).style.top = this.bubbleTop(document.getElementById(name+'_caller'))+top_correction+'px';
							document.getElementById(name).style.left = this.bubbleLeft(document.getElementById(name+'_caller'))+document.getElementById(name+'_caller').offsetWidth+left_correction+'px';
						}
						//DIV anzeigen
						document.getElementById(name).style.display = 'block';
					}
				}
			}
			else {
				if(this.proper_msie_dom) {
					if(document.all[name]) {
						//DIV anzeigen
						document.all[name].style.display = 'none';
					}
				}
				else if(this.proper_w3c_dom) {
					if(document.getElementById(name)) {
						//DIV anzeigen
						document.getElementById(name).style.display = 'none';
					}
				}
			}
		}
	}
}

menu.prototype.hideMenu = function(id) {
	if(this.has_dom) {
		this.layers[id].status = 'closed';

		if(this.proper_msie_dom) {
			if(document.all[id]) {
				//DIV verstecken
				document.all[id].style.display = 'none';
			}
		}
		else if(this.proper_w3c_dom) {
			if(document.getElementById(id)) {
				//DIV verstecken
				document.getElementById(id).style.display = 'none';
			}
		}
	}
}

menu.prototype.bubbleTest = function(node) {
	var my_offset = node.offsetTop;
	if(isNaN(my_offset)) my_offset = 0;
	alert(node.tagName+' '+my_offset);
	if(node.parentNode) this.bubbleTest(node.parentNode);
}

menu.prototype.bubbleTop = function(node) {
	if(this.has_dom) {
		if(node.offsetParent) return node.offsetTop+this.bubbleTop(node.offsetParent);
		else return node.offsetTop;
	}
}

menu.prototype.bubbleLeft = function(node) {
	if(this.has_dom) {
		if(node.offsetParent) return node.offsetLeft+this.bubbleLeft(node.offsetParent);
		else return node.offsetLeft;
	}
}

menu.prototype.stopBubbling = function(event) {
	if(this.has_dom) {
		if(window.event && window.event.cancelBubble !== null) {
			window.event.cancelBubble = true;
		}
		else {
			event.cancelBubble = true;
			if(event.cancelable) event.preventDefault();
			if(event.stopPropagation != null) event.stopPropagation();
		}
	}
}

menu.prototype.isChildOfDiv = function(node) {
	if(this.proper_w3c_dom) {
		var isDiv = false;
		for(a=0;a<my_layers.length;a++) {
			if(node.id == my_layers[a][0]) isDiv = true;
		}

		if(isDiv) return true;
		else {
			if(node.parentNode) return isChildOfDiv(node.parentNode);
			else return false;
		}
	}
}

menu.prototype.bubbling = function() {
	if(!this.safari_regexp.test(navigator.userAgent)) {
		//Stoppt das lästige Event-Bubbling bestimmter Objekte
		eval('function __'+this.name+'_cancelBubble(event) { '+this.name+'.stopBubbling(event); }');

		//Das Schießen der Layer verhindern
		if(this.proper_msie_dom) {
			for(a=0;a<document.all.length;a++) {
				if(this.bubble_regexp[0].test(document.all[a].tagName) && this.bubble_regexp[1].test(document.all[a].id)) {
					eval('document.all[a].attachEvent("onmouseout", __'+this.name+'_cancelBubble);');
				}
			}
		}
		else if(this.proper_w3c_dom) {
			//Wir machen hier per wildcard eine Kollektion aller Objekte (ähnlich document.all)
			var node = document.getElementsByTagName('*');
			for(a=0;a<node.length;a++) {
				if(this.bubble_regexp[0].test(node[a].tagName) && this.bubble_regexp[1].test(node[a].id)) {
					eval('node[a].addEventListener("mouseout", __'+this.name+'_cancelBubble, false);');
				}
			}
		}
	}
}
