if (typeof jslibDevErrMsg != "string") {
	var jslibDevErrMsg = 'Illegal argument or assignment!';
}
/*
	Arguments must be of type object, string/(function/object), boolean, integer, integer
	The second argument must be a regular expression or a string.
	Note that a regular expression is of type function in Netscape (4 & 6), but is of type
	object in Internet Explorer and Opera.
	If the second argument is a string a regular expression is created based on the string.
	The third argument is boolean (default is false) indicating whether or not the regular
	expression should match	the value of the field. In other words if the third argument is
	false the characters specified in the regular expression must not be found in the value
	of the field.
*/
function validText(fieldObj, target, doMatch, minLength, maxLength) {
	if (fieldObj == null || typeof fieldObj != "object" || typeof fieldObj.value != "string") {
		self.jslibErrorMsg = jslibDevErrMsg;
		return false;
	}
	if (target == null) {
		target = "";
	}
	if (typeof doMatch != "boolean") {
		doMatch = false;
	}
	var txt = fieldObj.value;
	var fieldType = (fieldObj.name.toLowerCase().indexOf("search") > -1) ? "SEARCH" : "FIELD";
	minLength = parseInt(minLength,10);
	if (!isNaN(minLength) && minLength > 0 && txt.length < minLength) {
		return reportError(fieldObj, getErrMsg(fieldType + "_MIN_NO_OF_CHARS", new Array(minLength,fieldObj.name)));
	}
	maxLength = parseInt(maxLength,10);
	if (!isNaN(maxLength) && maxLength > 0 && txt.length > maxLength) {
		return reportError(fieldObj, getErrMsg("FIELD_MAX_NO_OF_CHARS", new Array(maxLength,fieldObj.name)));
	}
	var regExp, found;
	if (typeof target == "string") {
		var pattern = target;
		if (pattern == "") {
			if (txt == pattern) {
				return reportError(fieldObj, getErrMsg("FIELD_NOT_FILLED", new Array(fieldObj.name)));
			}
		} else {
			regExp = new RegExp(pattern);
		}
	}
	// Netscape 4 & 6 defines a Regular Expression to be of type function, but Internet Explorer and Opera defines it to be of type object
	else if (target != null && (typeof target == "function" || typeof target == "object") && typeof target.exec == "function") {
		regExp = target;
	}
	if (regExp != null) {
		found = regExp.exec(txt);
		if (doMatch) {
			if (found == null) {
				return reportError(fieldObj, getErrMsg("FIELD_INVALID", new Array(fieldObj.name)));
			}
		} else {
			if (found != null) {
				if (found[0].length == 1) {
					if (found.index == 0) {
						return reportError(fieldObj, getErrMsg("FIELD_CHAR_NOT_ALLOWED_AS_FIRST", new Array(found[0],fieldObj.name)), found);
					} else if (found.index == txt.length - 1) {
						return reportError(fieldObj, getErrMsg("FIELD_CHAR_NOT_ALLOWED_AS_LAST", new Array(found[0],fieldObj.name)), found);
					} else {
						return reportError(fieldObj, getErrMsg("FIELD_CHAR_NOT_ALLOWED_AS_NTH", new Array(found[0],found.index + 1,fieldObj.name)), found);
					}
				} else {
					return reportError(fieldObj, getErrMsg(fieldType + "_STRING_NOT_ALLOWED", new Array(found[0])), found);
				}
			}
		}
	}
	return reportOk(fieldObj);
}

