/*
 *		Generic Validation Script
 *		--------------------------------------------------------------------------------
 *		
 *		Copyright ©		: OpenSearch
 *		Created By		: Brett Errington
 *		Last Updated	: 4/11/2005
 *		Version			: 1.2
 *
 *
 *		Description
 *		--------------------------------------------------------------------------------
 *
 *		For use as a general validation routine on all HTML forms. Based on the .Net
 *		method of invoking validation using one hidden validator field per user field
 *		requiring validation. This routine caters for validation that occurs on most
 *		forms, such as checking for required fields, if an email is valid etc.
 *
 *
 *		Usage
 *		--------------------------------------------------------------------------------
 *
 *		In form add a hidden (validator) field as so:
 *
 *			<input type="hidden" name="[field]_Validator"
 *			 value="[required],[type]|[chars],[error1]|[error2]|[error3],[min],[max]">
 *
 *		Where:
 *				[field]			= The name of the field to validate (exact name)
 *				[required]		= If the field is required (true or false)
 *				[type]			= Special validation type. Choices:
 *										Text 		(default)
 *										Number 		(value is valid number)
 *										Email 		(value is valid email address)
 *										Price		(value is valid price)
 *										Phone		(value is valid phone / mobile number)
 *										Domain		(value is valid domain / ip address)
 *										RegEx 		(please see regular expression section)
 *										File 		(value is valid filename, please see
 *													 for further details)
 *				[chars]			= List of invalid characters (e.g. "*()\/")
 *										You cannot use: ",|
 *				[error1]		= Message for required field error
 *				[error2]		= Message for minimum/maximum error
 *				[error3]		= Message for special type error
 *				[min]			= If special type is a number then this is the minimum
 *								  value, else this is the minimum length
 *				[min]			= If special type is a number then this is the maximum
 *								  value, else this is the maximum length
 *
 *		Finally add the following to the form tag:
 *
 *			onSubmit="return ValidateForm(this);"
 *
 *
 *		Notes
 *		--------------------------------------------------------------------------------
 *
 *		- Add one validator field per field requiring validation
 *		- Use underscores instead of spaces for field names
 *		- JavaScript is case sensitive
 *		- If you are using regular expressions, make sure they are valid for other
 *		  browsers such as Netscape.
 *
 *
 *		Regular Expressions
 *		--------------------------------------------------------------------------------
 *		
 *		If you intend on using a regular expression ( [type] = RegEx ) as the validator
 *		for a field then you will also need to add an extra hidden field as follows:
 *
 *			<input type="hidden" name="[field]_Validator_Ext"
 *			 value="[expression]">
 *
 *		Where:
 *				[field]			= The name of the field to validate (exact name)
 *				[expression]	= The regular expression to use for validation
 *
 *		--------------------------------------------------------------------------------
 *
*/


document.write("<scr" + "ipt language='javascript' src='/OSLibrary/JScript/inheritance.js'" +
			   " type='text/javascript'><\/scr" + "ipt>");
document.close();

var ErrorMessageDiv;
var ShowErrorDiv = false;
			   
var Imports = new Array();

Imports[0] = 'Browser.Detection';
Imports[1] = 'Objects.Array';


var PredefinedRegEx = new Object();

