// Einfacher Browser check
var NS = (navigator.appName == "Netscape");
// Timer für das anzeigen der Error Meldung
var errorTimer;
// Boolsche Werte aus de.bullex.Boolean
var boolstr = new Array('TRUE', 'JA', 'WAHR', '1', 'OFF',
  'FALSE', 'NEIN', 'FALSCH', '0', 'ON');
// Flagge, die von __checkForm gesetzt wird, um zu zeigen dass die
// Events zum Prüfen des Formulars aufgerufen werden
var calledByCheckForm = false;
// Flagge, die von Check-Methoden gesetzt wird und das Ergebnis
// der Prüfung angeben. Aufgrund der Event-Verarbeitung von
// Return-Werten kann dies nicht als Rückgabewert der Funktion
// implementiert werden
var lastCheckValid;
// Liste der verwendeten Reiter
var tabList;
// Letzter aktiver Reiter
var currentTab;
// Forms initialisiert
var __initDone = false;
// Liste der bereits abgefragten Form-Elemente
var __namedFormElements = new Object();

var _MS;

// Öffnet das Popup
function openCentered(url, name, width, height, options) {
        var x = (screen.width - width) / 2;
        var y = (screen.height - height) / 2;
        win = window.open(url, name, "width="+width+",height="+height+",top="+y+",left="+x+","+options);
        win.focus();
}

// Konvertiert einen Fliesskommazahl-String von deutsch nach englisch
function __numeric_de2en(numstr) {

  for(i = 0 ; i < numstr.length ; i++) {
    if (numstr[i] == ',')
      numstr[i] = '.';
  }
  return numstr;
}

// Prüft ob der übergebene Wert numerisch ist
function isNumeric(strString, mustbeint)
   //  check for valid numeric strings
   {
   var strValidChars = mustbeint ? "01234567890-" : "0123456789.,-";
   var strChar;
   var blnResult = true;

   if (strString.length == 0) return false;

   //  test strString consists of valid characters listed above
   for (i = 0; i < strString.length ; i++) {
      strChar = strString.charAt(i);
      if (strValidChars.indexOf(strChar) == -1) {
         return false;
      }
   }
   return true;
}

// Zeigt Info oder Error Meldungen an
function showInfoOrError(node, hasError, msg, defaultClassName,  errorClassname) {
//    lastCheckValid = false;
//	if(true) return;

  if (defaultClassName == '') {
  	defaultClassName = node.type;
  }

  // Alle Eingabefelder bestimmen
  var nodes = __getFieldsByName(node.form, node.name);

  var nodeError = node.error;
  if(nodeError == undefined)
  	nodeError = false;

  if(hasError) {
  	if(nodeError) {
	  	node.error = true;
		lastCheckValid = false;
	  	return;
  	}

  	node.error = true;
	lastCheckValid = false;

    // Class für alle Elemente mit diesem Namen setzen
    for(var i=0 ; i<nodes.length ; ++i) {
      if (nodes[i].type)
        nodes[i].className = errorClassname;
      if (node.onCheckError)
        node.onCheckError(node.name,errorClassname);
    }
    if (node.area && node.area.onCheckError) {
      node.area.onCheckError(node.id);
    }

    // Info Icon ausblenden
    var infoIcon = document.getElementById("__" + node.id + "_info_icon");
    if (!infoIcon) {
    	infoIcon = document.getElementById("__" + node.id + "_1_info_icon");
    }
    if(infoIcon) {
      infoIcon.style.display = 'none';
    }
    // Error Icon einblenden
    var errorIcon = document.getElementById('__' + node.id + '_error_icon');
    if (!errorIcon) {
    	errorIcon = document.getElementById('__' + node.id + '_1_error_icon');
    }
    if(errorIcon) {
      errorIcon.style.display = 'inline';
    }

    // Fehlermeldung generieren
    showError(node.id, errorIcon,'',  msg);
    errorTimer = setTimeout("hideError('"+ node.id + "')", 1500);
  } else if(nodeError) {
  	node.error = false;
    for(var i=0 ; i<nodes.length ; ++i) {
      if (nodes[i].type)
        nodes[i].className = defaultClassName;
      if (node.onCheckOk)
        node.onCheckOk(node.name, defaultClassName);
    }
    if (node.area && node.area.onCheckOk) {
      node.area.onCheckOk(node.id);
    }

    // Info Icon einblenden
    var infoIcon = document.getElementById("__" + node.id + "_info_icon");
    if (!infoIcon) {
    	infoIcon = document.getElementById("__" + node.id + "_1_info_icon");
    }
    if(infoIcon) {
      infoIcon.style.display = 'inline';
    }
    // Error Icon ausblenden
    var errorIcon = document.getElementById('__' + node.id + '_error_icon');
    if (!errorIcon) {
    	errorIcon = document.getElementById('__' + node.id + '_1_error_icon');
    }
    if(errorIcon) {
      errorIcon.style.display = 'none';
    }
    hideError(node.id);
    lastCheckValid = true;
  }
}

