//	JavaScript Document, 27. September 2005 JD
//	Browseruebergreifende Funktionsbibliothek fuer Dynamic HTML (DHTML) und zum Zugriff auf
//	das Document Object Model (DOM).
//	Verwendet und unterstuetzt wird in dieser Reihenfolge das W3C- (ID), ALL- (IE) und
//	LAYER-DOM (N4). Trotz Verfuegbarkeit eines DOMs kann die Implementierung und Unterstuetzung
//	in einem aelteren Browser so mangelhaft sein, dass ein browser- und browserversions-
//	abhaengiger Wechsel auf ein anderes DOM notwendig sein kann.
//
//	Globale Variable:
//		glIdDOM			true/false	W3C-DOM, zumindest in Teilen, verfuegbar
//		glAllDOM		true/false	ALL-DOM, zumindest in Teilen, verfuegbar
//		glLayerDOM		true/false	 N4-DOM, zumindest in Teilen, verfuegbar
//		glDHTML			true/false	dhtml bzw. mindestens 1 DOM ist verfuegbar
//
//	Funktionen:
//		getDocumentElementById ( id... )		Unter Beruecks. des verf. DOM wird ein
//												Document-Objekt geliefert
//		getValueOfDocumentElementById ( id... )	Liefert die angegebene Eigenschaft/Einstellung  
//		setValueOfDocumentElementById ( id... )	Aendert die angegebene Eigenschaft/Einstellung
//
//		setVisibility ( id, sichtbar )			Aendert die Sichtbarkeit
//		setFocus ( )							Setzt den Fokus auf das erste Eingabefeld
//		setColor ( )							Neue Vordergrundfarbe setzen.
//
//	Wenn eine Unterstuetzung des N4 erforderlich ist, muss die id bei verschachtelten
//	Objekten als array angegeben werden, siehe Beschr. zu getDocumentElementById.
//
	//	Konstante zeigt die Verfuegbarkeit dieses Moduls an, wird am Ende auf true gesetzt.
	//	Abfrage mittels	"typeof(window['DOM_JS']) != 'undefined'" oder
	//					"if(typeof(window.DOM_JS) == 'undefined' || DOM_JS == false) alert('dom.js fehlt');"
var DOM_JS	= false;
	//	Erstmal feststellen, was der Browser so alles kann, dabei wird ein Browser-Bug im
	//	Netscape 4.x beruecksichtigt, der die DOM-Abfrage (nur) bei nachgeladenen Scripts
	//	verhindert.

var glIdDOM		= (document.getElementById)	? true : false;
var glAllDOM	= (document.all)			? true : false;
var glLayerDOM	= (document.layers)			? true : (
					(navigator.appName.indexOf('Netscape') != -1 &&
					 parseInt(navigator.appVersion) == 4)
						? true : false
				  );
	//	DHTML ist verfuegbar, wenn mindestens ein DOM-Modell unterstuetzt wird.
	//	(Diese Variable wird zur Zeit nicht verwendet)
var glDHTML = (glIdDOM || glAllDOM || glLayerDOM);

	//	OBJECT	getDocumentElementById(STRING (,INT oder ARRAY) [,BOOLEAN])
	//
	//	Erfordert: JavaScript 1.1
	//	Unter Beruecksichtigung des verfuegbaren DOM wird die Adresse eines Elements
	//	zurueckgeliefert, im Fehlerfall ein null-Zeiger.
	//	Durch Angabe und das Setzen des optionalen zweiten bzw. letzten Funktionsparameters
	//	kann bei dem ID- und ALL-DOM auch gleich die style-Ebene adressiert werden, um bestimmte
	//	Attribute wie 'visibility' browserunabhaengig ansprechen zu koennen. Dabei muessen aber
	//	ggf. browserabhaengige Wertzuweisungen (show/hide bzw. visible/hidden) beachtet werden.
	//
	//	Das Layer-DOM wird als einziges Modell vom N4 unterstuetzt, der zudem verlangt, dass
	//	verschachtelte Objekte ueber weitere layer-adressiert werden. Beispiel:
	//	"<div id='a1'>Hallo Welt<div id='b1'><img src='b.gif'></div></div>" 
	//	Hier wird mittels "document.layers['a1'].layers['b1']" der innere Bereich b1 adressiert.
	//	Um auch bei verschachtelten Objekten zum N4 kompatible zu sein, muss die komplette
	//	Verschachtelungshierarchie als array im ersten Parameter uebergeben werden.
	//	Beispiel: "var ids = new Array("a1","b1");var obj = getDocumentElementById(ids, true);"