function validEmailAddress(fieldOrEmail, email) {
	var fieldObj = null;
	if (typeof fieldOrEmail == "object" && fieldOrEmail != null && typeof fieldOrEmail.value == "string") {
		fieldObj = fieldOrEmail;
	}
	else if (typeof fieldOrEmail == "string" && fieldOrEmail != "") {
		email = fieldOrEmail; // any second argument is ignored
	}
	if (typeof email != "string" || email == "") {
		if (fieldObj == null) {
	 		self.jslibErrorMsg = jslibDevErrMsg;
			return false;
		}
		email = fieldObj.value;
	}
	email = email.toLowerCase();
	if (email.length > 256) {
		return reportError(fieldObj, getErrMsg("EMAIL_TOO_LONG"));
	}
/*
	Impossible to combine several allowed dots/hyphenations/underscores before the last mandatory dot.
	So the last mandatory dot is check separately.
*/
	var regExp = new RegExp("^[a-zæøå0-9]{1,}([-_\\.]{1}[a-zæøå0-9]{1,}){0,}@[a-zæøå0-9]{1,}(([-_\\.]{1}[a-zæøå0-9]{1,}){1,})$","i");
	var found = regExp.exec(email);
	if (found == null) {
		return reportError(fieldObj, getErrMsg("EMAIL_INVALID"));
	}
	// check the last mandatory dot in the domain part of the email
	regExp.compile("((@|[-_\\.]{1})[a-zæøå0-9]{1,}\\.[a-zæøå]{2,6})$","i");
	found = regExp.exec(email);
	if (found == null) {
		return reportError(fieldObj, getErrMsg("EMAIL_INVALID"));
	}
	return reportOk();
}

function validEmail(fieldOrEmail, email) {
	var fieldObj = null;
	if (typeof fieldOrEmail == "object" && fieldOrEmail != null && typeof fieldOrEmail.value == "string") {
		fieldObj = fieldOrEmail;
	}
	else if (typeof fieldOrEmail == "string" && fieldOrEmail != "") {
		email = fieldOrEmail; // any second argument is ignored
	}
	if (typeof email != "string" || email == "") {
		if (fieldObj == null) {
	 		self.jslibErrorMsg = jslibDevErrMsg;
			return false;
		}
		email = fieldObj.value;
	}
	email = email.toLowerCase();
	if (email == "") {
		return reportError(fieldObj, getErrMsg("EMAIL_NOT_FILLED"));
	}
	else if (email.length < 6) {
		return reportError(fieldObj, getErrMsg("EMAIL_TOO_SHORT"));
	}
	else if (email.length > 256) {
		return reportError(fieldObj, getErrMsg("EMAIL_TOO_LONG"));
	}
	var atArray = email.split("@");
	if (atArray.length == 1) {
		return reportError(fieldObj, getErrMsg("EMAIL_NO_AT"));
	}
	else if (atArray.length > 2) {
		return reportError(fieldObj, getErrMsg("EMAIL_MORE_THAN_ONE_AT"));
	}
	// check for no successive special and otherwise allowed characters
	var regExp = new RegExp("[_\\.@-]{2}","i");
	var found = regExp.exec(email);
	if (found != null) {
		return reportError(fieldObj, getErrMsg("EMAIL_INVALID_SEQUENCE", new Array(found[0])), found);
	}
	// check the first character
	regExp.compile("^[^a-zæøå0-9]","i");
	found = regExp.exec(email);
	if (found != null) {
		return reportError(fieldObj, getErrMsg("EMAIL_INVALID_START", new Array(found[0])), found);
	}
	var firstname = atArray[0];
	var lastname = atArray[1];
	/* check "firstname" in mail address */
	regExp.compile("[^a-zæøå0-9-_\\.]","i");
	found = regExp.exec(firstname);
	if (found != null) {
		return reportError(fieldObj, getErrMsg("EMAIL_INVALID_BEFORE_AT", new Array(found[0])), found);
	}
	/* check "lastname" (domain) in mail address */
	var domArray = lastname.split(".");
	if (domArray.length == 1) {
		return reportError(fieldObj, getErrMsg("EMAIL_NO_DOT_AFTER_AT"));
	}
	var str;
	var minLength = 2;
	var maxLength = 6;
	for (var i = 0; i < domArray.length; i++) {
		str = domArray[i];
		if (i < domArray.length - 1) {
			regExp.compile("[^a-zæøå0-9-_]","i");
			found = regExp.exec(str);
			if (found != null) {
				return reportError(fieldObj, getErrMsg("EMAIL_INVALID_AFTER_AT", new Array(found[0])), found);
			}
		} else { // check top-level domain
			regExp.compile("[^a-zæøå0-9]","i");
			found = regExp.exec(str);
			if (found != null) {
				return reportError(fieldObj, getErrMsg("EMAIL_INVALID_LAST_PART", new Array(found[0])), found);
			}
			else if (str.length < minLength) {
				return reportError(fieldObj, getErrMsg("EMAIL_MIN_NO_OF_CHARS_IN_LAST_PART_OF_DOMAIN", new Array(minLength)));
			}
			else if (str.length > maxLength) {
				return reportError(fieldObj, getErrMsg("EMAIL_MAX_NO_OF_CHARS_IN_LAST_PART_OF_DOMAIN", new Array(maxLength)));
			}
		}	
	}
	return reportOk(fieldObj);
}