// Prüft das Formular vor dem absenden
function __checkForm(myForm,showDebug) {
	// showDebug = true;
//alert("Start Check ..."); var _START=new Date(); _MS=0;
//var __START = new Date();
//var __END = new Date(); _MS += (__END.getTime() - __START.getTime());
//var _END=new Date(); var _DUR = _END.getTime() - _START.getTime(); alert("End Check ... duration: "+_MS+"/"+_DUR+" ms."); return false;
  __initFields();
  var ok = true;
  var debug = '';
  var hasFocus = false;
  var lastCheckName;
  var formElements = myForm.elements;
  calledByCheckForm = true;
  for(var i=0; i<formElements.length; i++) {
    var ele = formElements[i];

    // Button werden gar nicht geprüft (wie auch?)
    if (ele.type == 'button') continue;

    // Radio- und Checkboxen müssen nur einmal geprüft werden
    if ((ele.type == "radio" || ele.type=="checkbox") && ele.name == lastCheckName)
    	continue;
	lastCheckName = ele.name;

	lastCheckValid = true;
	var attr;
    if(attr=ele.getAttribute('check') && attr=='false') {
      // Formularelement wird nicht geprüft
    } else if(attr=ele.getAttribute('oncheck')) {
      // Spezielle Methode zum Prüfen eines Formularfeldes
      if (attr!='' && ele.eval) {
        ele.eval(attr);
      }
    } else if(ele.onkeyup!= null) {
      var e = new Object(); e.keyCode=0;
      ele.onkeyup(e);
    } else if(ele.onblur!=null) {
      try {ele.onblur(); } catch(e) { }
    } else if(ele.onclick!= null) {
      ele.onclick();
    } else if(ele.onchange!= null) {
      ele.onchange();
    }

    if (!lastCheckValid) {
    	// alert(ele.name+" = "+lastCheckValid);
        ok = false;
        debug += ele.name+" ";
        if(!hasFocus) {
          try { ele.focus(); } catch(ex) {}
          hasFocus = true;
        }
	}
  }
  calledByCheckForm = false;
  if(!ok) {
    alert('Das Formular enthält Fehler. Bitte prüfe die markierten Felder.');
    if (showDebug) alert('Betroffene Felder: '+debug);
    return false;
  } else {
    return true;
  }
}

// Blendet das Error-Icon ein
function showErrorIcon(id) {
  var errorIcon = document.getElementById('__' + id + '_error_icon');
  if (!errorIcon) {
  	errorIcon = document.getElementById('__' + id + '_1_error_icon');
  }
  if(errorIcon) {
    errorIcon.style.display = 'inline';
  } else {
  }
}

// Blendet das Error-Icon aus
function hideErrorIcon(id) {
  var errorIcon = document.getElementById('__' + id + '_error_icon');
  if (!errorIcon) {
  	errorIcon = document.getElementById('__' + id + '_1_error_icon');
  }
  if(errorIcon) {
    errorIcon.style.display = 'none';
  }
}

// Blendet das Info-Popup ein
function showInfo(id, icon, align) {
  showTipp(id, icon, align, "_info", '');
}

// Blendet das Info-Popup aus
function hideInfo(id) {
  hideTipp(id, "_info");
}

// Blendet da Error-Pupup ein
function showError(id, icon, align, msg) {
  showTipp(id, icon, align, "_error", msg);
}

// Blendet das Error-Popup aus
function hideError(id) {
  hideTipp(id, "_error");
}

// Blendet den Tipp mit der angegebenen suffix aus
function hideTipp(id, suffix) {
  var div = document.getElementById("__" + id + suffix);
  if (!div) {
  	div = document.getElementById("__" + id + "_1" + suffix);
  }
  if(div) {
    div.style.display = 'none';
	var ifrm = document.getElementById('__tipp_ifrm__');
	if (ifrm) {
    	ifrm.style.display = 'none';
	}
  }
}