function getDocumentElementById( inId ) {
	var inStil	= (arguments.length == 1) ? false : (arguments[arguments.length - 1] == true);
	var objId	= typeof(inId) != "object" ? inId : inId[inId.length -1];
	var	outObj;

	if( glIdDOM ) {
		outObj = document.getElementById('' + objId + '');
		if( inStil && outObj != null ) outObj = outObj.style;
	} else
	if( glAllDOM ) {
		outObj = document.all['' + objId + ''];
		if( inStil && outObj != null ) outObj = outObj.style;
	} else
	if( glLayerDOM ) {
		if( typeof(inId) != "object" ) {
			outObj = document.layers['' + objId + ''];
		} else {
			outObj = document;
			for(idx = 0;idx < inId.length && outObj != null;idx++) {
				outObj = outObj.layers['' + inId[idx] + ''];
			}
		}
	} else {
		outObj = null;
	}

	return	outObj;
} // getDocumentElementById

	//	STRING	getValueOfDocumentElementById ( STRING (,INT oder ARRAY) [, STRING] )
	//
	//	Verwendet "getDocumentElementById", um per DHTML bzw. DOM eine Eigenschaft oder
	//	eine Einstellung eines Objektes zu ermitteln, die durch den zweiten, optionalen
	//	Funktionsparameter zu spezifizieren ist.
	//
	//	An einigen Stellen werden bekannte Browser Bugs und Sonderheiten beruecksichtigt:
	//	Opera-5		Keine Unterstuetzung fuer offsetWidth und offsetHeight, .clip.width und
	//				height verursachen Fehlermeldungen.
	//	N4			Die PC und Mac Version aktzeptieren bei Zuweisungen zwar die Standards
	//				"visible" und "hidden" liefern beim Lesen aber "show" und "hide", was
	//				hier konvertiert wird.

function getValueOfDocumentElementById( inId ) {

	var property	= arguments.length < 2 ? "value" : arguments[1]
	var	wert		= "";
	var	obj			= null;

	switch( property ) {
		case "checked":			wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.checked;					break;
		case "color":			wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.color;					break;	//ok
		case "data":			wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.firstChild.data;			break;	// + IE, Safari, iCab, Opera, Shiira  - Netscape 7.2, Mozilla, Firefox, Camino
		case "defaultValue":	wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.defaultValue;				break;
		case "display":			wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.display;					break;
		case "fontSize":		wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.fontSize;					break;	//ok
		case "innerText":		wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.innerText;				break;	// + IE, Safari, iCab, Opera, Shiira  - Netscape 7.2, Mozilla, Firefox, Camino
		case "left":			wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.left;						break;	//ok
		case "length":			wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.length;					break;
		case "lengthIndex":		wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.options.length;			break;
		case "selectedIndex":	wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.options.selectedIndex;	break;
		case "top":				wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.top;						break;	//ok
		case "value":			wert = (obj = getDocumentElementById(inId, false)) == null ? '' : obj.value;					break;
		case "visibility":		wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.visibility;						//ok-hide/hidden,show/visible
			switch( "" + wert + "" ) {
				case "show":
				case "SHOW": wert = "visible"; break;
				case "hide":
				case "HIDE": wert = "hidden";  break;
			}
			break;
		case "width":			wert = (obj = getDocumentElementById(inId, true )) == null ? '' : obj.width;					break;

		case "offsetWidth":
			obj = getDocumentElementById(inId, false);
			if( obj != null && !(wert = obj.offsetWidth) &&
			   (!glLayerDOM || !(wert = obj.clip.width)) ) wert ="0";
			break;
		case "offsetHeight":
			obj = getDocumentElementById(inId, false);
			if( obj != null && !(wert = obj.offsetHeight) &&
			   (!glLayerDOM || !(wert = obj.clip.height)) ) wert ="0";
			break;
			//	offsetTop und offsetLeft werden ohne style ausgelesen, top, left, pixelTop
			//	und pixelLeft mit style.
		case "offsetTop":
			obj = getDocumentElementById(inId, false);
			if( obj != null ) {
				if( !(wert = obj.offsetTop) ) {
					obj = getDocumentElementById(inId, true);
					if( obj != null && !(wert = obj.top) && !(wert = obj.pixelTop) ) wert ="0";
				}
			}
			break;
		case "offsetLeft":
			obj = getDocumentElementById(inId, false);
			if( obj != null ) {
				if( !(wert = obj.offsetLeft) ) {
					obj = getDocumentElementById(inId, true);
					if( obj != null && !(wert = obj.left) && !(wert = obj.pixelLeft) ) wert ="0";
				}
			}
			break;

		default:
			alert("Falsche Funktionsparameter fuer get: " + inProperty);
			break;
	}

	return wert;
} // getValueOfDocumentElementById

	//	STRING	setValueOfDocumentElementById ( STRING (,INT oder ARRAY), STRING, STRING )
	//
	//	Verwendet "getDocumentElementById", um per DHTML bzw. DOM eine Eigenschaft oder
	//	eine Einstellung eines Objektes neu zu setzen.

