/*
 * (c) fairtec Kommunikationstechnik GmbH Bremen
 */

// Pruefe, ob ein Wert in einem Array enthalten ist
function inArray(val,arr) {
	for (var i=0; i<arr.length; i++) {
		if (arr[i] == val)
			return true;
	}
	return false;
}

// Pruefe, ob ein String eine syntaktisch korrekte EMail-Adresse darstellt
function isValidEmail(val) {
	return (val.match(/^\s*[a-z0-9_!%\$\.\-\+\']+\@([a-z0-9\-]+\.)+[a-z]{2,}\s*$/i) != null);
}
function isValidEMail(val) {
	return isValidEmail(val);
}

// Pruefe, ob ein String ein Integer enthält (positiv + negativ)
function isInteger(val) {
	return (val.toString().search(/^-?[0-9]+$/) == 0);
}
// Pruefe, ob ein String ein Integer enthält (NUR positiv)
function isUnsignedInteger(val) {
	return (val.toString().search(/^[0-9]+$/) == 0);
}


// Pruefe, ob ein String eine "gaengige" unzustellbare EMail-Adresse darstellt
function isDummyEmail(val) {
	if (val.match(/\@(example|unbekannt|unknown)\.(de|com|net)\s*$/i) || val.match(/^\s*([x\.]|[y\.])+\@(x|y)+\.[a-z]{2,}\s*$/i))
		return true;
	return false;
}
function isDummyEMail(val) {
	return isDummyEmail(val);
}
// Pruefe, ob ein String eine "gaengige" IBM EMail-Adresse darstellt
function isIBMEmail(val) {
	if (val.match(/\@(de|uk|us|at|ch|fr)\.(ibm)\.(com)$/i))
		return true;
	//return false;
}
function isIBMEMail(val) {
	return isIBMEmail(val);
}

// Pruefe, ob ein String eine syntaktisch korrekte internationale Telefonnummer darstellt
function isValidInternationalPhoneNumber(val) {
	return trimPhoneNumber(val).match(/^\+[0-9]{6,}$/);
}

// Gibt einen String zurueck, aus dem fuer eine Telefonnummer "gueltige" aber ueberfluessige Zeichen entfernt wurden.
function trimPhoneNumber(val) {
	return val.replace(/[ \/-]/g,'').replace(/\(0\)/,'');
}

// wendet auf ein <input type="text"> die trimPhoneNumber() Funktion an und gibt zusaetzlich den neuen String zurueck
function trimPhoneNumberInput(elem) {
	return (elem.value = trimPhoneNumber(elem.value));
}

/*
	Pruefe, ob aus Jahr, Monat und Tag ein gueltiges Datum gebildet werden kann
	(Uebergabe als String)
*/
function isValidDate(year,month,day) {
	var y = Number(year);
	var m = Number(month);
	var d = Number(day);
	if (isNaN(y) || isNaN(m) || isNaN(d))
		return false;
	m--;
	var tmp = new Date(y,m,d);
	return !(isNaN(tmp.getFullYear()) || tmp.getFullYear() != y || tmp.getMonth() != m || tmp.getDate() != d);
}

/*
	Pruefe, ob per mehrfacher select-Box ein gueltiges Datum ausgewaehlt wurde
	(Uebergabe als select-Box-Objekte fuer Tag, Monat und Jahr)
*/
function isValidDateSelect(year,month,day) {
	return isValidDate(selectedOptionValue(year),selectedOptionValue(month),selectedOptionValue(day));
}

/*
	Pruefe, ob ein String ein gueltiges Datum (im Format dd.mm.yyyy) darstellt
*/
function isValidDateString(val) {
	var arr = val.split(/\./);
	return (arr.length == 3) && isValidDate(arr[2],arr[1],arr[0]);
}

/*
	Pruefe, ob ein String ein gueltiges Datum (im Format yyyy-mm-dd) darstellt
*/
function isValidISODateString(val) {
	var arr = val.split(/-/);
	return (arr.length == 3) && isValidDate(arr[0],arr[1],arr[2]);
}

/*
	Wandle einen String (im Format dd.mm.yyyy) in ein Datums-Objekt um.
	Gibt "NaN"-Objekt zurück, wenn der String kein gueltiges Datum darstellt.
*/
function parseDateString(val) {
	if (!isValidDateString(val))
		return Number.NaN;
	var arr = val.split(/\./);
	return new Date(Number(arr[2]),Number(arr[1])-1,Number(arr[0]));
}

/*
	Wandle einen String (im Format yyyy-mm-dd) in ein Datums-Objekt um.
	Gibt "NaN"-Objekt zurück, wenn der String kein gueltiges Datum darstellt.
*/
function parseISODateString(val) {
	if (!isValidISODateString(val))
		return Number.NaN;
	var arr = val.split(/-/);
	return new Date(Number(arr[0]),Number(arr[1])-1,Number(arr[2]));
}

/*
	Zur einfachen Handhabung einer unbekannten Anzahl an z.B. Checkboxen:
	- wenn "node" ein Array ist: gibt "node" zurueck
	- wenn "node" null ist: gibt ein leeres Array zurueck
	- sonst: gibt ein Array zurueck, das nur "node" enthaelt
*/
function inputAsArray(node) {
	if (node == null)
		return new Array();
	if ((typeof(node) == 'object' || typeof(node) == 'function') && typeof(node.length) == 'number' && typeof(node.nodeType) == 'undefined') // "node" ist ein Objekt (oder in Safari: Funktion), aber kein Knoten-Objekt: "node" ist (vermutlich) bereits ein Array
		return node;
	var tmp = new Array();
	tmp.push(node);
	return tmp;
}

/*
	Pruefe, ob ein Objekt sichtbar ist.
	(Die ganze Pruefung liesse sich auf [node.clientWidth <> 0] reduzieren, funktioniert beim Test im IE 6 aber nur so lange das Objekt noch *nie* sichtbar war ...)
*/
function inputIsVisible(node) {
	/* Firefox setzt bei versteckten Elementen offsetParent auf null: sofort fertig */
	if (node.offsetParent == null)
		return false;
	/* ansonsten fuer alle Elternelemente pruefen, ob sie irgendwie ausgeblendet sind */
	do {
		if (node.style != null && (node.style.visibility == 'hidden' || node.style.display == 'none'))
			return false;
		node = node.parentNode;
	} while (node);
	return true;
}

// Array der gewaehlten Indizes
function selectedCheckboxes(elem,countDisabled) {
	var arr = new Array();
	elem = inputAsArray(elem);
	for (var i=0; i<elem.length; i++) {
		if (elem[i].checked && (countDisabled || !elem[i].disabled))
			arr[arr.length] = i;
	}
	return arr;
}

// Array der gewaehlten Werte (value)
function selectedCheckboxValues(elem,countDisabled) {
	var arr = new Array();
	elem = inputAsArray(elem);
	for (var i=0; i<elem.length; i++) {
		if (elem[i].checked && (countDisabled || !elem[i].disabled))
			arr[arr.length] = elem[i].value;
	}
	return arr;
}

// Index des gewaehlten Radiobutton (oder der ersten gewaehlten Checkbox), -1 = keine
function selectedRadio(elem,countDisabled) {
	elem = inputAsArray(elem);
	for (var i=0; i<elem.length; i++) {
		if (elem[i].checked && (countDisabled || !elem[i].disabled)) return i;
	}
	return -1;
}

// Wert (value) des gewaehlten Radiobutton (oder der ersten gewaehlten Checkbox), null = keiner
function selectedRadioValue(elem,countDisabled) {
	elem = inputAsArray(elem);
	for (var i=0; i<elem.length; i++) {
		if (elem[i].checked && (countDisabled || !elem[i].disabled))
			return elem[i].value;
	}
	return null;
}

// Index der gewaehlten Option (Einfach-select, keine Arrays!)
function selectedOption(elem) {
	return elem.options.selectedIndex;
}

// Objekt der gewaehlten Option (Einfach-select, keine Arrays!)
function selectedOptionObject(elem) {
	return elem.options[elem.options.selectedIndex];
}

// Wert (value) der gewaehlten Option (Einfach-select, keine Arrays!)
function selectedOptionValue(elem) {
	return (elem.options.selectedIndex == -1) ? null : elem.options[elem.options.selectedIndex].value;
}

// Wert (value) der gewaehlten Option (Einfach-select, keine Arrays!)
function selectedOptionText(elem) {
	return (elem.options.selectedIndex == -1) ? null : elem.options[elem.options.selectedIndex].text;
}

// Array der gewaehlten Option-Indizes (Mehrfach-select, keine Arrays!)
function selectedOptions(elem) {
	var arr = new Array();
	for (var i=0; i<elem.options.length; i++) {
		if (elem.options[i].selected)
			arr[arr.length] = i;
	}
	return arr;
}

// Array der gewaehlten Option-Werte (Mehrfach-select, keine Arrays!)
function selectedOptionValues(elem) {
	var arr = new Array();
	for (var i=0; i<elem.options.length; i++) {
		if (elem.options[i].selected)
			arr[arr.length] = elem.options[i].value;
	}
	return arr;
}

/*
	Setze Select-Box auf die (erste) Option, deren value "val" ist
	Falls keine Option gefunden wird, wird "false" zurückgegeben und bei:
		first = false: nichts geaendert
		first = true: der erste Wert gewaehlt
*/
function setOption(elem,val,first) {
	for (var i=0; i<elem.options.length; i++) {
		if (elem.options[i].value == val) {
			elem.options.selectedIndex = i;
			return true;
		}
	}
	if (first)
		elem.options.selectedIndex = 0;
	return false;
}

/*
	Waehle in einer Mehrfach-Select-Box alle Options, deren value in "arr" enthalten ist.
	Gibt die Anzahl der danach tatsaechlich selektierten Options zurueck.
*/
function setMultiOption(elem,arr) {
	var sel = 0;
	for (var i=0; i<elem.options.length; i++) {
		elem.options[i].selected = inArray(elem.options[i].value,arr);
		if (elem.options[i].selected)
			sel++;
	}
	return sel;
}

/*
	Setze Text-Input auf "val", wobei auf maxlength geprueft und "val" ggf. abgeschnitten wird
	(Firefox macht dies bereits von sich aus, IE hingegen nicht)
*/
function setInputText(elem,val) {
	elem.value = (elem.maxLength != null && elem.maxLength >= 0) ? val.substr(0,elem.maxLength) : val;
}

// Setze alle checkbox/radio auf "checked", deren value in arr enthalten ist
function setCheckboxes(elem,arr) {
	elem = inputAsArray(elem);
	for (var i=0; i<elem.length; i++) {
		elem[i].checked = inArray(elem[i].value,arr);
	}
}

// Einzelne oder mehrere checkbox/radio/input/select-Box enablen oder disablen und beim disablen den Wert zuruecksetzen (def=true: auf Standardwert, def=false/null: auf leer/erste Auswahl)
function setDisabled(elem,disable,def) {
	var e = elem.nodeType ? new Array(elem) : elem;
	for (var n=0; n<e.length; n++) {
		e[n].disabled = disable;
		if (disable) {
			switch (e[n].type.toLowerCase()) {
				case "select-one":
					if (def) {
						for (var i=0; i<e[n].options.length; i++) {
							e[n].options[i].selected = e[n].options[i].defaultSelected;
						}
					} else {
						e[n].options.selectedIndex = 0;
					}
					break;
				case "select-multiple":
					for (var i=0; i<e[n].options.length; i++) {
						e[n].options[i].selected = def ? e[n].options[i].defaultSelected : false;
					}
					break;
				case "checkbox":
				case "radio":
					e[n].checked = def ? e[n].defaultChecked : false;
					break;
				case "text":
				case "textarea":
				case "password":
					e[n].value = def ? e[n].defaultValue : "";
					break;
			}
		}
	}
}

/*
	Pruefe, ob eine Auswahl getroffen wurde, d.h. bei
		- Checkbox/Radio/Select-multiple: mindestens ein Button/Option
		- Select-one: nicht die erste Option
		- Text/Textarea: Feld nicht leer oder nur "white-spaces"
	(keine gemischten input-Typen und keine select/text/textarea-Arrays erlaubt!)
	Rueckgabe: true bei keiner Auswahl, sonst false
*/
function noSelection(elem,allowDisabled) {
	if (elem == null)
		return true;
	var e = elem.type ? elem : elem[0];
	switch (e.type.toLowerCase()) {
		case "select-one":
			return (selectedOption(elem) < 1);
		case "select-multiple":
			return (selectedOptions(elem).length == 0);
		case "checkbox":
		case "radio":
			return (selectedRadio(elem,allowDisabled) == -1);
		case "hidden":
		case "text":
		case "textarea":
		case "password":
		case "file":
			return elem.value.match(/^\s*$/);
		default:
			return true;
	}
}

// (erstes) Feld fokussieren und Meldung ausgeben, falls keine Auswahl getroffen wurde [siehe noSelection()]
// Rueckgabe: true bei keiner Auswahl, sonst false
function alertNoSelection(elem,msg,allowDisabled) {
	var warn = noSelection(elem,allowDisabled);
	var e = inputAsArray(elem);
	if (warn) {
		for (var i=0; i<e.length; i++) {
			if (!e[i].disabled && inputIsVisible(e[i])) {
				e[i].focus();
				break;
			}
		}
		alert(msg);
	}
	return warn;
}

/*
	Pruefe, ob ein input/select veraendert wurde (nicht mehr dem Defaultwert entspricht)
*/
function modified(elem) {
	var e = elem.type ? elem : elem[0];
	switch (e.type.toLowerCase()) {
		case "select-one":
		case "select-multiple":
			for (var i=0; i<elem.options.length; i++) {
				if (elem.options[i].selected != elem.options[i].defaultSelected)
					return true;
			}
			return false;
		case "checkbox":
		case "radio":
			return (elem.checked != elem.defaultChecked);
		case "hidden":
		case "text":
		case "textarea":
		case "password":
		case "file":
			return (elem.value != elem.defaultValue);
		default:
			return true;
	}
}