// Zeigt den Tipp mit der angegebenen suffix an
function showTipp(id, icon, align, suffix, msg) {
  var div = document.getElementById("__" + id + suffix);
  if (!div) {
  	div = document.getElementById("__" + id + "_1" + suffix);
  }

  /*
  var msgElement = document.getElementById("__" + id + suffix + "_msg");
  if(msg && msgElement) {
    msgElement.innerHTML = msg;
  }
  */

  if(!div)
    return;

  if(msg && div) {
    div.innerHTML = msg;
  }

  div.style.display = 'block';

  var top = 0;
  var left = 0;
  if (icon.offsetParent)
  {
    while (icon.offsetParent)
    {
      top += icon.offsetTop;
      left += icon.offsetLeft
      icon = icon.offsetParent;
    }
  }
  else if (icon.x) {
    top += icon.y;
    left += icon.x;
  }

  var winWidth;
  if(document.body.offsetWidth) {
	winWidth = document.body.offsetWidth - 25;
  } else {
	winWidth = window.innerWidth;
  }

  div.style.top = (top - div.offsetHeight - 5) + "px";
  if(align == 'right' || left+div.offsetWidth > winWidth) {
    div.style.left = (left + 20 - div.offsetWidth) + "px";
    div.style.background = 'url(img/bg/r'+suffix+'.gif) no-repeat bottom';
  } else {
    div.style.left = left + "px";
    div.style.background = 'url(img/bg/l'+suffix+'.gif) no-repeat bottom';
  }

  // IFrame unter den Tipp legen, um GUI-Elemente zu verstecken
  var ifrm = document.getElementById('__tipp_ifrm__');
  if (!ifrm) {
	// Beim ersten Aufruf einen IFrame für Tipps anlegen
  	ifrm = document.createElement("iframe");
  	ifrm.style.width = "0px";
  	ifrm.style.height = "0px";
  	ifrm.id = '__tipp_ifrm__';
  	ifrm.frameBorder = 0;
  	ifrm.style.position = 'absolute';
	ifrm.style.zIndex = 99;
  	document.body.appendChild(ifrm);
  }
  div.style.zIndex = ifrm.style.zIndex + 1;
  ifrm.style.left = div.style.left;
  ifrm.style.top = div.style.top;
  ifrm.style.width = div.style.width;
  // ifrm.style.border = "1px solid red";
  if (div.offsetHeight > 0) {
	  ifrm.style.height = (div.offsetHeight - 0) +"px";
  } else {
	  ifrm.style.height = "100px";
  }
  ifrm.style.display = 'block';
}

// Blendet eine Area ein oder aus
function toggleArea(id) {
  var cont = document.getElementById('__' + id + '_area');
  if(cont) {
    if (cont.style.display == 'none')
      cont.style.display = '';
    else
      cont.style.display = 'none';
  }
}
function showArea(id) {
  var cont = document.getElementById('__' + id + '_area');
  if(cont)
    cont.style.display = '';
}
function hideArea(id) {
  var cont = document.getElementById('__' + id + '_area');
  if(cont)
    cont.style.display = 'none';
}
function showTab(id) {
	var tab = document.getElementById(id);
	if (tab && tab.style) {
		if (currentTab)
			currentTab.className='tab';
		tab.className = 'currtab';
		currentTab = tab;
		for(var i=0 ; i<tabList.length ; ++i) {
			if (tabList[i] == id) {
				showArea(tabList[i]);
			} else {
				hideArea(tabList[i]);
			}
		}
	}
}
function initTabs(id, list) {
	tabList = list;
	showTab(id);
	for(var i=0 ; i<list.length ; ++i) {
		var t = document.getElementById('__' + tabList[i] + '_area');
		if (t && t.error) {
			showErrorIcon(tabList[i]);
		}
	}
}