PredefinedRegEx['Email'] = /^([a-zA-Z0-9_\.\-\!\#\$\%\&\'\*\+\=\?\`\{\|\}\~])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
PredefinedRegEx['MultiEmail'] = /^((a-zA-Z0-9_\.\-\!\#\$\%\&\'\*\+\=\?\`\{\|\}\~]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})+([,.](([a-zA-Z0-9_\.\-\!\#\$\%\&\'\*\+\=\?\`\{\|\}\~]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}){1,25})+)*$/;
PredefinedRegEx['Price'] = /^[\$]?\d+(?:\.\d{1,2})?$/ig;
PredefinedRegEx['Date'] = /^\d{1,2}[\/\- ](?:\d{1,2}|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[\/\- ](?:\d{2}|\d{4})$/ig;
PredefinedRegEx['DayAndDate'] = /^(?:mon|tue|wed|thu|fri|sat|sun)[\s\,]+\d{1,2}[\/\- ](?:\d{1,2}|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[\/\- ](?:\d{2}|\d{4})$/ig;
PredefinedRegEx['Domain'] = /^(?:[\d\w-]+){1}(?:\.[\d\w-]+){2,}(?:\:\d+)?$/ig
PredefinedRegEx['URL'] = /^http\:\/\/(?:[\d\w-]+){1}(?:\.[\d\w-]+){2,}(?:\:\d+)?(?:\/.[^\/]*|\/){0,}$/ig
PredefinedRegEx['URLNoHTTP'] = /^(?:[\d\w-]+){1}(?:\.[\d\w-]+){2,}(?:\:\d+)?(?:\/.[^\/]*|\/){0,}$/ig
PredefinedRegEx['Phone'] = /^(?:\+?\d{0,3}[ \.\-]?)?(?:\(?\d{0,3}\)?[ \.\-]?)?\d{3,4}[ \.\-]?\d{3,4}$/ig


function ValidateField( theValue, isRequired, specialConditions, minValue, maxValue, theField )
{
	specialConditions = specialConditions.split('|');
	
	var required = isRequired.toLowerCase() == 'true';
	var theType = specialConditions[0];
	var theForm = theField.form;
	var invalidChars = specialConditions.length > 1 ? specialConditions[1] : '';
	
	if( required && theValue == '' ){
		return 'Blank';
	}
	else if( required && theField.type == 'checkbox' ){
		if( theForm[ theField.name ] != theField ){
			var group = theForm[ theField.name ];
			var checked = false;
			
			for( var i = 0; i < group.length; i++ ){
				checked = checked || group[i].checked;
			}
			
			if( ! checked ){
				return 'Blank';
			}
		}
		else if( ! theField.checked ){
			return 'Blank';
		}
	}
	else if( theValue != '' )
	{
		switch( theType.toLowerCase() )
		{
			case 'number' :
			{
				if( isNaN( theValue ) )
				{
					return 'Invalid';
				}
				else
				{
					if( minValue != '' )
					{
						if( 1 * theValue < 1 * minValue )
						{
							return 'MinMax';
						}
					}
					if( maxValue != '' )
					{
						if( 1 * theValue > 1 * maxValue )
						{
							return 'MinMax';
						}
					}
				}
				break;
			}
			case 'regex' :
			{
				var theForm		 = theField.form;
				var validatorExt = new RegExp( eval('theForm.' + theField.name + '_Validator_Ext').value );
				var matches 	 = validatorExt.exec( theValue );
				
				if( ! ( matches != null && theValue == matches[0] ) )
				{
					return 'Invalid';
				}
				
				break;
			}
			case 'file' :
			{
				var theForm		 = theField.form;
				var validatorExt = eval('theForm.' + theField.name + '_Validator_Ext');
				
				var fileNExtPos = theValue.lastIndexOf('.');
				var fileNLength = theValue.length;
				var fileNExt;
				
				if( fileNExtPos == -1 || fileNLength == 0 ){
					return 'Invalid';
				}
				else{
					fileNExt = theValue.substring(fileNExtPos + 1, fileNLength);
				}
				
				if( validatorExt != undefined )
				{
					var validExtensions = validatorExt.value.split('|');
					
					if( ! validExtensions.contains( fileNExt ) )
					{
						return 'InvalidExt';
					}
				}
				break;
			}
			default :
			{
				if( PredefinedRegEx[ theType ] ){
					if( theValue.search( PredefinedRegEx[ theType ] ) == -1 ){
						return 'Invalid';
					}
					break;
				}
				else{
					if( invalidChars != '' )
					{
						for( j = 0; j < invalidChars.length; j++ )
						{
							if( theValue.indexOf( invalidChars.charAt(j) ) > -1 )
							{
								return 'Invalid';
							}
						}
					}
					if( minValue != '' )
					{
						if( theValue.length < 1 * minValue )
						{
							return 'MinMax';
						}
					}
					if( maxValue != '' )
					{
						if( theValue.length > 1 * maxValue )
						{
							return 'MinMax';
						}
					}
					break;
				}
			}
		}
	}
	
	return '';
}

function ValidateForm( theForm )
{
	var baseTypes = new Array('text','textarea','password','file','select-one','select-multiple','checkbox');
	var baseType = '';
	var errorMessage = '';
	var theField;
	var validated = new Object(); // keeps a reference of already validated field names
	
	for( var i = 0; i < theForm.elements.length; i++ )
	{
		theField = theForm.elements[i];
		baseType = theField.type;
		errorMessage = '';
		
		if( validated[ theField.name ] ){
			continue; // bypass fields already validated, this can occur with checkboxes for example
		}
		
		if( baseTypes.contains( baseType ) )
		{
			validator = eval('theForm.' + theForm.elements[i].name + '_Validator');
			
			if( validator != undefined )
			{
				theValue   = theForm.elements[i].value;
				theParams  = validator.value.split(',');
				theErrMsgs = theParams[2].toString().split('|');
				
				theResult = ValidateField( theValue,
										   theParams[0],
										   theParams[1],
										   theParams[3],
										   theParams[4],
										   theForm.elements[i] );
				
				if( theResult == 'Blank' )
				{
					errorMessage = theErrMsgs[0];
				}
				else if( theResult == 'MinMax' )
				{
					errorMessage = theErrMsgs[1];
				}
				else if( theResult == 'Invalid' )
				{
					errorMessage = theErrMsgs.length > 2 ? theErrMsgs[2] : theErrMsgs[1];
				}
				else if( theResult == 'InvalidExt' )
				{
					errorMessage = theErrMsgs[2];
				}
				
				if( errorMessage != '' ){
					ShowError( theForm.elements[i], errorMessage );
					return false;
				}
			}
		}
		
		validated[ theField.name ] = true;
	}
	// alert(theField.Submit.value);
	return true;
}

function SetFieldRequired( field, required ){
	var values, validator;
	
	if (field && field.form && field.form[field.name + '_Validator']) {
		validator = field.form[field.name + '_Validator']
		values = validator.value.split(',');
		values[0] = required;
		
		validator.value = values.join(',');
	}
}

function ShowError( field, errorMessage ){
	if( field.focus ){
		field.focus();
		
		if( field.type == 'text' ){
			if( field.select ){
				field.select();
			}
		}
	}
	
	/*if( ShowErrorDiv && document.createElement ){
		if( ! ErrorMessageDiv ){
			ErrorMessageDiv = document.createElement( 'div' );
			ErrorMessageDiv.id = 'ErrorMessageDiv';
			
			ErrorMessageDiv.style.left = field.getBoundingClientRect().left;
			ErrorMessageDiv.style.top = field.getBoundingClientRect().top + field.offsetHeight + field.clientHeight + 5;
			alert( ErrorMessageDiv.style.top );
			document.body.appendChild( ErrorMessageDiv );
		}
		
		ErrorMessageDiv.style.visibility = 'visible';
		ErrorMessageDiv.innerHTML = '<span>Error:</span> ' + errorMessage;
		
		setTimeout( 'HideErrorMessage()', 2000 );
	}
	else{*/
		alert( errorMessage );
	//}
}

function HideErrorMessage(){
	if( ErrorMessageDiv ){
		ErrorMessageDiv.style.visibility = 'hidden';
	}
}
