/*
 * (c) fairtec Kommunikationstechnik GmbH Bremen, soweit keine andere Quelle angegeben
 */

/*
	document.getElementById() fuer IE und Opera reparieren: diese liefern das ("erstbeste") Element
	zurueck, dessen ID (so sollte es sein) *ODER* der *NAME* (falsch!) dem gesuchten Wert entspricht!

	Quelle: http://webbugtrack.blogspot.com/2007/08/bug-152-getelementbyid-returns.html
*/
function fixGetElementById() {
	//use browser sniffing to determine if IE or Opera (ugly, but required)
	var isOpera = false;
	var isIE = false;
	if (typeof(window.opera) != 'undefined') {
		isOpera = true;
	} else if (navigator.appName.indexOf('Internet Explorer') >= 0) {
		isIE = true;
	}
	
	//fix both IE and Opera (adjust when they implement this method properly)
	if ((isOpera || isIE) && typeof(document.nativeGetElementById) == 'undefined'){
		document.nativeGetElementById = document.getElementById;
		//redefine it!
		try {
			document.getElementById = function(id){
				var elem = document.nativeGetElementById(id);
				if (elem){
					//verify it is a valid match!
					if (elem.attributes['id'] && elem.attributes['id'].value == id){
						//valid match!
						return elem;
					} else {
						//not a valid match!
						//the non-standard, document.all array has keys for all name'd, and id'd elements
						//start at one, because we know the first match, is wrong!
						for (var i=1; i<document.all[id].length; i++){
							if (document.all[id][i].attributes['id'] && document.all[id][i].attributes['id'].value == id)
								return document.all[id][i];
						}
					}
				}
				return null;
			};
		} catch (e) {} // IE 5.0 unterstuetzt kein Ueberschreiben vordefinierter Funktion? Setzen schlaegt fehlt wegen "Das Objekt unterstuetzt diese Eigenschaft oder Methode nicht" ... Fehler ignorieren und hoffen, dass niemand mehr IE 5.0 an einer "problematischen Stelle" verwendet ;-)
	}
}
fixGetElementById();

/*
	Workaround fuer document.createElement, um auch in "kaputten" Browsern (in diesem Fall: IE bis incl. Version 7)
	neue Elemente MIT name und/oder id zu erzeugen.
*/
function fixCreateElement(type,id,name) {
	var elem;
	var isBroken = false;
	if (id != null || name != null) {
		var xf = document.createElement('form');
		var xi = document.createElement('input');
		xi.setAttribute('name','dummy');
		xf.appendChild(xi);
		isBroken = (xf.dummy == null);
	}
	if (isBroken) {
		var str = '<' + type;
		if (id != null)
			str += ' id="' + id + '"';
		if (name != null)
			str += ' name="' + name + '"';
		str += '>';
		elem = document.createElement(str);
	} else {
		elem = document.createElement(type);
		if (id != null)
			elem.setAttribute('id',id);
		if (name != null)
			elem.setAttribute('name',name);
	}
	return elem;
}

/*
	Dyntext in einem neuen Fenster bearbeiten.
*/
function editDyntext(dir,id) {
	var w = window.open(dir + '/dyntext/edit.cfm?id=' + id, 'DT_' + dir.replace(/[^a-zA-Z0-9_]/g, "_"),'width=930,height=450,location=no,menubar=no,status=no,toolbar=no');
	w.focus();
}

/*
	Hilfetext in einem neuen Fenster bearbeiten.
*/
function editHelp(dir,mod,label,ev) {
	var w = window.open(dir + '/dyntext/help.cfm?mod=' + encodeURIComponent(mod) + '&label=' + encodeURIComponent(label) + '&event=' + encodeURIComponent(ev), 'Help_' + dir.replace(/[^a-zA-Z0-9_]/g, "_"),'width=930,height=450,location=no,menubar=no,status=no,toolbar=no');
	w.focus();
}

/*
	Fuege einem Element eine CSS-Klasse hinzu.
*/
function addClass(elem,name) {
	var pattern = new RegExp('(^|\\s+)' + name + '(\\s+|$)');
	if (!elem.className.match(pattern))
		elem.className += ' ' + name;
}

/*
	Entferne eine CSS-Klasse von einem Element.
*/
function removeClass(elem,name) {
	var pattern = new RegExp('(^|\\s+)' + name + '(\\s+|$)');
	elem.className = elem.className.replace(pattern, '$1$2');
}

/*
	Fuege einem Element eine CSS-Klasse hinzu oder entferne sie.
*/
function changeClass(elem,name,add) {
	if (add) {
		addClass(elem,name);
	} else {
		removeClass(elem,name);
	}
}