// Umbewegen von Optionen zwischen zwei Select-Listen
function sort_option(a, b) {
	var as = a.getAttribute('sort');
	var bs = b.getAttribute('sort');
	if (as && bs) {
		as = as.toLowerCase();
		bs = bs.toLowerCase();
		return (as < bs) ? -1 : ((as > bs) ? 1 : 0);
	}
	var at = a.text.toLowerCase();
	var bt = b.text.toLowerCase();
	return (at < bt) ? -1 : ((at > bt) ? 1 : (a.value - b.value));
}
function move(fbox, tbox) {
	// Select-Listen suchen
	fbox = document.getElementById(fbox);
	tbox = document.getElementById(tbox);
	if(!tbox || !fbox) {
		alert("Interner Fehler beim Umbewegen von Einträgen: zugrundeliegende Listen nicht gefunden");
		return;
	}

	// Zwei Listen pflegen: ausgewählte und nicht ausgewählte
	var selList = new Array();
	var notselList = new Array();

	// Liste aller bereits in der Ziel-Liste vorhandenen Elemente erstellen
	for(var i=0 ; i<tbox.options.length ; ++i) {
		var opt = new Option();
		opt.value = tbox.options[i].value;
		opt.text = tbox.options[i].text;
		if (tbox.options[i].getAttribute('sort')) {
			opt.setAttribute('sort', tbox.options[i].getAttribute('sort'));
		}
		selList[selList.length] = opt;
	}
	// Quell-Liste aufsplitten in ausgewählte und nicht ausgewählte
	for(var i=0 ; i<fbox.options.length ; ++i) {
		var opt = new Option();
		opt.value = fbox.options[i].value;
		opt.text = fbox.options[i].text;
		if (fbox.options[i].getAttribute('sort')) {
			opt.setAttribute('sort', fbox.options[i].getAttribute('sort'));
		}
		if (fbox.options[i].selected) {
			selList[selList.length] = opt;
		} else {
			notselList[notselList.length] = opt;
		}
	}

	// Listen sortieren
	selList.sort(sort_option);
	notselList.sort(sort_option);

	// Select-Listen neu aufbauen
	fbox.length = 0;
	tbox.length = 0;
	for(var i=0 ; i<notselList.length ; i++) {
		fbox[i] = notselList[i];
	}
	for(var i=0 ; i<selList.length ; i++) {
		tbox[i] = selList[i];
	}

	// Benachrichtigungen
	if (document.createEventObject) {
		try {
			var evt = document.createEventObject();
			evt.move = true;
			tbox.fireEvent("onchange", evt);
			fbox.fireEvent("onchange", evt);
		} catch (e) {
			alert(e);
		}
	} else {
		try {
			var evt = document.createEvent("HTMLEvents");
			evt.initEvent("change", true, true);
			evt.move = true;
			tbox.dispatchEvent(evt);
			evt = document.createEvent("HTMLEvents");
			evt.initEvent("change", true, true);
			evt.move = true;
			fbox.dispatchEvent(evt);
		} catch (e) {
			alert(e);
		}
	}

	// Select Elemente markieren für den onsubmit Event handler
	tbox.selectbeforesubmit = true;
	fbox.selectbeforesubmit = true;
}

function selectAllMoveOptions(e) {
	var from = null;
	if(e.srcElement) {
		form = e.srcElement;
	} else {
		form = e.target;
	}
	for(i=0; i<form.elements.length; i++) {
		var ele = form.elements[i];

		if(ele.getAttribute("selectall")) {
			selectAll(ele.options);
		}
	}
}

function selectAll(box) {
	for(var i=0; i<box.length; i++) {
		box[i].selected = true;
	}
}




// -----------------------------------------------------------------------
// -------------------- Ab hier folgen die JavaSCript Prüfungen ----------
// -------------------- für CGI-Parameter und Validatoren       ----------
// -----------------------------------------------------------------------

// Prüft die Abhängigkeit zu anderen Parametern. Liefert zurück, ob
// der Parameter weiter geprüft werden muss
function __checkDependency(node, depends) {
	// Abhängigkeit lösen
	var depOk = true;
	if (depends) {
		var deplist = depends.split(",");
		for(var i=0 ; i<deplist.length ; ++i) {
			var pos = deplist[i].indexOf('!=');
			if (pos != -1) {
				// Abhängigkeit mit Ungleichheit
				var name  = deplist[i].substring(0, pos);
				var value = deplist[i].substring(pos+2);
				var depval = __getValuesByName(node.form, name);
				for(var j=0 ; j<depval.length ; ++j) {
					if(depval[j] == value) { depOk = false; }
				}
			} else {
				pos = deplist[i].indexOf('=');
				if (pos != -1) {
					// Abhängigkeit mit Gleichheit
					var name  = deplist[i].substring(0, pos);
					var value = deplist[i].substring(pos+1);
					var depval = __getValuesByName(node.form, name);
					var found = false;
					for(var j=0 ; j<depval.length ; ++j) {
						if(depval[j] == value) { found = true; }
					}
					if (!found) {
						depOk = false;
					}
				} else {
					// Abhängigkeit mit Existenz / boolschem Wert
					var depval = __getValuesByName(node.form, deplist[i]);
					if (depval && depval.length>0) {
						for(var j=0 ; j<depval.length ; ++j) {
							if(depval[j]=='' || depval[j]=='0') { depOk = false; }
						}
					} else {
						depOk = false;
					}
				}
			}
		}
	}
	if (!depOk) {
		// Parameter ist gültig, da Abhängigkeit nicht erfüllt ist
		showInfoOrError(node, false, "", "", "error");
	}
	return depOk;
}