function setValueOfDocumentElementById( inId, inProperty, inValue ) {
	var	obj = null;
	switch( inProperty ) {
		case "checked":			if( (obj = getDocumentElementById(inId, false)) != null ) obj.checked				= inValue;	break;
		case "color":			if( (obj = getDocumentElementById(inId, true )) != null ) obj.color					= inValue;	break;	//ok
		case "data":			if( (obj = getDocumentElementById(inId, false)) != null ) obj.firstChild.data		= inValue;	break;	//ok
		case "defaultValue":	if( (obj = getDocumentElementById(inId, false)) != null ) obj.defaultValue			= inValue;	break;
		case "display":			if( (obj = getDocumentElementById(inId, true )) != null ) obj.display				= inValue;	break;
		case "fontSize":		if( (obj = getDocumentElementById(inId, true )) != null ) obj.fontSize				= inValue;	break;	//ok
		case "innerText":		if( (obj = getDocumentElementById(inId, false)) != null ) obj.innerText				= inValue;	break;	//ok
		case "left":			if( (obj = getDocumentElementById(inId, true )) != null ) obj.left					= inValue;	break;	//ok
		case "length":			if( (obj = getDocumentElementById(inId, false)) != null ) obj.length				= inValue;	break;
		case "lengthIndex":		if( (obj = getDocumentElementById(inId, false)) != null ) obj.options.length		= inValue;	break;
		case "selectedIndex":	if( (obj = getDocumentElementById(inId, false)) != null ) obj.options.selectedIndex	= inValue;	break;
		case "top":				if( (obj = getDocumentElementById(inId, true )) != null ) obj.top					= inValue;	break;	//ok
		case "value":			if( (obj = getDocumentElementById(inId, false)) != null ) obj.value					= inValue;	break;
		case "visibility":		if( (obj = getDocumentElementById(inId, true )) != null ) obj.visibility			= inValue;	break;	//ok-hide/hidden,show/visible
		case "offsetWidth":		if( (obj = getDocumentElementById(inId, true )) != null ) obj.offsetWidth			= inValue;	break;
		case "offsetHeight":	if( (obj = getDocumentElementById(inId, true )) != null ) obj.offsetHeight			= inValue;	break;
		case "width":			if( (obj = getDocumentElementById(inId, true )) != null ) obj.width					= inValue;	break;	//ok

		default:
			alert("Falsche Funktionsparameter fuer set: " + inProperty);
			break;
	}
} // setValueOfDocumentElementById

//	VOID setVisibility(STRING (,INT oder ARRAY), BOOLEAN)
//
//	Aendert die Sichtbarkeit eines Objektes.
//	(Eine Anpassung an show/hide fuer den N4 (PC) und N6 (Mac) sollte nicht notwendig sein, da
//	dieser bei Zuweisungen auch visible/hidden versteht.

function setVisibility(inId, inSichtbar) {
	var action = inSichtbar ? "visible" : "hidden";
	setValueOfDocumentElementById(inId, "visibility", action);
} // setVisibility