/*
	Prueft, ob ein Element eine bestimmte CSS-Klasse hat.
*/
function hasClass(elem,name) {
	var pattern = new RegExp('(^|\\s+)' + name + '(\\s+|$)');
	return elem.className.match(pattern);
}

/*
	Ermittle die absoluten Koordinaten eines Objekt innerhalb des Dokument.
	toNonStatic = true: Koordinaten nur relativ zum ersten Elternobjekt, das NICHT "position:static" hat, ermitteln (fuer position:absolute)
*/
function getNodeCoords(node,toNonStatic) {
	var coords = { x: 0, y: 0 };
	do {
		coords.x += node.offsetLeft;
		coords.y += node.offsetTop;
	} while ((node = node.offsetParent) && (!toNonStatic || !node.style || (node.style.position == 'static' || node.style.position == '')));
	return coords;
}

/*
	Ermittle die Groesse des Fensters bzw. Frames
	Quelle: http://www.quirksmode.org/viewport/compatibility.html (leicht modifiziert)
*/
function getWindowSize() {
	if (self.innerHeight) {
		return {
			x:self.innerWidth,
			y:self.innerHeight
		};
	} else if (document.documentElement && document.documentElement.clientHeight) {
		return {
			x:document.documentElement.clientWidth,
			y:document.documentElement.clientHeight
		};
	} else {
		return {
			x:document.body.clientWidth,
			y:document.body.clientHeight
		};
	}
}

/*
	Ermittle die Scrollposition des Fensters bzw. Frames
	Quelle: http://www.quirksmode.org/viewport/compatibility.html (leicht modifiziert)
*/
function getWindowOffset() {
	if (self.pageXOffset) {
		return {
			x:self.pageXOffset,
			y:self.pageYOffset
		};
	} else if (document.documentElement && document.documentElement.scrollTop) {
		return {
			x:document.documentElement.scrollLeft,
			y:document.documentElement.scrollTop
		};
	} else {
		return {
			x:document.body.scrollLeft,
			y:document.body.scrollTop
		};
	}
}

/*
	Ersetze den Text des ersten Textknoten oder, falls kein Textknoten existiert,
	fuege einen neuen Textknoten hinzu.
*/
function setText(node,txt) {
	var txtobj = document.createTextNode(txt);
	if (node.hasChildNodes()) {
		for (var i=0; i<node.childNodes.length; i++) {
			if (node.childNodes[i].nodeType == 3) {
				node.replaceChild(txtobj,node.childNodes[i]);
				return;
			}
		}
	}
	node.appendChild(txtobj);
}

/*
	Liefert den Text des ersten Textknoten.
	Falls kein Textknoten existiert, wird:
	- bei emptystr = false: null zurueckgegeben
	- bei emptystr = true: ein Leerstring zurueckgegeben
*/
function getText(node,emptystr) {
	if (node.hasChildNodes()) {
		for (var i=0; i<node.childNodes.length; i++) {
			if (node.childNodes[i].nodeType == 3)
				return node.childNodes[i].data;
		}
	}
	return emptystr ? '': null;
}

/*
	Liefert rekursiv den Text aller enthaltenen Textknoten.
	<br>-Knoten werden dabei in Zeilenumbrueche umgewandelt.
	Falls kein Textknoten existiert, wird:
	- bei emptystr = false: null zurueckgegeben
	- bei emptystr = true: ein Leerstring zurueckgegeben
*/
function getTextContent(node,emptystr) {
	if (!node.hasChildNodes())
		return emptystr ? '' : null;
	var str = '';
	for (var i=0; i<node.childNodes.length; i++) {
		switch (node.childNodes[i].nodeType) {
			case 3: {
				str += node.childNodes[i].data;
				break;
			}
			case 1: {
				if (node.childNodes[i].nodeName == 'BR') {
					str += '\n';
				} else if (node.childNodes[i].hasChildNodes()) {
					str += getTextContent(node.childNodes[i]);
				}
				break;
			}
		}
	}
	return str;
}

/*
	Allen Sonderzeichen von regulaeren Ausdruecken im String ein "\" voranstellen
*/
function RegExpFormat(str) {
	var re = new RegExp('([\\[\\]\\{\\}\\(\\)\\.\\^\\$\\?\\+\\*\\|\\-\\\\])','g');
	return String(str).replace(re,'\\$1');
}