// Prüfung für StringCgiParameter
// Es wird lediglich geprüft, ob bei Pflichtfeldern eine Eingabe
// vorhanden ist.
function __checkString(node, field, minval, maxval, depends, evt) {
  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  }

  var hasError = false;
  var values = __getValuesByName(node.form, node.name);
  var msg;

  if(values.length < minval) {
    hasError = true;
    msg = 'Bitte fülle das das Feld "' + field + '" aus.';
  }
  showInfoOrError(node, hasError, msg, "", "error");
}

// Prüfung für StringValidator
// Es wird geprüft, ob die Pflichtfelder ausgefüllt sind und die
// ausgefüllten Felder den vorgegebenen Längenangaben entsprechen
function __checkStringLen(node, field, minlength, maxlength, minval, maxval, depends, evt) {
  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  }

  var value = node.value;
  var values = __getValuesByName(node.form, node.name);
  var hasError = false;
  var msg;

  if(values.length == 0) {
    if(minval > 0 && minlength > 0) {
      hasError = true;
      msg = 'Bitte fülle das Feld "' + field + '" aus.';
    }
  } else {
    if(value.length < minlength) {
      hasError = true;
      msg = 'Das Feld "' + field + '" enthält zu wenig Zeichen. Bitte gib mehr Zeichen ein.';
    } else if(value.length > maxlength) {
      hasError = true;
      msg = 'Das Feld "' + field + '" enthält zu viele Zeichen. Bitte gib weniger Zeichen ein.';
    }

  }
  showInfoOrError(node, hasError, msg, "", "error");
}

// Prüfung NumberCgiParameter
// Es wird geprüft ob es sich um eine (Ganz-)Zahl handelt und ob bei
// Pflichtfeldern eine Eingabe vorhanden ist.
// TODO: Prüfung auf korrektes NumberFormat
function __checkNumber(node, field, mustbeint, minval, maxval, depends, evt) {
  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  }

  var hasError = false;
  var value = node.value;
  var values = __getValuesByName(node.form, node.name);
  var msg;

  if(values.length < minval) {
    hasError = true;
    msg = 'Bitte fülle das Feld "' + field + '" aus.';
  } else if (value != '' && !isNumeric(value, mustbeint)) {
    hasError = 'true';
    msg = 'Bitte gib im Feld "' + field + '" eine gültige Zahl ein.';
  }

  showInfoOrError(node, hasError, msg, "", "error");
}

// Prüfung NumberValidator
// Es wird geprüft ob es sich um eine (Ganz-)Zahl handelt, ob bei
// Pflichtfeldern eine Eingabe vorhanden ist und ob die eingegebene
// Zahl innerhalb des angegeben Wertebereiches liegt
// TODO: Prüfung auf korrektes NumberFormat
function __checkNumberRange(node, field, minValue, maxValue, mustbeint, minval, maxval, depends, evt) {
  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  }

  var hasError = false;
  var value = node.value;
  var values = __getValuesByName(node.form, node.name);
  var msg;

  if(values.length < minval) {
    hasError = true;
    msg = 'Bitte fülle das Feld "' + field + '" aus.';
  } else if (value != '') {
    if (!isNumeric(value, mustbeint)) {
      hasError = 'true';
      msg = 'Bitte gib im Feld "' + field + '" eine gültige Zahl ein.';
    } else {
      var num = Number(__numeric_de2en(value));
      if (isNaN(num)) {
        hasError = 'true';
        msg = 'Bitte gib im Feld "' + field + '" eine gültige Zahl ein.';
      } else if (num < minValue) {
        hasError = 'true';
        msg = 'Das Feld "' + field + '" enthält eine zu kleine Zahl.';
      } else if (num > maxValue) {
        hasError = 'true';
        msg = 'Das Feld "' + field + '" enthält eine zu grosse Zahl.';
      }
    }
  }
  showInfoOrError(node, hasError, msg, "", "error");
}

