// Formular Validierung Version 2.2
// (C) 2004 Electronic Minds
// www.electronic-minds.de

// 16.11.2004 10:27	Bugfix direct compare -> Stürzt ab, wenn man Zeilenumbrüche in der Value hat
//			Bugfix direct compare -> Stürzt unter Netscape 4 ab, wenn man in der Objektaddressierung (this.this.) benutzt
//			Bugfix Checkbox-Support unter Netscape 4
//			Bugfix Opera Radiobutton-Debugausgabe
// 01.07.2004 17:56	Add direct compare -> ?
// 06.05.2004 12:00	Bugfix


// Liefert den Wert eines Objektes zurück


function GetElementValue(elobj)
{
	var itype= typeof elobj;
	var retval= "";

	switch(itype.toLowerCase())
	{
		case "string":
			retval= elobj
			break;

		case "number":
			retval= String(elobj);
			break;

		case "object":
			var objtype= "";
			var arrlength= elobj.length;

			// Wenns einen Objekttyp gibt: auslesen
			if(typeof elobj.type != 'undefined') objtype= elobj.type;
			
			if(typeof arrlength == 'undefined')
			{
				switch(objtype.toLowerCase())
				{
					case "text":
					case "textarea":
					case "file":
					case "password":
						retval= elobj.value;
						break;
						
					case "checkbox":
						if(elobj.checked) retval= elobj.value;
						else retval= "";
						break;
						
					default:
						NoHandlerFound(objtype);
				}
			}
			else
			{
				if(typeof elobj.type == 'undefined')
				{
					// Radiobuttons
					for(var pos= 0; pos < elobj.length; pos++)
						if(elobj[pos].checked)
						{
							retval= elobj[pos].value;
							break;
						}
				}
				else
				{
					switch(objtype.toLowerCase())
					{
						case "select-multiple":
							retval= new Array();
							for(var pos= 0; pos < elobj.length; pos++)
								if(elobj[pos].selected) retval[pos]= elobj[pos].value;
								retval= retval.join(",");
							break;
							
						case "select-one":
							if(elobj.selectedIndex > -1) retval= elobj[elobj.selectedIndex].value;
							break;
							
						case "container":
							retval= elobj.get_cnt();
							break;
							
						case "checkbox":
							if(elobj.checked) retval= elobj.value;
							else retval= "";
							break;
						default:
							NoHandlerFound(objtype);
					}
				}
			}
			break;

		case "function":
			// Opera Radiobuttons
			arrlength= elobj.length;
			if(typeof arrlength != 'undefined')
			{
				for(var pos= 0; pos < elobj.length; pos++)
					if(elobj[pos].checked)
					{
						retval= elobj[pos].value;
						break;
					}
			}
			break;

		default:
			window.alert("Unbekanntes Objekt: " + itype);
			retval= false;
			break;
	}
	return retval;
}

// Gibt eine Fehlermeldung aus
function NoHandlerFound(objtype)
{
	window.alert("Für das Objekt vom Typ '" + objtype + "' existiert kein Handler!");
}

// Klasse, die einn beliebigen Inhalt transportieren kann
function Container()
{
	this.type= "container";
	this.length= -1;
	this.cnt= new Array();

	this.add_cnt= AddContentToContainer;
	this.get_cnt= GetContentFromContainer;
}

// Speichert ein Objekt im Container
function AddContentToContainer(new_cnt)
{
	var cnt_ok= (typeof new_cnt != 'undefined');
	if(cnt_ok) this.cnt= new_cnt;

	return cnt_ok;
}

// Liefert das Objekt aus dem Container
function GetContentFromContainer()
{
	return this.cnt;
}