/*
	Ersetze Platzhalter innerhalb eines String durch Text
*/
function printvar(str) {
	var ref;
	for (var i=1; i<arguments.length; i++) {
		// unbedingte Platzhalter einsetzen
		str = str.replace(new RegExp("\\$\\{" + i + "\\}","g"),arguments[i]);
	}
	for (var i=1; i<arguments.length; i++) {
		ref = str;
		// bedingte Platzhalter einsetzen
		str = str.replace(new RegExp("\\$\\{"+i+"="+RegExpFormat(arguments[i])+"\\|([^\\}]*)\\}","g"),"$1");
		if (str == ref) {
			// keine Uebereinstimmungen gefunden (String unveraendert): "else"-Fall einsetzen
			str = str.replace(new RegExp("\\$\\{"+i+"\\?\\|([^\\}]*)\\}","g"),"$1")
		} else {
			// Uebereinstimmungen gefunden (String veraendert): "else"-Fall entfernen
			str = str.replace(new RegExp("\\$\\{"+i+"\\?\\|([^\\}]*)\\}","g"),"")
		}
		// unpassende bedingte Platzhalter entfernen
		str = str.replace(new RegExp("\\$\\{"+i+"=[^\\|]*\\|([^\\}]*)\\}","g"),"");
	}
	return str;
}

function copyToClipboard(s) {
	if (window.clipboardData && clipboardData.setData) {
		clipboardData.setData("Text", s);
		return true;
	}
	if (netscape) {
		// You have to sign the code to enable this or allow the action in about:config by changing
		// user_pref("signed.applets.codebase_principal_support", true);
		netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

		// https://developer.mozilla.org/en/Using_the_Clipboard
		var clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
		if (clipboardHelper) {
			clipboardHelper.copyString(s);
			return true;
		}
	}
	return false;
}

/*
	Ersetzt alle "New Lines" durch ein <br>
*/
function nl2br(str) {
	return str.replace(/\r?\n/g, "<br>");
}

/*
	Inhalt eines Objekt ausgeben. (zu Debug-Zwecken)
	Parameter:
	- obj: auszugebendes Objekt
	- maxstr: Stringausgabe auf diese Laenge kuerzen (Standard: 20; 0=nur Zeichenanzahl ausgeben, -1=unbegrenzt, null=Standard verwenden)
	          String wird trotzdem laenger, wenn der Zusatz ("... [x chars]") laenger waere als der weggelassene Text
	- skip: Array mit Namen von Objekttypen (siehe "typeof"), die nicht ausgegeben werden sollen (z.B. "new Array('function','object')")
*/
function dumpObject(obj,maxstr,skip) {
	if (maxstr == null) maxstr = 20;
	var str = "";
	var append = "";
	var skipObj = new Object();
	if (typeof skip == 'object') {
		for (var i=0; i<skip.length; i++) {
			skipObj[skip[i]] = true;
		}
	}
	for (var f in obj) {
		if (skipObj[typeof obj[f]])
			continue;
		str += f + '=';
		if (typeof obj[f] == 'number') {
			str += obj[f];
		} else if (typeof obj[f] == 'boolean') {
			str += obj[f] ? '<TRUE>' : '<FALSE>';
		} else if (typeof obj[f] == 'string') {
			append = '[' + obj[f].length + ' chars]';
			if (maxstr == 0) {
				str += append;
			} else if (maxstr > 0 && obj[f].length > (maxstr + append.length + 4)) {
				str += "'" + obj[f].substr(0,maxstr) + "'... " + append;
			} else {
				str += "'" + obj[f] + "'";
			}
		} else {
			str += '[' + typeof(obj[f]) + ']';
		}
		str += '\n';
	}
	return str;
}

/*
	Browseruebergreifend einen Eventlistener zu einem Objekt hinzufuegen
*/
function addEvent(obj,type,fn) {
	if (obj.addEventListener) {
		obj.addEventListener(type,fn,false);
	} else if (obj.attachEvent) {
		obj.attachEvent("on"+type,fn);
	}
}

/*
	Aktuelle Scrollposition in einem Formular sichern (um diese "automatisch" nach dem Absenden wiederherstellen zu koennen)
*/
function saveScrollPos(f) {
	var st;
	var sl;
	if (f.__ScrollTop == null) {
		st = fixCreateElement("input",null,"__ScrollTop");
		st.setAttribute('type','hidden');
		f.appendChild(st);
	} else {
		st = f.__ScrollTop;
	}
	if (f.__ScrollLeft == null) {
		sl = fixCreateElement("input",null,"__ScrollLeft");
		sl.setAttribute('type','hidden');
		f.appendChild(sl);
	} else {
		sl = f.__ScrollLeft;
	}
	var off = getWindowOffset();
	st.value = off.y;
	sl.value = off.x;
}