// Prüfung DateCgiParameter
// Es wird geprüft ob es sich um ein Datum handelt und ob bei
// Pflichtfeldern eine Eingabe vorhanden ist.
function __checkDate(node, field, format, minval, maxval, depends, evt) {
  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  }

  var hasError = false;
  var value = node.value;
  var values = __getValuesByName(node.form, node.name);
  var msg;

  if(values.length < minval) {
    hasError = true;
    msg = 'Bitte fülle das Feld "' + field + '" aus.';
  } else if (values.length>0 && !isDate(value, format)) {
    hasError = 'true';
    msg = 'Bitte gib im Feld "' + field + '" ein gültiges Datum ein.';
  }
  showInfoOrError(node, hasError, msg, "", "error");
}

// Prüfung AgeValidator
// Es wird geprüft ob es sich um ein Datum handelt, ob bei
// Pflichtfeldern eine Eingabe vorhanden ist und ob das erforderliche
// Mindestalter erreicht ist
function __checkAge(node, field, format, minage, minval, maxval, depends, evt) {
  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  }

  var hasError = false;
  var value = node.value;
  var values = __getValuesByName(node.form, node.name);
  var msg;

  if(values.length < minval) {
    hasError = true;
    msg = 'Bitte fülle das Feld "' + field + '" aus.';
  } else {
    var d = getDateFromFormat(value, format);
    if (d == 0) {
      hasError = 'true';
      msg = 'Bitte gib im Feld "' + field + '" ein gültiges Datum ein.';
    } else {
      d = new Date(d);
      var now = new Date();
      var age = 0;

      if ( (d.getMonth() < now.getMonth())
        || (d.getMonth() == now.getMonth() && d.getDate() <= now.getDate()) )
      {
        // Datum war dieses Jahr bereits
        age = now.getFullYear() - d.getFullYear();
      } else {
        // Datum kommt dieses Jahr noch
        age = now.getFullYear() - d.getFullYear() - 1;
      }

      if (age < minage) {
        hasError = 'true';
        msg = 'Das Mindestalter beträgt '+minage+' Jahre.';
      }
    }
  }
  showInfoOrError(node, hasError, msg, "", "error");
}

// Prüfung BooleanCgiParameter
// Es wird geprüft ob es sich um einen boolschen Wert handelt und ob
// bei Pflichtfeldern eine Eingabe vorhanden ist.
function __checkBoolean(node, field, minval, maxval, depends, evt) {

  if (!evt) evt=window.event;
  if (evt && evt.keyCode == 9) { // tab key pressed
    return true;
  }

  // Abhängigkeiten prüfen
  if (!__checkDependency(node, depends))
    return true;

  var hasError = false;
  var value = node.value;
  var values = __getValuesByName(node.form, node.name);
  var msg;

  if(values.length < minval) {
    hasError = true;
    msg = 'Bitte fülle das Feld "' + field + '" aus.';
  } else {
    var val = value.toUpperCase();
    var valid = false;
    for(i=0 ; i<boolstr.length ; i++) {
      if (val == boolstr[i]) {
        valid = true;
        break;
      }
    }
    if (!valid) {
      hasError = 'true';
      msg = 'Bitte gib im Feld "' + field + '" einen gültigen Wert ein.';
    }
  }

  if("radio" == node.type || "checkbox" == node.type) {
    if(!__checkRadio(node, field, minval, maxval)) {
      return false;
    }
  } else {
  	showInfoOrError(node, hasError, msg, "", "error");
  }

}

// Prüft Boolean/Radio Felder
function __checkRadio(node, field, minval, maxval, depends) {
	var msg;
	var hasError = false;
	var form = node.form;
	var list = __getFieldsByName(form, node.name);

	var checked = 0;
	for(i=0 ; i<list.length ; ++i) {
		if (list[i].checked) ++checked;
	}

	if(checked < minval || checked > maxval) {
	    hasError = true;
	    if (checked < minval) {
	      msg = 'Bitte fülle das Feld "' + field + '" aus.';
	    } else {
	      msg = 'Bitte gib im Feld "' + field + '" maximal ' + maxval + ' Werte ein.';
	    }
	}

	var defaultClass = "radio";
	var errorClass = "radioerror";

	if(node.type == "checkbox") {
		errorClass = "checkboxerror";
		defaultClass = "checkbox";
	}

	showInfoOrError(node, hasError, msg, defaultClass, errorClass);

	return !hasError;
}