// Klasse zum Validieren von Eingaben
function CValidation()
{
	this.required_rule= new Array("");
	this.rule_result= new Array("");

	// Überprüft eine Emailadresse auf Richtigkeit
	this.email= check_email;

	// Überprüft ein Datum auf Richtigkeit
	this.date= check_date;

	// Überprüft eine Ganzzahl auf Richtigkeit
	this.integer= check_int;

	// Überprüft eine Kommazahl auf Richtigkeit
	this.floating= check_float;

	// Überprüft eine Ganzzahl/Kommazahl auf Richtigkeit
	this.number= check_number;

	// Überprüft eine Kontonummer auf Richtigkeit
	this.konto= check_konto;

	// Überprüft eine Bankleitzahl auf Richtigkeit
	this.blz= check_blz;

	// Überprüft ob eine Nummer enthalten ist
	this.contains_number= check_containnr;

	// Überprüft eine PLZ auf Richtigkeit
	this.plz= check_plz;

	// Überprüft ob ein Wert leer ist
	this.empty= check_empty;

	// Fügt eine NICHT OPTIONALE Prüfregel an
	this.require= valid_require;

	// Fügt eine OPTIONALE Prüfregel an
	this.optional= valid_optional;

	// Führt einen Vergleich aus
	this.comparefunction= run_comparefunction

	// Führt die Prüfregeln aus
	this.validate= do_validation;
}

// Prüft auf Emailadresse
function check_email(email_inp)
{
	var mailpart= "";
	var isValid= (email_inp != "");

	if(isValid)
	{
		mailpart= email_inp.match("\([a-zA-Z0-9_-]+\)\@\([a-zA-Z0-9_-]+\)[\.]{1}\([a-zA-Z0-9]+\)");
		isValid= mailpart != null;
		if(isValid) isValid= typeof mailpart[1] != 'undefined' && typeof mailpart[2] != 'undefined' && typeof mailpart[3] != 'undefined';
	}

	return isValid;
}

// Prüft auf Datum
function check_date(date_inp)
{
	var isValid= (date_inp != "");
	if(isValid)
	{
		var datepart= date_inp.match("\(.*\)\([0-9]{2}\)\.\([0-9]{2}\)\.\([0-9]{4}\)\(.*\)");
		isValid= datepart != null;
		if(isValid) isValid= (datepart[1] == "") && (datepart[5] == "");
		if(isValid) isValid= !isNaN(datepart[2]) && !isNaN(datepart[3]) && !isNaN(datepart[4]);
		if(isValid) isValid= ((datepart[2] > 0 && datepart[2] <= 31) && (datepart[3] > 0 && datepart[3] <= 12) && (datepart[4] > 1900 && datepart[4] < 2200));
	}
	return isValid;
}

// Prüft auf Zahl ohne Komma
function check_int(num_inp)
{
	var isValid= (num_inp != "");
	if(isValid)
	{
		numpart= num_inp.match("\([^0-9]*\)[0-9]+\([^0-9]*\)");
		isValid= numpart != null;
		if(isValid) isValid= numpart[1] == "" && numpart[2] == "";
	}
	return isValid;
}

// Prüft auf Zahl mit Komma
function check_float(float_inp)
{
	isValid= (float_inp != "");
	if(isValid)
	{
		floatpart= float_inp.match("\([^0-9]*\)\([0-9]+\)[,\.]\([0-9]+\)\([^0-9]*\)");
		isValid= floatpart != null;
		if(isValid) isValid= floatpart[1] == "" && floatpart[4] == "";
	}
	return isValid;
}

// Prüft auf Zahl mit oder ohne Komma
function check_number(num_inp)
{
	return (this.integer(num_inp) || this.floating(num_inp));
}

// Prüft auf Kontonummer
function check_konto(konto_inp)
{
	return (this.integer(konto_inp) && konto_inp.length <= 10);
}

// Prüft auf Bankleitzahl
function check_blz(blz_inp)
{
	return (this.integer(blz_inp) && blz_inp.length == 8);
}

// Prüft ob Nummer beinhaltet ist
function check_containnr(nr_inp, min_length)
{
	var nrpart= "";
	var isValid= (nr_inp != "");

	if(isValid)
	{
		nrpart= nr_inp.match(".*\([0-9]{" + min_length + ",}\).*");
		isValid= nrpart != null;
		if(isValid) isValid= typeof nrpart[1] != 'undefined';
	}

	return isValid;
}

// Prüft auf Postleitzahl
function check_plz(plz_inp)
{
	var isValid= this.integer(plz_inp);
	if(isValid) isValid= (plz_inp.length == 5);
	return isValid;
}

