var XpLib = {
	
	/**
	 * Schreibt String als innerHTML in eine ID
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @param	String		content: Inhalt
	 * @return	boolean		True, wenn Inhalt geschrieben wurde.
	 */
	fillContentById: function (id, content) {
		var obj = this.getObject(id);
		if (typeof(obj) == "object" && content.length > 0){
			obj.innerHTML = content;
			return true;
		} else {
			return false;
		}
	},
	
	
	/**
	 * Holt innerHTML von einer ID und schreibt den Inhalt in eine andere ID
	 * @param	String		idSrc: ID oder Element der Quelle
	 * @param	String		idDest: ID oder Element des Ziels
	 * @return	boolean		True, wenn Inhalt geschrieben wurde.
	 */
	getContentFromIdToId: function (idSrc, idDest){
		var objSrc = this.getObject(idSrc);
		var objDest = this.getObject(idDest);
		if (objSrc && objDest){
			objDest.innerHTML = objSrc.innerHTML;
			return true;
		} else {
			return false;
		}
	},
	
	
	/**
	 * Aendert die Display-Eigenschaft einer ID per FlipFlop auf "block" oder "none".
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @return 	True, wenn "block", false, wenn "none" und 2, wenn Objekt nicht gefunden wurde.
	 */
	showHideById: function (id){
		var obj = this.getObject(id);
		if (obj){
			if (obj.style.display == 'block'){
				obj.style.display = 'none';
				return false;
			} else {
				obj.style.display = 'block';
				return true;
			}
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Aendert die Display-Eigenschaft einer ID mit angegebenem Parameter.
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @param	String		parameter: CSS, welches gesetzt werden soll
	 * @return 	True, wenn Parameter gesetzt wurde und 2, wenn Objekt nicht gefunden wurde.
	 */
	displayById: function (id, parameter){
		var myElement = this.getObject(id);
		if (myElement){
			myElement.style.display = parameter;
			return true;
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Aendert die Klasse eines Objekts/ID wie ein FlipFlop
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @param	String		myClass1: Name der 1. CSS-Klasse
	 * @param	String		myClass2: Name der 2. CSS-Klasse
	 * @param	Boolean		childNode: Soll die CSS-Klasse einem Kindknoten gegeben werden?
	 * @param	childLevel	childLevel: Wenn childNode, welches Child-Level?
	 * @return 	True, wenn Klasse geaendert wurde und 2, wenn Objekt nicht gefunden wurde.
	 */
	changeClassViceVersaById: function (id, myClass1, myClass2, childNode, childLevel){
		var obj = this.getObject(id);
		if (obj){
			if (childNode==true){
				if (obj.childNodes[childLevel]){
					if (obj.childNodes[childLevel].className == myClass1)
						obj.childNodes[childLevel].className = myClass2;
					else {
						obj.childNodes[childLevel].className = myClass1;
					}
				} else {
					return 2;
				}
			} else {
				if (obj.className == myClass1)
					obj.className = myClass2;
				else {
					obj.className = myClass1;
				}
			}
			return true;
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Aendert die Klasse eines Objekts, welche mit einem Klassennamen gesucht wird.
	 * @param	String		tagName: Name des zu suchenden Tags. z. B. "h1".
	 * @param	String		myClass: Name der zu suchenden css-Klasse.
	 * @param	String		myNewClass: Name der neuen CSS-Klasse.
	 * @param	Boolean		childNode: Soll die CSS-Klasse einem Kindknoten gegeben werden?
	 * @param	childLevel	childLevel: Wenn childNode, welches Child-Level?
	 * @return 	True, wenn Klasse geaendert wurde und 2, wenn Objekt nicht gefunden wurde.
	 */
	changeClassByClassName: function (tagName, myClass, myNewClass, childNode, childLevel){
		var objs = this.getElementsByClassName(document, tagName, myClass);
		if (objs.length>0){
			for (i=0;i<objs.length;i++){
				if (childNode==true){
					if (objs[i].childNodes[childLevel]){
						objs[i].childNodes[childLevel].className = myNewClass;
					}
				} else {
					objs[i].className = myNewClass;
				}
			}
			return true;
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Aendert die Klasse eines Objekts, welches als Object oder ID referenziert wird.
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @param	String		cssClass: Name der CSS-Klasse, welcher gesetzt werden soll.
	 * @param	Boolean		childNode: Soll die CSS-Klasse einem Kindknoten gegeben werden?
	 * @param	childLevel	childLevel: Wenn childNode, welches Child-Level?
	 * @return 	True, wenn Klasse geaendert wurde und 2, wenn Objekt nicht gefunden wurde.
	 */
	changeClassById: function (id, cssClass, childNode, childLevel){
		var obj = this.getObject(id);
		if (obj){
			if (childNode==true){
				if (obj.childNodes[childLevel]){
					obj.childNodes[childLevel].className = cssClass;
				}
			} else {
				obj.className = cssClass;
			}
		}
	},
	
	
	/**
	 * Aendert die Klasse eines Objekts, welches als Object oder ID referenziert wird.
	 * Funktioniert wie ein FlipFlop.
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @param	String		cssClass1: Name der CSS-Klasse 1.
	 * @param	String		cssClass2: Name der CSS-Klasse 2.
	 * @param	Boolean		childNode: Soll die CSS-Klasse einem Kindknoten gegeben werden?
	 * @param	childLevel	childLevel: Wenn childNode, welches Child-Level?
	 * @return 	True, wenn Klasse geaendert wurde und 2, wenn Objekt nicht gefunden wurde.
	 */
	changeClassViceVersaById: function (id, cssClass1, cssClass2, childNode, childLevel){
		var obj = this.getObject(id);
		if (obj){
			if (childNode==true){
				if (obj.childNodes[childLevel]){
					if (obj.childNodes[childLevel].className == cssClass1)
						obj.childNodes[childLevel].className = cssClass2;
					else {
						obj.childNodes[childLevel].className = cssClass1;
					}
				}
			} else {
				if (obj.className == cssClass1)
					obj.className = cssClass2;
				else {
					obj.className = cssClass1;
				}
			}
			return true;
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Aendert die Display-Eigenschaft eines Objekts, welches mit einem Klassennamen gesucht wird.
	 * @param	String		tagName: Name des zu suchenden Tags. z. B. "h1".
	 * @param	String		cssClass: Name der zu suchenden css-Klasse.
	 * @param	String		parameter: CSS-Parameter fuer die Display-Eigenschaft.
	 * @param	Boolean		childNode: Soll die CSS-Klasse einem Kindknoten gegeben werden?
	 * @param	childLevel	childLevel: Wenn childNode, welches Child-Level?
	 * @return 	True, wenn Klasse geaendert wurde und 2, wenn Objekt nicht gefunden wurde.
	 */
	 changeDisplayByClassName: function (tagName, cssClass, parameter, childNode, childLevel){
		var objs = this.getElementsByClassName(document, tagName, myClass);
		if (objs.length>0){
			for (i=0;i<objs.length;i++){
				if (childNode==true){
					if (objs[i].childNodes[childLevel]){
						objs[i].childNodes[childLevel].style.display = parameter;
					}
				} else {
					objs[i].style.display = parameter;
				}
			}
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Aendert die Display-CSS-Eigenschaft einer Klasse
	 * @param	String		tagName: Name des zu suchenden Tags. z. B. "h1".
	 * @param	String		cssClass: Name der zu suchenden css-Klasse.
	 * @param	String		parameter: CSS-Parameter fuer die Display-Eigenschaft.
	 * @return	True, wenn Objekte gefunden wurden und geaendert wurden - 2, wenn keine Objekte gefunden wurden.
	 */
	displayByClassName: function (tagName, cssClass, parameter){
		objs = this.getElementsByClassName(document, tagName, cssClass);
		if (objs.length>0){
			for (i=0;i<objs.length;i++){
				objs[i].style.display = parameter;
			}
			return true;
		} else {
			return 2;
		}
	},
	
	
	/**
	 * Nimmt die Groesse eines Objekts und gibt sie einem anderen Objekt
	 * @param	String		idResize: ID oder Element des HTML-Tags, welche die Groesse bekommen soll
	 * @param	String		idGetsize: ID oder Element des HTML-Tags der Quelle
	 * @return	True: geaendert; False: keine ID angegeben/Objekt nicht vorhanden; 2: ID/Objekt nicht gefunden.
	 */
	sameSizeById: function (idResize, idGetsize){
		if (idResize && idGetsize){
			var my_element_getsize = this.getObject(idGetsize);
			var my_element_resize = this.getObject(idResize);
			if (my_element_getsize && my_element_resize){
				my_element_resize.style.width = my_element_getsize.offsetWidth+"px";
				my_element_resize.style.height = my_element_getsize.offsetHeight+"px";
				return true;
			} else {
				return 2;
			}
		}
		return false;
	},
	
	
	/**
	 * Hilfs-Methoden fuer eine Klappnavigation (Wird nur gebraucht weil der IE keinen Hover auf LI kennt.
	 * @param	String		obj: Objekt
	 * @param	String		css: CSS-Code
	 */
	naviShow: function (obj){
		obj.className += " hover";
	},
	
	naviHide: function (obj, css){
		obj.className = css;
	},
	
	
	/**
	 * Prueft, ob String als Ankerpunkt in der aufgerufenen URL steht.
	 * Beispiel: index.php?id=1#meinAnker
	 * @param	String		str: Zu testender Ankername.
	 * @return	True oder False.
	 */
	checkSectionIsInUrl: function (str){
		var mySection = str;
		var mySectionUrl = location.href.substr(location.href.length-mySection.length, mySection.length);
		return (mySection == mySectionUrl) ? true : false;
	},
	
	
	/**
	 * Stellt ein Element transparent dar
	 * @param	String		element: Name eines Elements: ID, CSS-Klasse, Tag, Name
	 * @param	String		percent: Transparenz
	 */
	trans: function (element, percent) {
		var i;
		var count;
		var objStyle;
		var filterValue;
		var opacityValue;
		
		if(document.getElementById) {
			
			if(typeof(element) == "object" && element){
				obj = element;
			} else if (document.getElementsByName(element) && document.getElementsByName(element)[0]){
				obj = document.getElementsByName(element);
			} else if (document.getElementById(element)){
				obj = document.getElementById(element);
			} else if (getElementsByClassName(document, "*", element)){
				obj = getElementsByClassName(document, "*", element);
			} else if (document.getElementsByTagName && document.getElementsByTagName(element) && document.getElementsByTagName(element)[0]){
				obj = document.getElementsByTagName(element);
			} else {
				obj = false;
			}
			
			if (obj) {
				percent = (typeof(percent) == "undefined") ? 50 : 100-percent;
				filterValue = "Alpha(opacity="+percent+")";
				opacityValue = ""+percent/100;
				count = (obj.length) ? obj.length : 1;
				for(i=0; i<count; i++) {
					objStyle = (obj.length) ? obj[i].style : obj.style;
					objStyle.filter = filterValue;
					objStyle.MozOpacity = opacityValue;
					objStyle.KhtmlOpacity = opacityValue;
					objStyle.opacity = opacityValue;
				}
			}
		}
	},
	
	
	/**
	 * Gibt einem Element eine CSS-Klasse nach der Ueberpruefung zweier Werte
	 * @param	String		id: ID oder Element des HTML-Tags.
	 * @param	String		cssClassBigger: CSS-Klasse, wenn testHeight kleiner als myHeight
	 * @param	String		cssClassSmaller: CSS-Klasse, wenn testHeight groesser als myHeight
	 * @param	Int			myHeight: Wert 1
	 * @param	Int			testHeight: Wert 2
	 */
	writeClassOnSizeById: function (id, cssClassBigger, cssClassSmaller, myHeight, testHeight){
		var obj = this.getObject(id);
		if (typeof(obj) == "object"){
			if (myHeight > testHeight){
				obj.className = cssClassBigger;
				return true;
			} else {
				obj.className = cssClassSmaller;
				return true;
			}
		}
		return false;
	},
	
	
	/**
	 * Gibt die Hoehe des inneren Bereichs des Fensters zurueck
	 */
	getWindowHeight: function (){
		if (window.innerHeight) {
			return window.innerHeight;
		} else if (document.body && document.body.offsetHeight) {
			return document.body.offsetHeight;
		} else {
			return false;
		}
	},
	
	
	/**
	 * Gibt die Breite des inneren Bereichs des Fensters zurueck
	 */
	getWindowWidth: function (){
		if (window.innerWidth) {
			return window.innerWidth;
		} else if (document.body && document.body.offsetWidth) {
			return document.body.offsetWidth;
		} else {
			return false;
		}
	},
	
	
	/**
		BEGIN: Bugfix-Funktionen
	*/
	
	/**
	 * Der IE und aeltere Browser kennen das CSS "empty-cells: show;" nicht - oder der Wert steht per Default auf "hidden".
	 * Dafuer kann man diese Funktion benutzen um leere TD zu fuellen.
	 */
	fillEmptyTD: function (id, fillStr, onlyIE){
		if (onlyIE && navigator.appName.indexOf("Microsoft") == -1 && navigator.appVersion.indexOf("MSIE") == -1) {
			return false;
		}
		
		if (fillStr == "") fillStr = "&nbsp;";
		var myReturn = false;
		
		if (id){
			var myElement = this.getObject(id);
			if (myElement.innerHTML == "") {
				myElement.innerHTML = fillStr;
				myReturn = true;
			}
		} else {
			var arrElements = document.getElementsByTagName("td");
			for(var j=0; j<arrElements.length; j++){
				oElement = arrElements[j];
				if (this.trim(oElement.innerHTML) == "") {
					oElement.innerHTML = fillStr;
					myReturn = true;
				}
			}
		}
		
		return myReturn;
	},
	
	
	/**
	 * Ja nee ist klar, ne?
	 */
	minHeightIE6: function (id, targetHeight){
		if (navigator.appName.indexOf("Microsoft") >= 0 && navigator.appVersion.indexOf("MSIE 6") >= 0){
			if (id && targetHeight) {
				var my_element = this.getObject(id);
				if (my_element && my_element.offsetHeight < targetHeight){
					my_element.style.height = targetHeight+'px';
					return true;
				}
			}
			
		}
		return false;
	},
	
	
	/**
	 * Ja nee ist klar, ne?
	 */
	minWidthIE6: function (id, targetWidth){
		if (navigator.appName.indexOf("Microsoft") >= 0 && navigator.appVersion.indexOf("MSIE 6") >= 0){
			if (id && targetWidth) {
				var my_element = this.getObject(id);
				if (my_element && my_element.offsetWidth < targetWidth){
					my_element.style.width = targetWidth+'px';
					return true;
				}
			}
			
		}
		return false;
	},
	
	/**
		END: Bugfix-Funktionen
	*/
	
	
	/**
		START: Hilfs-Funktionen
	*/
	
	/**
	 * Manche Browser kennen "getElementsByClassName" nicht
	 * @param	Object		oElm: Element, wo gesucht werden soll, wahrscheinlich "document"
	 * @param	String		strTagName: Bezeichner des HTML-Tags. z. B. "h1"
	 * @param	String		oClassNames: Name der CSS-Klasse, die gesucht wird.
	 * @return 	Array mit den Objekten.
	*/
	getElementsByClassName: function (oElm, strTagName, oClassNames){
		var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
		var arrReturnElements = new Array();
		var arrRegExpClassNames = new Array();
		if(typeof oClassNames == "object"){
			for(var i=0; i<oClassNames.length; i++){
				arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
			}
		}
		else{
			arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
		}
		var oElement;
		var bMatchesAll;
		for(var j=0; j<arrElements.length; j++){
			oElement = arrElements[j];
			bMatchesAll = true;
			for(var k=0; k<arrRegExpClassNames.length; k++){
				if(!arrRegExpClassNames[k].test(oElement.className)){
					bMatchesAll = false;
					break;
				}
			}
			if(bMatchesAll){
				arrReturnElements.push(oElement);
			}
		}
		return (arrReturnElements)
	},
	
	
	/**
	 * Es gibt keine Trim-Funktion bei JS - aber ein replace
	 */
	trim: function (str) {
		return str.replace(/^\s+/, '').replace(/\s+$/, '');
	},
	
	
	/**
	 * Prueft, ob es ein Objekt/Element ist im DOM und gibt es zurueck, ansonsten wird nach einer ID gesucht
	 * @param	String		id: ID oder Element des HTML-Tags
	 * @param	String		content: Inhalt
	 * @return	boolean		True, wenn Inhalt geschrieben wurde.
	 */
	getObject: function (obj){
		if (typeof(obj) == "object") {
			return obj;
		}
		if (document.getElementById(obj)){
			return document.getElementById(obj);
		} else {
			return false;
		}
	}
	
	/**
		END: Hilfs-Funktionen
	*/
}


/*
	ACHTUNG:
	Bei allen Funktionen, wo man als Objekt-Referenz childNodes benutzt, ist es wichtig, dass vor dem ChildNode kein Leerzeichen oder anderes steht. Internet Explorer zaehlt den Leerraum nicht mit, andere Browser schon. a.childNodes[0].innerHTML bei "<div id="a"> <span>content</span></div>" ist im Explorer "content" und bei anderen Browsern " ".
*/


function XpLibXpFold(myElement){
	if (myElement.nextSibling.style.display == 'none'){
		myElement.nextSibling.style.display='block'
		myElement.className = 'xpFoldButtonAct';
	} else {
		myElement.nextSibling.style.display='none'
		myElement.className = 'xpFoldButton';
	};
}

function XpLibDisplayInnerByClassName(object, myClass, myInnerClass, parameter){
	myClasses = getElementsByClassName(document, object, myClass);
	for (i=0;i<myClasses.length;i++){
		myInnerClasses = getElementsByClassName(myClasses[i], object, myInnerClass);
		for (ii=0;ii<myInnerClasses.length;ii++){
			myInnerClasses[ii].style.display = parameter;
		}
	}
}

function XpLibXpFoldHideFirstHeadline(object, myClass, myInnerClass){
	myClasses = getElementsByClassName(document, object, myClass);
	for (i=0;i<myClasses.length;i++){
		myInnerClasses = getElementsByClassName(myClasses[i], object, myInnerClass);
		if (myInnerClasses[0]) myInnerClasses[0].style.display = 'none';
	}
}


/**
 * Function : dump()
 * Arguments: The data - array,hash(associative array),object
 *    The level - OPTIONAL
 * Returns  : The textual representation of the array.
 * This function was inspired by the print_r function of PHP.
 * This will accept some data as the argument and return a
 * text that will be a more readable version of the
 * array/hash/object that is given.
 *
 * 1000thx to http://binnyva.blogspot.com/2005/10/dump-function-javascript-equivalent-of.html
 */
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += ".&nbsp;";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects
		for(var item in arr) {
			var value = arr[item];
	
			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...<br />";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"<br />";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
} 


/**
BEGIN Trace
*/
var traceIt = false;
var traceInt = 0;
function initTrace(){
	traceInt = 0;
	traceIt = true;
	$("body").append('<div id="trace"><div class="header">TRACE</div><div class="entries"><!-- --></div>');
	$("#trace").draggable();
}

function trace(str){
	if (traceIt){
		traceInt++;
		var css = (traceInt.int == 1) ? "entry first" : "entry";
		$("div#trace div.entries").prepend('<div class="'+css+'"><tt>('+traceInt+') '+str+'</tt></div>');
	}
}

/**
END Trace
*/


/**
Ist "str" als Sprungmarke im URL vorhanden?
*/
function sectionInUrl(str){
	var mySectionUrl = location.href.substr(location.href.length-str.length, str.length);
	return (str == mySectionUrl) ? true : false;
}


/**
Zaehlt die Elemente in einem Object
*/
function objCount(obj){
	var objCount = 0;
	for (_obj in obj) objCount++;
	return objCount;
}


/**
BEGIN Lade-Animation
*/
var loader = {
	selector: {
		parent: "body",
		bg: "loaderBg654684",
		loader: "loader65465"
	},
	
	value: "loading ...",
	
	css: {
		bg: {
			position: "absolute",
			'z-index': 10000,
			top: 0,
			left: 0,
			width: null,
			height: null,
			background: "#000",
			opacity: .8
		},
	
		loader: {
			position: "absolute",
			'z-index': 10001,
			top: null,
			left: null,
			color: "#fff"
		}
	},
	
	act: function(params) {
		
		if(typeof(params) == 'object') {
			for(var item in params) {
				var value = params[item];
				loader[item] = value;
			}
		}
		
		jQuery(document).ready(
			function(){
				
				if (!$(loader.selector.parent+" "+"div#"+loader.selector.bg).length) {
					$(loader.selector.parent).append('<div id="'+loader.selector.bg+'"><!-- --></div>');
					
					if (loader.css.bg.width == null) loader.css.bg.width = $(loader.selector.parent).width();
					if (loader.css.bg.height == null) loader.css.bg.height = $(loader.selector.parent).height();
					
					$("#"+loader.selector.bg).css(loader.css.bg);
				}
				
				if (!$(loader.selector.parent+" "+"div#"+loader.selector.loader).length) {
					$(loader.selector.parent).append('<div id="'+loader.selector.loader+'">'+loader.value+'</div>');
					
					if (loader.css.loader.top == null) loader.css.loader.top = $(loader.selector.parent).height() / 2 - $(loader.selector.loader).height() / 2;
					if (loader.css.loader.left == null) loader.css.loader.left = $(loader.selector.parent).width() / 2 - $(loader.selector.loader).width() / 2;
					
					$("#"+loader.selector.loader).css(loader.css.loader);
				} else {
					$("#"+loader.selector.loader).html(loader.value);
				}
			}
		);
	},
	
	deact: function() {
		jQuery(document).ready(
			function(){
				if ($(loader.selector.parent+" "+"div#"+loader.selector.bg).length) $(loader.selector.parent+" "+"div#"+loader.selector.bg).remove();
				if ($(loader.selector.parent+" "+"div#"+loader.selector.loader).length) $(loader.selector.parent+" "+"div#"+loader.selector.loader).remove();
			}
		);
	},
	
	set: function (val) {
		jQuery(document).ready(
			function(){
				if ($(loader.selector.parent+" "+"div#"+loader.selector.loader).length && val) $(loader.selector.parent+" "+"div#"+loader.selector.loader).html(val);
			}
		);
	}
};

/**
END Lade-Animation
*/


/**
BEGIN objectToUrl

Erstellt aus einem Object einen String, den man im URL fuer POST oder GET benutzen kann
*/

var objectToUrl = function(obj, prefix) {
	var objPrefix = (prefix) ? prefix : "urlVar";
	
    var tmpObj = {};

	var buildTmpObject = function(object, prefix) {
		for (var key in object) {
			var postKey = prefix + "[" + key + "]";
			if (typeof(object[key]) == "object") {
				buildTmpObject(object[key], postKey != "" ? postKey : key);
			} else {
				tmpObj[postKey] = object[key];
			}
		}
	};

    buildTmpObject(obj, "");
    
    var result = "";
	for (var key in tmpObj) {
		result += "&"+objPrefix+key+"="+tmpObj[key];
	}
    
    return result;
};

/**
END objectToUrl
*/