function validRadio(radioObj) {
	if (radioObj == null) {
		self.jslibErrorMsg = jslibDevErrMsg;
		return false;
	}
	// if there is only one choice the length property is not defined.
	if (typeof radioObj.length != "number") {
		return true;
	}
	for (var i = 0; i < radioObj.length; i++) {
		if (radioObj[i].checked) {
			return reportOk();
		}
	}
	return reportError(radioObj[0], getErrMsg("RADIO_NOT_CHOSEN", new Array(radioObj[0].name)));
}

function validCheckBox(chBoxObj, minSelection) {
	if (chBoxObj == null) {
		self.jslibErrorMsg = jslibDevErrMsg;
		return false;
	}
	// if there is only one choice the length property is not defined.
	if (typeof chBoxObj.length != "number") {
		return true;
	}
	minSelection = parseInt(minSelection,10);
	if (isNaN(minSelection)) {
		minSelection = 1;
	}
	var count = 0;
	for (var i = 0; i < chBoxObj.length; i++) {
		if (chBoxObj[i].checked) {
			count++;
		}
	}
	if (count < minSelection) {
		if (minSelection > 1) {
			return reportError(chBoxObj[0], getErrMsg("CHBOX_MIN_SELECTED_PLURALIS", new Array(minSelection,chBoxObj[0].name)));
		} else {
			return reportError(chBoxObj[0], getErrMsg("CHBOX_MIN_SELECTED_SINGULARIS", new Array(chBoxObj[0].name)));
		}
	}
	return reportOk();
}

function validSelect(selObj, minSelection) {
	// if the value attribute of the selected option is the empty string, it is not considered valid
	if (selObj == null || typeof selObj != "object" || selObj.options == null) {
		self.jslibErrorMsg = jslibDevErrMsg;
		return false;
	}
	minSelection = parseInt(minSelection,10);
	if (isNaN(minSelection)) {
		minSelection = 1;
	}
	var count = 0;
	var ok = false;
	var optArray = selObj.options;
	for (var i = 0; i < optArray.length; i++) {
		if (optArray[i].selected && optArray[i].value != "") {
			count++;
		}
		if (count >= minSelection) {
			ok = true;
			break;
		}
	}
	if (!ok && minSelection == 1) {
		return reportError(selObj, getErrMsg("SEL_NOT_CHOSEN", new Array(selObj.name)));
	}
	else if (!ok) {
		return reportError(selObj, getErrMsg("SEL_MIN_SELECTED", new Array(minSelection,selObj.name)));
	}
	return reportOk();
}

/* used by link or button of another type than submit */
function doSubmit(form) {
	if (form == null) {
		alert(jslibDevErrMsg);
		return;
	}
	var ok = true;
	if (form.onsubmit != null) {
		ok = form.onsubmit();
	}
	if (ok) {
		form.submit();
	}
}

/* used by link or button of another type than reset */
function doReset(form) {
	if (form == null) {
		alert(jslibDevErrMsg);
		return;
	}
	var ok = true;
	if (form.onreset != null) {
		ok = form.onreset();
	}
	if (ok) {
		form.reset();
	}
}

