/* *********************************************************************************
Copyright IT-Inspiration ApS, All rights reserved Worldwide.
Any change or copying of the below code or parts hereof without explicit written concent from IT-Inspiration ApS is strictly forbidden.
Web: http://www.it-inspiration.dk
E-mail: mail@it-inspiration.dk
Change log:
-----------
MH-23042002-v1.3 : Added checkbox and radio button support
MH-15032002-v1.2 : Bug correction - numbers wasn't allowed in email addresses
MH-25112001-v1.1 : Updated EmailField, added SelectField, changed FormValidator so one function returns the 
                   number of fields added and another returns the number of unique fields added. Added support 
                   for error codes and error msg's
MH-07112001-v1.0 : Third argument added to TextField class so an arbitrary value may be use for the != test
MH-05112001-v0.9a: First version, submit for change requests :-)
Example:
--------
<SCRIPT SRC="FormValidator.js">
</SCRIPT>
<SCRIPT SRC="ErrorTranslation.js">
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
function doValidation() {
	var a = new FormValidator(document.forms[0]);
	
	// var x = new EmailField(<element reference>, <element name>, <is blank ok>)
	var f1 = new EmailField(document.forms[0].elements["email"], "E-post", false);
	
	// var x = new TextField(<element reference>, <element name>, <validation value>)
	var f2 = new TextField(document.forms[0].elements["Text1"], "Telefon", "lekkim");
	var f3 = new TextField(document.forms[0].elements["Text1"], "Telefon", "");
	
	// var x = new TextField(<element reference>, <element name>, <validation value>, <validate on value property>)
	var f4 = new SelectField(document.forms[0].elements["Selection"], "Favorit maltid", "", true);
	var f5 = new SelectField(document.forms[0].elements["Selection"], "Favorit maltid", "lunch", true);
	
	// add fields to validator
	a.addField(f1);
	a.addField(f2);
	a.addField(f3);
	a.addField(f4);
	a.addField(f5);
	
	//alert("There are " + a.getNumUniqueFields() + " unique fields to be validated...");
	//alert("There are " + a.getNumFields() + " fields added...");
	
	if (a.validate()) {
		alert("yep the fields are ok");
		//a.submit();
	} else {
		alert("We couldn't validate the fields: " +  a.getErrorMsg());
	}
	
	// translate the error code for the email field if any
	if (f1.getErrorCode() > -1) {
		var t1 = new ErrorCodes("da");
		alert(f1.getErrorCode() + " - " + t1.getErrorMsg(f1.getErrorCode()));
		var t2 = new ErrorCodes("en");
		alert(f1.getErrorCode() + " - " + t2.getErrorMsg(f1.getErrorCode()));
	}
	
}
</SCRIPT>
***********************************************************************************/
/* Object declaration ***************
Name: FormValidator
Purpose: To validate a form
************************************/
function FormValidator_getFormName() {
	return this.FormName;
}
function FormValidator_validate() {
	// declarations
	var strErrorMsg = "";
	
	if (this.fieldArray.length > 0) {
		for (var i = 0; i < this.fieldArray.length; i++) {
			if (this.fieldArray[i].validate() == false) {
				if (strErrorMsg == "") {
					strErrorMsg = this.fieldArray[i].desc;
				} else {
					strErrorMsg = strErrorMsg + ", " + this.fieldArray[i].desc;
				}
			}
		}
		
		// did all fields validate
		if (strErrorMsg == "") {
			return true;
		} else {
			this.ErrorMsg = strErrorMsg;
			return false;
		}
	} else {
		this.ErrorMsg = "No fields to validate"
		return false;
	}
}
function FormValidator_addField(aField) {
	var isAlreadyAdded = false;
	
	if (null != aField) {
		this.fieldArray[this.numFields] = aField;
		this.numFields++;
		
		for (var i=0; i < this.fieldArray.length; i++) {
			if (this.fieldArray[i].name == aField.name && this.fieldArray[i] != aField) {
				isAlreadyAdded = true;
			}
		}
		if (isAlreadyAdded == false) {
			this.numUniqueFields++;
		}
	}
}
function FormValidator_getNumFields() {
	return this.numFields;
}
function FormValidator_getNumUniqueFields() {
	return this.numUniqueFields;
}
function FormValidator_submit() {
	if (this.validate()) {
		this.Form.submit();
	}
}
function FormValidator_getErrorMsg() {
	return this.ErrorMsg;
}
function FormValidator(hForm) {
	// was we passed a form
	if (null == hForm) {
		return;
	}
	
	// object variables
	this.fieldArray = new Array();
	
	// a pointer to the form we are validating
	this.Form = hForm; 
	// the name of the form
	this.FormName = hForm.name; 
	// when validation fails this variable will have a comma 
	// separated list of the fields that failed validation
	this.ErrorMsg = ""; 
	// the number of unique fields added
	this.numUniqueFields = 0;
	// the number of fields added
	this.numFields = 0;
	
	// pointers to functions
	this.getFormName = FormValidator_getFormName;
	this.addField = FormValidator_addField;
	this.validate = FormValidator_validate;
	this.getNumFields = FormValidator_getNumFields;
	this.getNumUniqueFields = FormValidator_getNumUniqueFields;
	this.submit = FormValidator_submit;
	this.getErrorMsg = FormValidator_getErrorMsg;
	
	return this;
}
/* Object declaration ***************
Name: EmailField
Purpose: Models an email field to be validated
************************************/
function EmailField_validate() {
	var strSource = this.element.value;
	// the string must not be empty
	if (strSource == "") {
		if (this.isBlankOK) {
			return true;
		} else {
			this.errorcode = 1001; // email must not be blank
			return false;
		}
	}
	
	// did the user write comma instead of period
	if (strSource.indexOf(",") > 0) {
		this.errorcode = 1006;
		return false;
	}
	
	// there should be a @
	 if (strSource.indexOf("@") > 0) {
		// after the @ there should be a at least one period
		if (strSource.lastIndexOf(".") > strSource.indexOf("@") + 1) {
			// we must only use ASCII chars
			strSource = strSource.toLowerCase();
			var intFlag = true;
			for (var i=0; i < strSource.length; i++) {
				if ( (47 < strSource.charCodeAt(i) && strSource.charCodeAt(i) < 58) || (96 < strSource.charCodeAt(i) && strSource.charCodeAt(i) < 123) || strSource.charCodeAt(i) == 64 || strSource.charCodeAt(i) == 45 || strSource.charCodeAt(i) == 46 || strSource.charCodeAt(i) == 95) {
					// the char is ok
				} else {
					// is it an ASCII char
					intFlag = false;
				}
			}
			
			// did we have non-ASCII chars
			if (intFlag) {
				// only ASCII - is there at least 2 chars after the last period 
				if (strSource.length - strSource.lastIndexOf(".") < 3) {
					this.errorcode = 1005; // there must be at least 2 chars after the last period
					return false;
				} else {
					return true;
				}
			} else {
				this.errorcode = 1004; // we only allow ASCII chars
				return false;
			}
		} else {
			this.errorcode = 1003; // there must be at least one char between the @ and the domain period
			return false;
		}
	} else {
		this.errorcode = 1002; // email must have a @
		return false;
	}
}
function EmailField_getErrorCode() {
	return this.errorcode;
}
function EmailField(field, strDesc, blankOK) {
	this.name = field.name;
	this.desc = strDesc;
	this.element = field;
	this.isBlankOK = blankOK;
	this.errorcode = -1; // code series 1000
	this.type = "email";
	this.validate = EmailField_validate;
	this.getErrorCode = EmailField_getErrorCode;
}
/* Object declaration ***************
Name: TextField
Purpose: Models a text field to be validated
************************************/
function TextField_validate() {
	if (this.element.value != this.value) {
		return true;
	} else {
		return false;
	}
}
function TextField(field, strDesc, strValue) {
	this.name = field.name;
	this.desc = strDesc;
	if (strValue == null) {
		this.value = "";
	} else {
		this.value = strValue;
	}
	this.element = field;
	this.type = "text";
	this.validate = TextField_validate;
}
/* Object declaration ***************
Name: SelectionField
Purpose: Models a SELECT HTML field to be validated
************************************/
function SelectField_validate() {
	// declarations
	var strSource = "";
	
	// a select field may be validated on the text property and on the value property
	if (this.property == true) {
		strSource = this.element.value;
	} else {
		// validate on text
		strSource = this.element[this.element.selectedIndex].text;
	}
	
	if (strSource != this.value) {
		return true;
	} else {
		return false;
	}
}
function SelectField(field, strDesc, strValue, prop) {
	this.name = field.name;
	this.desc = strDesc;
	this.property = prop;
	if (strValue == null) {
		this.value = "";
	} else {
		this.value = strValue;
	}
	this.element = field;
	this.type = "select";
	this.validate = SelectField_validate;
}
/* Object declaration ***************
Name: CheckboxField
Purpose: Models a checkbox HTML field to be validated
************************************/
function CheckboxField_validate() {
	// declarations
	var strSource = "";
	
	// loop the forms and check the fields with matching field name
	for (var i = 0; i < this.element.elements.length; i++) {
		if (this.element.elements[i].name == this.name && this.element.elements[i].checked) {
			strSource = this.element.elements[i].value;
		}
	}
	if (strSource != this.value) {
		return true;
	} else {
		return false;
	}
}
function CheckboxField(form, fieldname, strDesc, strValue) {
	// checkboxes are special since we have many fields with the same name
	this.name = fieldname;
	this.desc = strDesc;
	if (strValue == null) {
		this.value = "on";
	} else {
		this.value = strValue;
	}
	this.element = form;
	this.type = "checkbox";
	this.validate = CheckboxField_validate;
}
/* Object declaration ***************
Name: RadioButtonField
Purpose: Models a radio button HTML field to be validated
************************************/
function RadioButtonField_validate() {
	// declarations
	var strSource = "";
	
	// loop the forms and check the fields with matching field name
	for (var i = 0; i < this.element.elements.length; i++) {
		if (this.element.elements[i].name == this.name && this.element.elements[i].checked) {
			strSource = this.element.elements[i].value;
		}
	}
	if (strSource != this.value) {
		return true;
	} else {
		return false;
	}
}
function RadioButtonField(form, fieldname, strDesc, strValue) {
	// radio buttons are special since we have many fields with the same name
	this.name = fieldname;
	this.desc = strDesc;
	if (strValue == null) {
		this.value = "on";
	} else {
		this.value = strValue;
	}
	this.element = form;
	this.type = "checkbox";
	this.validate = CheckboxField_validate;
}
