// default function to validate a form
function validateForm (formObject){
	var validator = new formValidator('default');
	var valid = validator.validateForm(formObject);
	return valid;
}

/**
 * function to validate a form and display the error-messages differently
 * see setMessage() for the different modes and their requirements
 */
function validateFormPlus(formObject, MODE){
	var validator = new formValidator(MODE);
	var valid = validator.validateForm(formObject);
	return valid;
}

if (!window.getObj){
	function getObj(name)
	{
	  if (document.getElementById)
	  {
	  	this.obj = document.getElementById(name);
			if( this.obj )
				this.style = document.getElementById(name).style;
	  }
	  else if (document.all)
	  {
	  	this.obj = document.all[name];
			if( this.obj )
		  	this.style = document.all[name].style;
	  }
	  else if (document.layers)
	  {
	   	this.obj = document.layers[name];
	   	this.style = document.layers[name];
	  }
	}
	
	function getElement( name )
	{
	  	var myObj = new getObj( name );
		return myObj.obj;
	}
}


 /**
	* formValidator klasse - ME
	* Valideert een HTML form op basis van attributen, datatypes en input tags
	* Versie 0.2 - 11/10/05
	*/

function formValidator(MODE)
{
	// globale constanten
	var VALIDATION_ERROR 	= "Onjuiste invoer.";
	var REGEX_ERROR 		= "Invoer bevat verkeerd formaat.";
	var REQUIRED_ERROR 		= "verplicht";
	var DATATYPE_ERROR 		= "Onjuiste invoer.";
	var LENGTH_ERROR 		= "Tekstinvoer moet liggen tussen de {0} en {1} tekens.";
	var MIN_LENGTH_ERROR	= "De invoer moet minimaal {0} tekens zijn.";
	var MAX_LENGTH_ERROR	= "De invoer mag maximaal {0} tekens zijn.";
	var SIZE_ERROR 			= "Numerieke invoer moet liggen tussen {0} en {1}.";
	var UNEQUAL_ERROR		= "Dit veld dient gelijk te zijn met {0}.";
	var DATUM_FORMAAT_ERROR 	= "Het datum formaat moet zijn: dd-mm-yyyy";
	var MAAND_ERROR 		= "Voer een valide maand in.";
	var DAG_ERROR 		= "Voer een valide dag in.";
	var JAAR_ERROR 		= "Voer een jaar tussen {0} en {1} in.";
	var DATUM_ERROR 	= "Voer een valide datum in.";
	
	var VALIDATION_ERROR_GROUPED = "{0} heeft een onjuiste invoer.";
	var REGEX_ERROR_GROUPED 		= "Invoer voor {0} heeft een verkeerd formaat.";
	var REQUIRED_ERROR_GROUPED 		= "Het veld {0} is verplicht.";
	var DATATYPE_ERROR_GROUPED 		= "Onjuiste invoer voor {0}.";
	var LENGTH_ERROR_GROUPED 		= "Invoer voor {0} moet liggen tussen de {1} en {2} tekens lang zijn.";
	var MIN_LENGTH_ERROR_GROUPED	= "De invoer voor {0} moet minimaal {1} tekens zijn.";
	var MAX_LENGTH_ERROR_GROUPED	= "De invoer voor {0} mag maximaal {1} tekens zijn.";
	var SIZE_ERROR_GROUPED 			= "Numerieke invoer voor {0} moet liggen tussen {1} en {2}.";
	var UNEQUAL_ERROR_GROUPED		= "De velden {0} en {1} dienen aan elkaar gelijk te zijn.";
	var DATUM_FORMAAT_ERROR_GROUPED	= "Het formaat van {0} moet zijn: dd-mm-yyyy";
	var MAAND_ERROR_GROUPED 		= "{0} heeft geen valide waarde voor de maand";
	var DAG_ERROR_GROUPED 		= "{0} heeft geen valide waarde voor de dag";
	var JAAR_ERROR_GROUPED 		= "{0} moet een waarde voor jaar hebben tussen {1} en {2}.";
	var DATUM_ERROR_GROUPED 		= "Bij {0} moet een valide datum worden ingevuld.";
	
	// constanten voor weergave	
	var ERROR_ID = "formError"; // id van de error-message
	var WARNING_ID = "formWarning"; // id van de warning-message
	var GROUPED_ID = "groupValidation"; // id van de "verzamelplaats" (plaats waar de errors eventueel gezamenlijk worden getoond)
	var INPUT_CLASS = "noVeldError"; // klasse van het input-veld zonder error
	var ERROR_INPUT_CLASS = "veldError"; // klasse van het input-veld als de error optreed
	var GROUPED_CLASS = "noGroupError"; // klasse van de verzamelplaats zonder errors
	var ERROR_GROUPED_CLASS = "groupError"; // klasse van de verzamelplaats als een of meerdere errors optreden
	
	var DATE_SEPARATOR = "-";
	var MIN_YEAR = 1900;
	var MAX_YEAR = 9999;
	
	// globale basistypes
	var UNKNOWN = 0;
	var INTEGER = 1;
	var STRING = 2;
	var DATE = 3;
	var EMAIL = 4;
	
	// mins en maxs voor numerieke waarden
	var INT64_MAX_SIGNED =  9223372036854775807;
	var INT64_MIN_SIGNED = -9223372036854775808;
	var INT64_MAX_UNSIGNED = 18446744073709551615;
	var INT64_MIN_UNSIGNED = 0;
	var INT32_MAX_SIGNED =  2147483647;
	var INT32_MIN_SIGNED = -2147483648;
	var INT32_MAX_UNSIGNED = 4294967295;
	var INT32_MIN_UNSIGNED = 0;
	var INT24_MAX_SIGNED =  8388607;
	var INT24_MIN_SIGNED = -8388608;
	var INT24_MAX_UNSIGNED = 16777216;
	var INT24_MIN_UNSIGNED = 0;
	var INT16_MAX_SIGNED = 32767;
	var INT16_MIN_SIGNED = -32768;
	var INT16_MAX_UNSIGNED = 65535;
	var INT16_MIN_UNSIGNED = 0;
	var INT8_MAX_SIGNED =  127;
	var INT8_MIN_SIGNED = -128;
	var INT8_MAX_UNSIGNED = 255;
	var INT8_MIN_UNSIGNED = 0;
	
	var MONEY_MIN = -922337203685477.5808;
	var MONEY_MAX =  922337203685477.5807;
	var SMALLMONEY_MIN = -214748.3648;
	var SMALLMONEY_MAX =  214748.3647;
	
	var STRING_MIN = 0;
	
	var VARCHAR_MAX = 8000;
	var NVARCHAR_MAX = 8000;
	var CHAR_MAX = 255;
	var TEXT_MAX = 2147483647;
	var NTEXT_MAX = 2147483647;
	
	// default waarden
	var m_ErrorBackColor = "#AA0000";
	var m_ErrorTextColor = "#000000";
	var m_WarningBackColor = "#FFFF88";
	var m_WarningTextColor = "#000000";

	var m_DecimalChar = ",";
	
	// globale variabelen
	var m_FormToValidate = null;
	
	// -------------------------------------------------------------------------
	// public functies
	this.validateForm = validateForm;
	this.validateField = validateField;
	this.setDecimalChar = setDecimalChar;
	this.getDecimalChar = getDecimalChar;
	
	// -------------------------------------------------------------------------
	// private functies
	
	// valideert het opgegeven formulier
	function validateForm( formObj)
	{
		if( !isSet( formObj ) ) // controleer of het form bestaat
			return false;
		
		m_FormToValidate = formObj;
		
		var validated = true;
		removeAllMessages();
		// ga elk element af in de form
		for( var i=0; i<formObj.elements.length; i++ )
		{
			
		//alert (formObj.elements[i].id);
			if( formObj.elements[i].type == "submit" || formObj.elements[i].type == "button" || formObj.elements[i].type == "reset" )
				continue;
			
			if( !isSet( formObj.elements[i].id ) )
				continue;
			
			if( !validateField( formObj.elements[i] ) )
				validated = false;
		}
		
		/**
		* This is a hook!! (a hook! a hook! hoeza!)
		* The script looks for a function named validateFormCustom
		* This function can be put anywhere on the page and returns
		* a boolean (pass/no-pass). The contents of the function can be anything.
		*/
		if (window.validateFormCustom){
			customValidated = validateFormCustom();
			if (!customValidated) validated = customValidated;
		}
		return validated;
	}
	
	// -------------------------------------------------------------------------
	
	function validateField( field )
	{
		if( !isSet( field ) ) // invalideer wanneer het veld niet bestaat
			return false;
		var validated = true; // return variabele
		
		//supressMessage( field.id, WARNING_ID );
		//supressMessage( field.id, ERROR_ID );
		
		// check of het veld required is
		if( validated )
			validated = validateRequired( field );
		
		// controleer op invoer enkel als er iets te controleren valt
		if(getFieldValue(field) != ""){
			// controleer op datatype als het veld nog steeds valide is
			if( validated )
				validated = validateDataType( field );
				
			// minlength
			if( validated )
				validated = validateLength( field );
			
			// regex
			if( validated )
				validated = validateRegEx( field );
			
			// same as another
			if (validated)
				validated = validateEqual( field );
		}	
		return validated;
	}
	
	// -------------------------------------------------------------------------
	// controleert op verplicht veld
	function validateRequired( field )
	{
		var validated = true;
		required = field.getAttribute("required");
		if( !isSet( required ) || required == "0" || required == "false" || required == "FALSE" || required == "False")
			return true;
		
		var value = getFieldValue( field );

		if( ( required == "1" || required == "true" ) && !isSet( value ) )
		{
			// zet een error als het veld leeg is
			if(MODE == "grouped"){
				var error = REQUIRED_ERROR_GROUPED.replace( /\{0\}/, field.name);
			}else{
				var error = REQUIRED_ERROR;
			}
			setError( field.id, error );
			validated = false;
		}
		
		return validated;
	}

	// -------------------------------------------------------------------------
	// controleert of de invoer overeenkomt met het datatype
	function validateDataType( field )
	{
		var validated = true;
	
		// controleer of datatype is gezet
		if( !isSet( field.getAttribute("datatype") ) )
			return true;
		
		var dataType = (field.getAttribute("datatype")).toLowerCase(); // pak datatype
		
		// lokale vars
		var basicType = 0;
		var decimals = 0;
		
		// bepaal minimale en maximale grootte van de invoer
		// deze kunnen gewijzigd worden met de attributen "minLength" en "maxLength" (historische redenen)
		if(!field.getAttribute("min")){
			var minimum = getMinValue( dataType, isSigned( field ) );
		}else{
			var minimum = Number(field.getAttribute("min"));
		}
		
		if(!field.getAttribute("max")){
			var maximum = getMaxValue( dataType, isSigned( field ) );
		}else{
			var maximum = Number(field.getAttribute("max"));
		}

		// globaliseren naar basistypes
		if( dataType == "int" || dataType == "int32" || dataType == "bigint" || dataType == "smallint" || dataType == "tinyint" || dataType == "mediumint" )
		{
			basicType = INTEGER;
			decimals = 0;
			if( minimum == null )
				minimum = 0;
		}
		else if( dataType == "decimal" || dataType == "float" || dataType == "money" || dataType == "double" || dataType == "smallmoney" )
		{
			basicType = INTEGER;
			decimals = -1;
			if( minimum == null )
				minimum = 0;
		}
		else if( dataType == "char" || dataType == "string" || dataType == "varchar" || dataType == "nvarchar" || dataType == "text" || dataType == "ntext" || dataType == "tinytext" || dataType == "mediumtext" || dataType == "longtext" || dataType == "nchar" )
		{
			basicType = STRING;
			if( minimum == null )
				minimum = STRING_MIN;
			if( maximum == null )
				maximum = 255;
		}
		else if( dataType == "datetime" || dataType == "smalldatetime" || dataType == "date" || dataType == "time" )
		{
			basicType = DATE;
			if( minimum == null )
				minimum = 0;
		}
		else if( dataType == "email" )
		{
			basicType = EMAIL;
		}
		else
		{
			basicType = UNKNOWN;
		}
		
		// functies voor het afhandelen van de basistypes
		switch( basicType )
		{
			case INTEGER:
				// controleer of invoer numeriek is zoals het datatype
				if( !isNumeric( getFieldValue( field ), decimals ) )
				{
					if(MODE == "grouped"){
						var error = DATATYPE_ERROR_GROUPED.replace( /\{0\}/, field.name);
					}else{
						var error = DATATYPE_ERROR;
					}
					setError( field.id, error );
					validated = false;
				}
				else
				{
					// controleer de waarde van het getal
					if( !validateSize( field, minimum, maximum ) )
					{
						if(MODE == "grouped"){
							var error = SIZE_ERROR_GROUPED.replace( /\{0\}/, field.name);
							error = error.replace( /\{1\}/, minimum);
							error = error.replace( /\{2\}/, maximum);
						}else{
							var error = SIZE_ERROR;
							error = error.replace( /\{0\}/, minimum );
							error = error.replace( /\{1\}/, maximum );
						}
						setError( field.id, error );
						validated = false;
					}
				}
				break;
			
			case STRING:
				// controleer de lengte van de invoer
				if( !validateLength( field, minimum, maximum ) )
				{
					if(MODE == "grouped"){
						var error = LENGTH_ERROR_GROUPED.replace(/\{0\}/, field.name);
						error = error.replace( /\{1\}/, minimum );
						error = error.replace( /\{2\}/, maximum );
					}else{
						var error = LENGTH_ERROR;
						error = error.replace( /\{0\}/, minimum );
						error = error.replace( /\{1\}/, maximum );
					}
					setError( field.id, error );
					validated = false;
				}
				break;
			
			case DATE:
				validated = isDate( field );
				break;
				
			case EMAIL:
				validated = isValidEmail( field );
				break;
				
			case ZipCodeNL:
				validated = isValidZipCodeNL( field );
				break;
			
			default:
				setWarning( field.id, "Onbekend datatype of geen datatype gespecificeerd." );
				break;
		}
		
		return validated;
	}

	// -------------------------------------------------------------------------
	// valideert signed number
	function isSigned( field )
	{
		var signed = false;
		
		if( isSet( field.getAttribute("signed") ) )
		{
			if( field.getAttribute("signed") == "1" || field.getAttribute("signed") == "true" )
				signed = true;
		}
		
		return signed;
	}

	
	// -------------------------------------------------------------------------
	// controleert of veld gelijk is aan gegeven ander veld
	function validateEqual( field )
	{
		var validated = true;
		otherFieldId = field.getAttribute("equals");
		if( !isSet( otherFieldId ) )
			return true;
		
		var value = getFieldValue( field );
		var otherValue = document.getElementById(otherFieldId);
		if ( !isSet(otherValue) || getFieldValue(otherValue) != value )
		{
			// zet een error als het veld
			if(MODE == "grouped"){ 
				var error = UNEQUAL_ERROR_GROUPED.replace( /\{0\}/, field.name);
				error = error.replace( /\{1\}/, otherValue.name);
			}else{
				var error = UNEQUAL_ERROR.replace( /\{0\}/, otherValue.name);
			}
			setError( field.id, error);
			validated = false;
		}
		
		return validated;
	}

	
	// -------------------------------------------------------------------------

	function daysInFebruary( year )
	{
		// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return ( ( ( year % 4 == 0 ) && ( ( !( year % 100 == 0 ) ) || ( year % 400 == 0 ) ) ) ? 29 : 28 );
	}
	
	// -------------------------------------------------------------------------
	function daysArray( n )
	{
		for( var i = 1; i <= n; i++ )
		{
			n[i] = 31;
			
			if( i==4 || i==6 || i==9 || i==11 )
				n[i] = 30;
			
			if( i==2 )
				n[i] = 29;
		 }
		 return n;
	}

	// -------------------------------------------------------------------------
	function isDate( field )
	{
		dtStr = getFieldValue( field );
		
		var daysInMonth = daysArray( 12 );
		var pos1 = dtStr.indexOf( DATE_SEPARATOR );
		var pos2 = dtStr.indexOf( DATE_SEPARATOR, pos1 + 1 );
		var strDay = dtStr.substring( 0, pos1 );
		var strMonth = dtStr.substring( pos1 + 1, pos2 );
		var strYear = dtStr.substring( pos2 + 1 );

		strYr = strYear;
		
		if( strDay.charAt( 0 ) == "0" && strDay.length > 1 )
			strDay = strDay.substring( 1 );

		if( strMonth.charAt( 0 ) == "0" && strMonth.length > 1 )
			strMonth = strMonth.substring( 1 );

		for( var i = 1; i <= 3; i++ )
		{
			if( strYr.charAt( 0 ) == "0" && strYr.length > 1 )
				strYr = strYr.substring( 1 );
		}
		
		month = parseInt( strMonth );
		day = parseInt( strDay );
		year = parseInt( strYr );
		
		if( pos1 == -1 || pos2 == -1 )
		{
			if(MODE == "grouped"){
				var error = DATUM_FORMAAT_ERROR_GROUPED.replace( /\{0\}/, field.name);
			}else{
				var error = DATUM_FORMAAT_ERROR;
			}
			setError( field.id, error);
			return false;
		}
		
		if( strMonth.length < 1 || month < 1 || month > 12 )
		{
			if(MODE == "grouped"){
				var error = MAAND_ERROR_GROUPED.replace( /\{0\}/, field.name);
			}else{
				var error = MAAND_ERROR;
			}
			setError( field.id, error );
			return false;
		}
		
		if( strDay.length < 1 || day < 1 || day > 31 || ( month == 2 && day > daysInFebruary( year ) ) || day > daysInMonth[ month ] )
		{
			if(MODE == "grouped"){
				var error = DAG_ERROR_GROUPED.replace( /\{0\}/, field.name);
			}else{
				var error = DAG_ERROR;
			}
			setError( field.id, error );
			return false;
		}
		
		if( strYear.length != 4 || year==0 || year < MIN_YEAR || year > MAX_YEAR )
		{
			if(MODE == "grouped"){
				var error = JAAR_ERROR_GROUPED.replace(/\{0\}/, field.name);
				error = error.replace(/\{1\}/, MIN_YEAR);
				error = error.replace(/\{2\}/, MAX_YEAR);
			}else{
				var error = JAAR_ERROR.replace( /\{0\}/, MIN_YEAR);
				error = error.replace(/\{1\}/, MAX_YEAR);
			}
			setError( field.id, error );
			return false;
		}
		
		if( dtStr.indexOf( DATE_SEPARATOR, pos2 + 1 ) != -1 || isNumeric( stripCharsInBag( dtStr, DATE_SEPARATOR ), 0 ) == false )
		{
			if(MODE == "grouped"){
				var error = DATUM_ERROR_GROUPED.replace( /\{0\}/, field.name);
			}else{
				var error = DATUM_ERROR;
			}
			setError( field.id, error );
			return false;
		}
		
		return true;
	}

	// -------------------------------------------------------------------------

	function stripCharsInBag(s, bag)
	{
		var i;
    var returnString = "";
		var c;
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++)
		{   
        c = s.charAt(i);
        if( bag.indexOf(c) == -1 )
					returnString += c;
    }
    return returnString;
	}
	
	// -------------------------------------------------------------------------
	// geef maximale waarde
	function getMaxValue( dataType, signed )
	{
		var maxVal = 0;
		
		switch( dataType )
		{
			case "tinyint":
				if( signed )
					maxVal = INT8_MAX_SIGNED;
				else
					maxVal = INT8_MAX_UNSIGNED;
				break;
			
			case "smallint":
				if( signed )
					maxVal = INT16_MAX_SIGNED;
				else
					maxVal = INT16_MAX_UNSIGNED;
				break;
			
			case "mediumint":
				if( signed )
					maxVal = INT24_MAX_SIGNED;
				else
					maxVal = INT24_MAX_UNSIGNED;
				break;

			case "int":
				if( signed )
					maxVal = INT32_MAX_SIGNED;
				else
					maxVal = INT32_MAX_UNSIGNED;
				break;
			
			case "bigint":
				if( signed )
					maxVal = INT64_MAX_SIGNED;
				else
					maxVal = INT64_MAX_UNSIGNED;
				break;
			
			case "money":
				maxVal = MONEY_MAX;
				break;
			
			case "smallmoney":
				maxVal = SMALLMONEY_MAX;
				break;
			
			case "char":
				maxVal = CHAR_MAX;
				break;
			
			case "varchar":
				maxVal = VARCHAR_MAX;
				break;
			
			case "nvarchar":
				maxVal = NVARCHAR_MAX;
				break;
			
			case "text":
				maxVal = TEXT_MAX;
				break;
			
			case "ntext":
				maxVal = NTEXT_MAX;
				break;
			
			default:
				maxVal = null;
				break;
		}
		return maxVal;
	}

	// -------------------------------------------------------------------------
	// geef minimale waarde
	function getMinValue( dataType, signed )
	{
		var minVal = 0;
		
		switch( dataType )
		{
			case "tinyint":
				if( signed )
					minVal = INT8_MIN_SIGNED;
				else
					minVal = INT8_MIN_UNSIGNED;
				break;
			
			case "smallint":
				if( signed )
					minVal = INT16_MIN_SIGNED;
				else
					minVal = INT16_MIN_UNSIGNED;
				break;
			
			case "mediumint":
				if( signed )
					minVal = INT24_MIN_SIGNED;
				else
					minVal = INT24_MIN_UNSIGNED;
				break;

			case "int":
				if( signed )
					minVal = INT32_MIN_SIGNED;
				else
					minVal = INT32_MIN_UNSIGNED;
				break;
			
			case "bigint":
				if( signed )
					minVal = INT64_MIN_SIGNED;
				else
					minVal = INT64_MIN_UNSIGNED;
				break;
			
			case "money":
				minVal = MONEY_MIN;
				break;
			
			case "smallmoney":
				minVal = SMALLMONEY_MIN;
				break;
						
			default:
				minVal = null;
				break;
		}
		
		return minVal;
	}

	// -------------------------------------------------------------------------
	// valideert integer waarde
	function validateSize( field, minimum, maximum )
	{
		var validated = true;
		var value = getFieldValue( field );
		
		if( minimum != null && value < minimum )
		{
			validated = false;
		}
		
		if( validated )
		{
			if( maximum != null && value > maximum )
			{
				validated = false;
			}
		}
		return validated;
	}
	
	// -------------------------------------------------------------------------
	// valideert veldlengte van strings indien opgegeven
	function validateLength( field, borderMinimum, borderMaximum )
	{
		var validated = true;
		var value = getFieldValue( field );
		
		maxLength = field.getAttribute("maxlength");
		minLength = field.getAttribute("minlength");
		
		if( borderMinimum != null && value.length < borderMinimum )
		{
			if(MODE == "grouped"){
				var error = LENGTH_ERROR_GROUPED.replace( /\{0\}/, field.name);
				error = error.replace( /\{1\}/, borderMinimum );
				error = error.replace( /\{2\}/, borderMaximum );
			}else{
				var error = LENGTH_ERROR;
				error = error.replace( /\{0\}/, borderMinimum );
				error = error.replace( /\{1\}/, borderMaximum );
			}
			setError( field.id, error );
			validated = false;
		}
		if( isSet( minLength ) )
		{
			if( value.length < minLength )
			{
				if(MODE == "grouped"){
					var error = MIN_LENGTH_ERROR_GROUPED.replace( /\{0\}/, field.name);
					error = error.replace( /\{1\}/, minLength );
				}else{
					var error = MIN_LENGTH_ERROR;
					error = error.replace( /\{0\}/, minLength );
				}
				setError( field.id, error );
				validated = false;
			}
		}
		if( validated )
		{
			if( borderMaximum != null && value.length > borderMaximum )
			{
				if(MODE == "grouped"){
				var error = LENGTH_ERROR_GROUPED.replace( /\{0\}/, field.name);
				error = error.replace( /\{1\}/, borderMinimum );
				error = error.replace( /\{2\}/, borderMaximum );
			}else{
				var error = LENGTH_ERROR;
				error = error.replace( /\{0\}/, borderMinimum );
				error = error.replace( /\{1\}/, borderMaximum );
			}
				setError( field.id, error );
				validated = false;
			}
			if( isSet( maxLength ) )
			{
				if( value.length > maxLength )
				{
					if(MODE == "grouped"){
						var error = MAX_LENGTH_ERROR_GROUPED.replace( /\{0\}/, field.name);
						error = error.replace( /\{1\}/, maxLength );
					}else{
						var error = MAX_LENGTH_ERROR;
						error = error.replace( /\{0\}/, maxLength );
					}
					setError( field.id, error );
					validated = false;
				}
			}
		}
		return validated;
	}

	// -------------------------------------------------------------------------
	// valideert regular expression indien opgegeven
	function validateRegEx( field )
	{
		regex = field.getAttribute("regex");
		if( !isSet( regex ) )
			return true;
		
		var validated = true;
		var value = getFieldValue( field );
		var regEx = new RegExp( regex );
		
		if( !value.match( regEx ) )
		{
			if(MODE == "grouped"){
				var error = REGEX_ERROR_GROUPED.replace( /\{0\}/, field.name);
			}else{
				var error = REGEX_ERROR;
			}
			setError( field.id, error );
			return false;
		}
		
		return validated;
	}

	// -------------------------------------------------------------------------
	function setDecimalChar( newChar )
	{
		if( newChar.length > 1 )
		{
			alert( "DecimalChar mag slechts ??n teken lang zijn." );
			return;
		}
		
		m_DecimalChar = newChar;
	}
	
	// -------------------------------------------------------------------------	
	function getDecimalChar()
	{
		return m_DecimalChar;
	}
	
	// -------------------------------------------------------------------------	
	// geeft bool terug die aangeeft of de waarde numeriek is of niet
	function isNumeric( value, decimal )
	{
		var numeric = true;
		var validChars = "-0123456789";
		
		if( decimal != 0 )
			validChars += m_DecimalChar;
		
		var vchar = null;
		
		for( var i = 0; i < value.length && numeric == true; i++ )
		{
			vchar = value.charAt( i );
			if( validChars.indexOf( vchar ) == -1 )
			{
				numeric = false;
				break;
			}
		}
		
		return numeric;
	}
	
	// -------------------------------------------------------------------------	
	// controleert of een waarde is gezet
	function isSet( value )
	{
		if( value == null || value == "undefined" || value == "" )
			return false;
		else
			return true;
	}
	
	// -------------------------------------------------------------------------	
	// voegt een warning aan een object met bepaalde id toe
	function setWarning( objId, warningMsg )
	{
		supressMessage( objId, WARNING_ID );
		setMessage( objId, WARNING_ID, "Waarschuwing: " + warningMsg );
	}
	
	// -------------------------------------------------------------------------	
	// voegt een error aan een object met een bepaalde id toe
	function setError( objId, errorMsg )
	{
//		supressMessage( objId, ERROR_ID );
		setMessage( objId, ERROR_ID, errorMsg );
	}

	// plaats een aanvullende className (en behoud de bestaande)
	function setClassName(obj, newClassName){
		var classNames = obj.className.split(' ');
		for (var j = 0; j < classNames.length; j++) {
		 	if(classNames[j] == newClassName){
		 		return true;
		 	}
		}
		obj.className = obj.className + " " + newClassName;
		return true;
	}
	
	// verwijder slechts 1 className
	function removeClassName(obj, className){
		var newClassName = "";
		var classNames = obj.className.split(' ');
		for (var j = 0; j < classNames.length; j++) {
		 	if(classNames[j] != className){
		 		if(newClassName == ""){
		 			newClassName = classNames[j];
		 		}else{
		 			newClassName = newClassName + "  " + classNames[j];
		 		}
		 	}
		}
		obj.className = newClassName;
		return true;
	}

	// -------------------------------------------------------------------------
	// zet een error of warning onder het invalide control
	function setMessage( objId, typeId, msg )
	{
		if( !isSet( objId ) )
			return;

		switch(MODE){
			case 'default':
				var text = document.createTextNode( msg );
				var paragraph = document.createElement( "span" );
				paragraph.appendChild( text );
				paragraph.className = typeId;
				paragraph.setAttribute( "id", ERROR_ID );
				
				var frm = m_FormToValidate;
				var field = frm.elements[ objId ];
				var prnt = field.parentNode;
				prnt.insertBefore(paragraph, field.nextSibling );
				break;
				
			case 'grouped':
				var field = m_FormToValidate.elements[objId];
				removeClassName(field, INPUT_CLASS);
				setClassName(field, ERROR_INPUT_CLASS);
				
				var holder = document.getElementById(GROUPED_ID);
				var uls = holder.getElementsByTagName("ul");
				if(uls.length == 0){
					var list = document.createElement("ul");
					list.id = ERROR_ID;
					holder.appendChild(list);
				}else{
					var list = uls[0];
				}  
				
				/**
				 * If the field has a "displayName" attribute, use it.
				 */				 				 				 
				
				var fieldName;
				if(field.hasAttribute && field.hasAttribute('displayName')){
					fieldName = field.getAttribute('displayName');
				}
				// syntax for browsers which don't support hasAttribute() like IE6
				else if (field.attributes && field.attributes['displayName']!=null)
				{
					fieldName = field.attributes['displayName'].value;
				}
				else {
					fieldName = field.name;
				}

				var text = document.createTextNode(fieldName);
				var item = document.createElement( "li" );
				item.appendChild( text );
				//item.className = typeId;
				//item.setAttribute( "id", ERROR_ID );
				list.appendChild(item);
				
				holder.appendChild(list);
				removeClassName(holder, GROUPED_CLASS);
				setClassName(holder, ERROR_GROUPED_CLASS);
			
				break;
		}
	}
	/*}*/
	
	// -------------------------------------------------------------------------
	// verwijdert alle errors van het formulier
	function supressMessage( objId, typeId )
	{
		/*
		var frm = m_FormToValidate;
		var field = frm.elements[objId];
		
    prnt = field.parentNode;
		
    if( prnt.className.indexOf( typeId ) >= 0 )
		{
      var org = field.cloneNode( true );
      frm = prnt.parentNode;
			
      prnt.removeChild( field );
      prnt.removeChild( prnt.lastChild );
      
			frm.replaceChild( org, prnt );
    }
    */
	}
	
	function removeAllMessages(){
		//var children = m_FormToValidate.elements;
		var children = m_FormToValidate.getElementsByTagName('*');
		// remove messages in default mode  
		for (var i = 0; i < children.length; i++) {
		  var child = children[i];
		  var classNames = child.className.split(' ');
		  for (var j = 0; j < classNames.length; j++) {
		    if (classNames[j] == ERROR_ID || classNames[j] == WARNING_ID) {
					frm = child.parentNode;
	      	frm.removeChild(child);
		      break;
		    }
		    
				// dit zou voor de duidelijkheid buiten dit blok moeten, maar we waren
				// hier toch al door het form aan het lopen.
				if(MODE == 'grouped'){
		    	removeClassName(child, ERROR_INPUT_CLASS);
		    	setClassName(child, INPUT_CLASS);
		    }
		  }
		}
		
		// remove messages in grouped mode
		if(MODE == 'grouped'){
			holder = document.getElementById(GROUPED_ID);
			removeClassName(holder, ERROR_GROUPED_CLASS);
			setClassName(holder, GROUPED_CLASS);
			for(var i = 0; i < holder.childNodes.length; i++){
				if(holder.childNodes[i].id == ERROR_ID){
					holder.removeChild(holder.childNodes[i]);
					i--;
				}
			}
		}
		return;
	}
	
	// -------------------------------------------------------------------------
	// geef de veldwaarde
	function getFieldValue( field )
	{
		var value = field.value;
		/*
		useInnerText = field.getAttribute("useinnertext");
		
		if( isSet( useInnerText ) )
		{
			if( useInnerText == "true" || useInnerText == "1" )
			{
				value = field.value;
			}
		}
		*/
		return value;
	}
	
	function isValidZipCodeNL(field)
	{
		if(MODE == "grouped"){
			var error = DATATYPE_ERROR_GROUPED.replace( /\{0\}/, field.name);
		}else{
			error = DATATYPE_ERROR;
		}
		zipcodestr = getFieldValue( field );
		
		//match regex
		var ZipRegEx = new RegExp("/^\W*[1-9]{1}[0-9]{3}\W*[a-zA-Z]{2}\W*$/"); 		
		var matchArray=emailStr.match(ZipRegEx);
		
		//
		if(matchArray==null)
		{
			setError(field.id, error);
			return false;
		}
		
		return true;
	}
	
	function isValidEmail(field){
		if(MODE == "grouped"){
			var error = DATATYPE_ERROR_GROUPED.replace( /\{0\}/, field.name);
		}else{
			error = DATATYPE_ERROR;
		}
		emailStr = getFieldValue( field );
		/* The following variable tells the rest of the function whether or not
		to verify that the address ends in a two-letter country or well-known
		TLD.  1 means check it, 0 means don't. */
		
		var checkTLD=1;
		
		/* The following is the list of known TLDs that an e-mail address must end with. */
		
		var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
		
		/* The following pattern is used to check if the entered e-mail address
		fits the user@domain format.  It also is used to separate the username
		from the domain. */
		
		var emailPat=/^(.+)@(.+)$/;
		
		/* The following string represents the pattern for matching all special
		characters.  We don't want to allow special characters in the address. 
		These characters include ( ) < > @ , ; : \ " . [ ] */
		
		var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
		
		/* The following string represents the range of characters allowed in a 
		username or domainname.  It really states which chars aren't allowed.*/
		
		var validChars="\[^\\s" + specialChars + "\]";
		
		/* The following pattern applies if the "user" is a quoted string (in
		which case, there are no rules about which characters are allowed
		and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
		is a legal e-mail address. */
		
		var quotedUser="(\"[^\"]*\")";
		
		/* The following pattern applies for domains that are IP addresses,
		rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
		e-mail address. NOTE: The square brackets are required. */
		
		var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
		
		/* The following string represents an atom (basically a series of non-special characters.) */
		
		var atom=validChars + '+';
		
		/* The following string represents one word in the typical username.
		For example, in john.doe@somewhere.com, john and doe are words.
		Basically, a word is either an atom or quoted string. */
		
		var word="(" + atom + "|" + quotedUser + ")";
		
		// The following pattern describes the structure of the user
		
		var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
		
		/* The following pattern describes the structure of a normal symbolic
		domain, as opposed to ipDomainPat, shown above. */
		
		var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
		
		/* Finally, let's start trying to figure out if the supplied address is valid. */
		
		/* Begin with the coarse pattern to simply break up user@domain into
		different pieces that are easy to analyze. */
		
		var matchArray=emailStr.match(emailPat);
		
		if (matchArray==null) {
		
		/* Too many/few @'s or something; basically, this address doesn't
		even fit the general mould of a valid e-mail address. */
			setError(field.id, error);
			return false;
		}
		var user=matchArray[1];
		var domain=matchArray[2];
		
		// Start by checking that only basic ASCII characters are in the strings (0-127).
		
		for (i=0; i<user.length; i++) {
			if (user.charCodeAt(i)>127) {
				setError(field.id, error);
				return false;
		  }
		}
		for (i=0; i<domain.length; i++) {
			if (domain.charCodeAt(i)>127) {
				setError(field.id, error);
				return false;
		 	}
		}
		
		// See if "user" is valid 
		
		if (user.match(userPat)==null) {
		
		// user is not valid
		
			setError(field.id, error);
			return false;
		}
		
		/* if the e-mail address is at an IP address (as opposed to a symbolic
		host name) make sure the IP address is valid. */
		
		var IPArray=domain.match(ipDomainPat);
		if (IPArray!=null) {
		
		// this is an IP address
		
			for (var i=1;i<=4;i++) {
				if (IPArray[i]>255) {
					setError(field.id, error);
					return false;
		   	}
			}
			return true;
		}
		
		// Domain is symbolic name.  Check if it's valid.
		 
		var atomPat=new RegExp("^" + atom + "$");
		var domArr=domain.split(".");
		var len=domArr.length;
		for (i=0;i<len;i++) {
			if (domArr[i].search(atomPat)==-1) {
				setError(field.id, error);
				return false;
		 	}
		}
		
		/* domain name seems valid, but now make sure that it ends in a
		known top-level domain (like com, edu, gov) or a two-letter word,
		representing country (uk, nl), and that there's a hostname preceding 
		the domain or country. */
		
		if (checkTLD && domArr[domArr.length-1].length!=2 && 
		domArr[domArr.length-1].search(knownDomsPat)==-1) {
			setError(field.id, error);
			return false;
		}
		
		// Make sure there's a host name preceding the domain.
		
		if (len<2) {
			setError(field.id, error);
			return false;
		}
		
		// If we've gotten this far, everything's valid!
		return true;
	}
	
} // end class