/*
	Saves a possible error message and the corresponding match array in global variables
	and moves the focus to the form element which contains the error.
	The match array contains information about the match of your regular expression.
*/
function reportError(fieldObj, msg, execArray) {
	if (typeof execArray == "object" && execArray != null && typeof execArray.length == "number") {
		self.jslibExecArray = execArray;
	}
	self.jslibErrorMsg = msg;
	if (fieldObj != null && fieldObj.type != "hidden") {
		// In Opera prior to version 7.1 the focus method is only fired through a new thread (use setTimeout)
		fieldObj.focus();
	}
	return false;
}

function reportOk(fieldObj) {
	if (fieldObj != null) {
		/* make sure that no tags of any kind is submitted in the field by removing the characters '<' and '>' */
		if (fieldObj.type == "text" || fieldObj.type == "hidden" || fieldObj.type == "textarea" || fieldObj.type == "password" || fieldObj.type == "file") {
			fieldObj.value = fieldObj.value.replace(/</g,"&lt;");
			fieldObj.value = fieldObj.value.replace(/>/g,"&gt;");
			if (fieldObj.form.action.toLowerCase().indexOf(".asp") > -1) { // IIS server does not handle input correctly
				fieldObj.value = fieldObj.value.replace(/"/g,"'");
			}
		}
	}
	/* reset for next validation */
	if (self.jslibErrorMsg != null) {
		self.jslibErrorMsg = null; // the delete operator is not supported by IE 5.5 and above
	}
	return true;
}

function getErrMsg(msg, valuesArray) {
	if (typeof jslibMsgDel != "string") {
		return "Invalid input!";
	}
	msg = eval(msg);
	var a = msg.split(jslibMsgDel);
	if (a.length == 1 || valuesArray == null || typeof valuesArray.length != "number" || a.length != valuesArray.length + 1) {
		return msg;
	}
	msg = "";
	var fieldName, label;
	for (var i = 0; i < valuesArray.length; i++) {
		if (i == valuesArray.length - 1 && document.getElementById) {
			fieldName = valuesArray[i];
			label = document.getElementById('Label' + fieldName);
			if (label != null && label.innerHTML != null) {
				fieldName = label.innerHTML;
			}
			msg += a[i] + fieldName;
		} else {
			msg += a[i] + valuesArray[i];
		}
	}
	return msg + a[a.length - 1];
}

// A function for form validation. Should be invoked like this: <form onsubmit="return validStdForm(this)" ...other attributes...>
function validStdForm(form) {
	if (form == null || typeof form != "object") {
		alert(jslibDevErrMsg);
		return false;
	}
	var field, radioName, chBoxName, tmpForm, radioObj, chBoxObj;
	var password = "";
	for (var i = 0; i < form.elements.length; i++) {
		field = form.elements[i];
		/*	On a fieldset element the type attribute is not defined
			For readonly and disabled input elements tabIndex is -1 in Mozilla and 0 in Opera and IE.
			In Netscape 4 it is undefined. */
		
		if (field.type != null) { 
			if (field.type == "text") {
				if (field.name.toLowerCase().indexOf("mail") > -1) {
					if (!validEmail(field)) {
						showErrorMsg(self.jslibErrorMsg);
						return false;
					}
				}
				else if (field.name.toLowerCase().indexOf("search") > -1) {
					if (!validText(field, jslibSearchPattern, false, 2)) {
						showErrorMsg(self.jslibErrorMsg);
						return false;
					}
				}
				else if (field.name.toLowerCase().indexOf("date") > -1) {
					if (!validText(field, jslibDatePattern, true)) {
						showErrorMsg(self.jslibErrorMsg);
						return false;
					}
				}
				else if (field.name.toLowerCase().indexOf("digits") > -1) {
					if (!validText(field, "[\\d]{1,}", true)) {
						showErrorMsg(self.jslibErrorMsg);
						return false;
					}
				}
				else if (!validText(field, "")) {
					showErrorMsg(self.jslibErrorMsg);
					return false;
				}			
			}
			else if (field.type == "password") {
				if (password == "") {
					if (!validText(field,jslibPasswordPattern,false,4,8)) {
						showErrorMsg(self.jslibErrorMsg);
						return false;
					}
					password = field.value;				
				}
				else if	(field.value != password) {
					reportError(field, getErrMsg("PASSWORD_REPEAT"));
					showErrorMsg(self.jslibErrorMsg);
					return false;
				}
			}
			else if (field.type == "radio") {
				/*
					The variable field refers to an entrance in the array of input elements of type radio.
					But this array is actually the radio object.
					Therefore necessary to check if this array has already been validated.
					This is done through the variable radioName.
				*/
				if (radioName != field.name) {
					tmpForm = field.form;
					radioObj = eval("tmpForm." + field.name);
					if (!validRadio(radioObj)) {
						showErrorMsg(self.jslibErrorMsg);
						return false;
					}
					radioName = field.name;
				}
			}
			else if (field.type == "checkbox") {
				if (chBoxName != field.name) {
					tmpForm = field.form;
					chBoxObj = eval("tmpForm." + field.name);

					var emailStatusRequested = false;
					if(form.name.toLowerCase() == "emailservice"){
						for(var tmpCounter = 0; tmpCounter < form.elements.length; tmpCounter++){
							var tmpField = form.elements[tmpCounter];
							if(tmpField.type == "radio" && tmpField.id.toLowerCase() == "status"){
								if(tmpField.checked == true){
									emailStatusRequested = true;
									break;
								}
							}
						}
					}
					
					if(!emailStatusRequested){
						if (!validCheckBox(chBoxObj)) {
							showErrorMsg(self.jslibErrorMsg);
							return false;
						}
					}
					chBoxName = field.name;
				}
			}
			else if (field.type.indexOf("select") > -1) {
				if (!validSelect(field)) {
					showErrorMsg(self.jslibErrorMsg);
					return false;
				}
			}
		}
	}
	return true;
}

function showErrorMsg(msg) {
	alert(msg);
}

// A function to reset a form. Should be invoked like this: <form onreset="return resetStdForm(this)" ...other attributes...>
function resetStdForm() {
	return confirm(getErrMsg("RESET_FORM"));
}

/*	The following patterns are some commonly used patterns for input fields. */

// this pattern allows only digits as keyboard input (\\b for backspace key - necessary in Netscape 4+ otherwise backspace won't work)
var jslibOnlyDigitsPattern = "[^\\d\\b]";

// this pattern do not allow the danish letters æ, ø and å as keyboard input
var jslibPasswordPattern = "[^a-zA-Z0-9-_\\b]";

/*	Pattern to validate a search-string against on form submittal.
	Remember to specify doMatch as false in the validText function (see validStdForm for an example) */
var jslibSearchPattern = "[\\*\\?_-]{2}";

/*	Pattern to validate a date-string against on form submittal.
	Remember to specify doMatch as true in the validText function (see validStdForm for an example) */
var jslibDatePattern = "^([1-9]{1}|([0-2]{1}[0-9]{1}|[3]{1}[0-1]{1}))([-\\./]{1})([1-9]{1}|([0]{1}[0-9]{1}|[1]{1}[0-2]{1}))\\3([0-9]{2}|[1-9]{1}[0-9]{2}|[1-9]{1}[0-9]{3})$";

/*	A date can be written like dd-mm-yyyy, dd/mm/yyyy or dd.mm.yyyy. Or like dd-mm-yy or dd-mm-yyy.
	If you specify 3 or 4 digits in the year the first one cannot be 0.
	Note that the american way yyyy/dd/mm is invalid by this pattern.
	But doMatch must be specified as true. In the array returned by the exec method of the regular expression the day part (dd) is the second entry (index 1),
	the month part (mm) is the fifth entry (index 4) and the year part (yyyy) is the seventh entry (index 6). */