// Prüfung für Ja/Nein Radioboxen mit einem zusätzlichen Feld
// Das zusätzliche Feld wird dabei mit der Original-Prüfung
// geprüft (nur, wenn die Radio-Box auf "Ja" steht)
function __checkYNT(node, textNode, field, minval) {
  var hasError = false;
  var msg;
  var list = __getFieldsByName(node.form, node.name);
  var text = document.getElementsByName(textNode)[0];
  var span1 = document.getElementById(node.name+"__text1");
  var span2 = document.getElementById(node.name+"__text2");

  // Radio-Boxen prüfen
  var isChecked = false;
  var isTrue = false;
  for(i=0 ; i<list.length ; ++i) {
    if (list[i].checked) {
      isChecked = true;
      if (list[i].value == 1) {
        isTrue = true;
        break;
      }
    }
  }

  if (!isChecked && minval > 0) {
    // Kein Ja/Nein gewählt
    hasError = true;
    msg = "Bitte wähle Ja oder Nein im Feld '"+field+"'.";
    if (span1 && span2) {
    	span1.style.display = 'none';
    	span2.style.display = 'none';
    }
  } else if(isTrue) {
    // Ja gewählt, Fokus auf Textfeld setzen
    if (span1 && span2) {
    	span1.style.display = '';
    	span2.style.display = '';
    }
    text.focus();
  } else {
    // Nein gewählt
    if (span1 && span2) {
    	span1.style.display = 'none';
    	span2.style.display = 'none';
    }
    text.value = '';
  }

  showInfoOrError(node, false, msg, "", "error")
  showInfoOrError(text, hasError, msg, "", "error");
}
function __checkYNT2(node,radioNode,isValid) {
  // Radio-Boxen prüfen
  var list = __getFieldsByName(node.form, radioNode);
  for(i=0 ; i<list.length ; ++i) {
    // Nur wenn JA gewählt wurde, wird der Prüfwert zurückgegeben
    if (list[i].checked && list[i].value == 1 && !isValid) {
      return false;
    }
  }
  // Ansonsten wird die Fehlermeldung zurückgesetzt
  showInfoOrError(node, false, "", "", "error");
  showInfoOrError(list[0], false, "", "", "error")
}

// Zeigt oder verbirgt eine Box (mit Checkbox)
function showBoxBody(node, what, imgurl) {
  var checkbox = document.getElementById(what+"_1");
  var w = document.getElementById(what + "_body");
  if(w && checkbox) {
    if(node.getAttribute('open') != '1') {
      node.setAttribute('open', '1');
      checkbox.checked = true;
      w.style.display = "block";
      node.src = imgurl + "/arrow-up.gif"
    } else {
      checkbox.checked = false;
      node.setAttribute('open', '0');
      w.style.display = "none";
      node.src = imgurl + "/arrow-down.gif"
    }
  }
}

function __onCheckError(name,clazz) {
	if (clazz) this.className = clazz;
}
function __onCheckOk(name,clazz) {
	if (clazz) this.className = clazz;
}
function __eval(code) {
	// Evaluiert JS-Code im Kontext des Form-Elementes!
	eval(code);
}

// Initialisiert die Parent-Area
function __initArea(node) {
  // Wenn Area vorhanden ist
  var area = node.getAttribute("parent");
  // Area anhand der ID suchen
  if (area) {
    area = document.getElementById(area);
    if (area) {
      // Area-Knoten auf der Node setzen
      node.area	= area;
      // Liste mit fehlerhaften Knoten erstellen
      if(!area.errors) {
      	area.errors = new Object();
      	area.errors['_len_'] = 0;
      }

      // ErrorHandler erstellen
      area.onCheckError = __onCheckErrorArea;
      area.onCheckOk = __onCheckOkArea;
      // Parent-Area bearbeiten
      __initArea(area);
    }
  }
}
function __onCheckErrorArea(name) {
	// Fehler zur Liste hinzufügen
	if (this.errors[name] != 1) {
		this.errors[name] = 1;
		++this.errors['_len_'];
	}
	// onerror aufrufen
	var func = this.getAttribute('onerror');
	if (func) eval(func);
	// Parent-Area prüfen
	if (this.area)
	  this.area.onCheckError(name);
}
function __onCheckOkArea(name) {
	// Fehler von Liste entfernen
	if (this.errors[name] == 1) {
		this.errors[name] = 0;
		--this.errors['_len_'];
	}
	if (this.errors['_len_'] == 0) {
	  // onok aufrufen
	  var func = this.getAttribute('onok');
	  if (func) eval(func);
	}
	// Parent-Area prüfen
	  if (this.area)
		this.area.onCheckOk(name);
}