// Prüft ob leer
function check_empty(inp_val)
{
	return (inp_val == "");
}

// Nimmt eine nicht optionale Bedingung entgegen
function valid_require(value, validation, errormsg, depend_on)
{
	var argscount= (this.require.arguments.length);
	var reqpos= this.required_rule.length;

	if(argscount >= 2)
	{
		if(typeof depend_on == 'undefined') depend_on= 0;
		if(argscount == 2) errormsg= "";
		this.required_rule[reqpos]= new Array(false, value, validation, errormsg, depend_on);
	}
	else reqpos= false;

	return reqpos;
}

// Nimmt eine optionale Bedingung entgegen
function valid_optional(value, validation, errormsg, depend_on)
{
	var argscount= (this.optional.arguments.length);
	var reqpos= this.required_rule.length;

	if(argscount >= 2)
	{
		if(typeof depend_on == 'undefined') depend_on= 0;
		if(argscount == 2) errormsg= "";

		this.required_rule[reqpos]= new Array(true, value, validation, errormsg, depend_on);
	}
	else reqpos= false;

	return reqpos;
}

// Führt den eigentlichen Vergleich durch...
function run_comparefunction(method, function_name, objvalue)
{
	var retval= false
	if(method == "!" || method == "")
	{
		// Validierungsfunktion ausführen (evtl mit Negierung)
		if(function_name.substr(0, 5) != "this.") function_name= "this." + function_name;
		retval= eval(method + function_name + "(\"" + escape(objvalue) + "\")");
	}
	else if(method == "?")
	{
		// Direkter Vergleich
		retval= (function_name == objvalue);
	}
	else window.alert("Unbekannte Methode: " + method);
	
	return retval;
}

// Führt die Validierung durch
function do_validation()
{
	var validation, msg;
	var isvalid= true;
	var allvalid= true;
	var dependancy= "";
	var objvalue= "";
	var is_optional= false;
	var itype= "";
	var cmd= "";

	var cont_succ= 0;
	var cont_pos= 0;
	var cont_obj= 0;
	var cont_obj_val= 0;
	var cont_cmd= "";

	for(var pos= 1; pos < this.required_rule.length; pos++)
	{
		cmd= this.required_rule[pos][2].match("\(\[!\?]?\)\(.*\)");
		validation= "this." + cmd[2];
		is_optional= this.required_rule[pos][0];
		dependancy= this.required_rule[pos][4];
		msg= this.required_rule[pos][3];

		if(dependancy < pos && dependancy > 0) dependancy= this.rule_result[dependancy];
		else if(dependancy == 0) dependancy= true;
		else dependancy= false;

		if(dependancy)
		{
			// Gültige Funktion oder direkter Vergleich -> ?
			isvalid= (typeof eval(validation) != 'undefined' || cmd[1] == "?");

			if(isvalid)
			{
				objvalue= GetElementValue(this.required_rule[pos][1]);

				// Normales Objekt...
				if(typeof objvalue != "object") isvalid= this.comparefunction(cmd[1], cmd[2], objvalue);
				
				// Es handelt sich um einen Container!!!
				else if(typeof objvalue.length != 'undefined')
				{
					cont_succ= 0;
					for(cont_pos= 0; cont_pos < objvalue.length; cont_pos++)
					{
						cont_obj= objvalue[cont_pos];
						cont_obj_val= GetElementValue(cont_obj);

						if(this.comparefunction(cmd[1], validation, cont_obj_val)) cont_succ++;
					}

					isvalid= (cont_succ > 0);
				}
				else window.alert("Unbekannntes Objekt: " + objvalue);
			}
			else window.alert("Unbekannte Validierungsfunktion: " + validation);

			this.rule_result[pos]= isvalid;
			allvalid= allvalid && (isvalid || is_optional);

			if(!isvalid)
			{
				if(msg != "") window.alert(msg);

				if(!is_optional)
				{
					if(typeof this.required_rule[pos][1].focus != 'undefined') this.required_rule[pos][1].focus();
					break;
				}
			}
		}
		else
		{
			this.rule_result[pos]= false;
			allvalid= allvalid && true;
		}
	}

	return allvalid;
}