//	VOID	setFocus ( VOID [,STRING] )
//
//	Setzt den Fokus auf das erste Eingabefeld bzw. auf das optional angegebene.

function setFocus( ) {
	if( arguments.length > 0 ) {
		var obj = getDocumentElementById(arguments[0]);
		if( obj != null && obj.focus ) obj.focus();
	} else
	if( document.forms.length > 0 ) {
		var field = document.forms[0];
		for(i = 0; i < field.length; i++) {
			if( (field.elements[i].type == "text")
			 || (field.elements[i].type == "textarea")
			 || (field.elements[i].type.toString().charAt(0) == "s")
			 ) {
				document.forms[0].elements[i].focus();
				break;
			}
		}
	}
} // setFocus

//	VOID setColor(STRING (,INT oder ARRAY), STRING)
//
//	Aendert die Vordergrundfarbe eines Objektes.
//
//	Probleme mit CSS Klassen:
//	Wenn per css die Farbe einer Klasse explizit gesetzt wurde, wirkt sich die Farbaenderung
//	durch diese Funktion nicht aus, da die CSS-Klasse Vorrang hat.
//	Beispiel "label {color:black;}". Abhilfe: Farbvorgaben fuer aenderbare Tags vermeiden oder
//	separate Objekte anlegen, z. B. ".label {color:black;}" oder "#label {color:black;}".

function setColor(inId, inColor) {
	setValueOfDocumentElementById(inId, "color", inColor);
} // setColor

//	STRING getInnerText (STRING (,INT oder ARRAY))
//
//	Liefert den Textinhalt ('Mein Text') eines tags,
//	z. B. <p>Mein Text</p> oder <p><strong>Mein</strong> Text</p>
//

function getInnerText( inId ) {
	var txt = getValueOfDocumentElementById(inId, "innerText");
	if( (''+txt) == 'undefined' ) {
		txt = internGetChildData( getDocumentElementById(inId, false) );
	}
	return	txt;
} // getInnerText

//	STRING internGetChildData( object )
//	Interne Unterfunktion von getInnerText zur rekursiven Ermittlung von Textdaten.

function internGetChildData( inChild ) {
	var text	= '';
	if( '' + inChild.data != 'undefined' ) text += inChild.data;
	if( inChild.hasChildNodes() ) {
		var nodes	= inChild.childNodes;
		var anz		= inChild.childNodes.length;
		var idx;
		for(idx = 0;idx < anz;idx++) {
			text += internGetChildData(inChild.childNodes[idx]);
		}
	}
	return text;
} //internGetChildData

//	STRING getSpeechData( STRING )
//	Liefert zu einem Schluesseltext sprachspezifische Daten oder den Schluesseltext.

function getSpeechData( inDescription ) {
	if(	(typeof(glSprachspezifischeDaten) == 'object' &&
		 typeof(glSprachspezifischeDaten[inDescription]) != 'undefined')
	) {
		return glSprachspezifischeDaten[inDescription];
	}

	var	txt;
	switch( inDescription ) {
		case 'FEHLER_PFLICHTFELDER_PRUEFEN':	txt = 'Bitte folgende Eingabefelder %u00fcberpr%u00fcfen';	break;
		case 'FEHLER_BIBLIOTHEK_FEHLT':			txt = 'Bibliothek muss vorab geladen werden!';				break;
		case 'FEHLER_EINGABE_UNGUELTIG':		txt = '(ung%u00fcltig)';									break;
		case 'FEHLER_EINGABE_LEER':				txt = '(leer)';												break;
		default:								txt = inDescription;										break;
	}

	return	txt;
} //getSpeechData

//	Konstante zeigt die Verfuegbarkeit dieses Moduls an.
DOM_JS = true;
//	Aenderungsstand:
//	2004-08-17 Erstellung, Juergen Deisenroth
//	2004-11-04 Abfragen nach undefinierten Objekte (null) eingefuegt.
//	2005-03-15 getSpeechData-Funktion eingebunden.
//	2005-07-27 getSpeechData: utf-8 Kodierung eingefuegt, um Server-Fehler bei html zu unterbinden.
//	2005-09-27 internGetChildData: Abfrage nach hasChildNodes() ergaenzt zwecks Kompatibilitaet zu Opera 6.03 (Mac,de)
//	2005-09-27 Letzte Aenderung