// Initialisiert die Formular-Elemente
function __initFields() {
  if (__initDone)
  	return;

  for (var f=0 ; f<document.forms.length ; ++f) {

    // Alle Formulare durchgehen
    var formElements = document.forms[f].elements;
    var len = formElements.length;
    for (var e=0 ; e<len ; ++e) {
      // Alle Elemente durchgehen
      var ele = formElements[e];

		// Werte in Hash legen
		var hashValue = __namedFormElements[ele.name];
		if(hashValue == undefined) {
			hashValue = new Array(ele);
			__namedFormElements[ele.name] = hashValue;
		} else {
			hashValue[hashValue.length] = ele;
		}

      if (ele.type != 'hidden') {
        // ErrorHandler erstellen
        ele.onCheckError = __onCheckError;
        ele.onCheckOk = __onCheckOk;
        ele.eval = __eval;
        // Area initialisieren
        __initArea(ele);
        // Beim Initialisieren passende Funktion aufrufen
        if (ele.getAttribute('hasError')) {
          ele.onCheckError(ele.name);
          if (ele.area)
            ele.area.onCheckError(ele.id);
        }
      }
    }
  }
  __initDone = true;
}

// Liefert eine Liste von Formularelementen für einen Namen
function __getFieldsByName(form, name) {
	__initFields();

	/*
	var arr = __namedFormElements[name];
	if (!arr) {
		var list = form.elements;
		var len = list.length;
		arr = new Array();
		for(var i=0 ; i<len ; ++i) {
			if (list[i].name == name) {
				arr[arr.length] = list[i];
			}
		}
		__namedFormElements[name] = arr;
	}
	*/
	var arr = __namedFormElements[name];

	return arr;
}

// Liefert eine Liste von Formularwerten für einen Namen. Bei
// Radio- und Checkboxen sowie Auswahllisten werden nur die
// ausgewählten Werte zurückgegeben
function __getValuesByName(form, name, allowEmpty) {
  var values = new Array();
  var list = __getFieldsByName(form, name);
  if (list && list.length>0) {
    type = list[0].type;
    if(type == 'radio' || type == 'checkbox') {
      // Radio/Checkbox: nur Werte von checked-Elementen aufnehmen
      for (var i=0 ; i<list.length ; ++i)
        if (list[i].checked && (list[i].value!='' || allowEmpty)) {
          values[values.length] = list[i].value;
        }
    } else if (type == 'select-one' || type == 'select-multiple') {
      // Auswahlboxen: nur Werte von selektierten Options aufnehmen
      for (var i=0 ; i<list.length ; ++i) {
        var opts = list[i].options;
        var selected = false;
        for(var j=0 ; j<opts.length ; ++j) {
          if(opts[j].selected) {
            selected = true;
            if (list[i].value!='' || allowEmpty)
              values[values.length] = opts[j].value;
          }
        }
        if (!selected && allowEmpty)
          values[values.length] = '';
      }
    } else {
      // Alle anderen Typen liefern immer alle eingegebenen Werte
      for (var i=0 ; i<list.length ; ++i)
        if  (list[i].value!='' || allowEmpty)
          values[i] = list[i].value;
    }
  }
  return values;
}

// Funktion um aus den Dropdown-Listen ein Datum zu erzeugen
function __updateDate(form, name, box) {
	var ttVal = __getValuesByName(form, name+'_tt')[0];
	var mmVal = __getValuesByName(form, name+'_mm')[0];
	var jjjjVal = __getValuesByName(form, name+'_jjjj')[0];

	var nodes = __getFieldsByName(form, name);
	if (ttVal && mmVal && jjjjVal) {
		if (ttVal.length == 1) ttVal = "0"+ttVal;
		if (mmVal.length == 1) mmVal = "0"+mmVal;
		nodes[0].value = ttVal+"."+mmVal+"."+jjjjVal
		nodes[0].onchange();
	} else if (jjjjVal || box==3 || calledByCheckForm) {
		nodes[0].value = '';
		nodes[0].onchange();
	}
}

function __monitorCKEditor(e) {
	e.on('key', function(evt) { __setCKEditorData(evt.editor); });
}
function __checkCKEditor(id) {
	__setCKEditorData(CKEDITOR.instances[id]);
}
function __setCKEditorData(editor) {
	if (editor) {
		var html = document.getElementById(editor.name);
		if (html) {
			var val = editor.getData();
			if (val=="<P>&nbsp;</P>" || val=="<br>") {
				val = "";
			}
			if(val != html.value) {
				html.value = val;
				html.onblur();
			}
		}		
	}
}
