/*
	validation.js
	
	Functions which handle the validation of form input.
	
	Based heavily on the concept by Stephen Poley (See credit below).
	
	Author: James Edgeworth
	
	Credit: http://www.xs4all.nl/~sbpoley/webmatters/formval.html

*/


var nbsp = 160;		// non-breaking space char
var node_text = 3;	// DOM text node-type
var emptyString = /^\s*$/ ;


/*
	BOOLEAN validate(OBJ field, OBJ infoHandle, STR args [, INT length, BOOL warn, STR message])
	Used to validate a form input if the user has javascript enabled.
	Should be called specifically from the element in question - e.g, with the 'onChange' parameter.
	Updates a specified html element with the same id as the infoHandle arg, as input is given.
	
	Returns TRUE if validation was successful
	
	field - the field storing the value to check (should just set to "this" when calling)
	infoHandle - the html element in which to place the status messages
	args - a string of args to supply to narrow down the validation: text, num, stripspecial, email, compare, postcode, time, money
	length - the length of the input required
	
	EXAMPLE
	
	input type="text" onChange="validate(this, 'ih_phone' 'num', 6)"
	...which would only be successful if the input value is numerical ONLY, and 6 or more characters long

*/
function validate(field, infoHandle, args, length, warn, message)
{
	var inputValue = trim(field.value);
	var length = (length == null) ? 0 : length;
	var success = false;
	var lengthSuccess = false;		//Length is always checked, and if we only used one success bool, then anything over the set length would return true
	var msgType = 'ok';
	var msgText = '';
	
	// If warn hasn't been set, then it's value won't be either true or false. Set to false
	// if is it not already set.
	if (warn != true)
	{
		warn = false;
	}
	
	
	// Check length
	if (inputValue.length < length)
	{
		msgType = 'short';
		msgText = 'must be ' + length + ' characters or more';
		//setInfo(infoHandle, 'short', 'must be ' + length + ' characters or more');
	}
	else
	{
		//setInfo(infoHandle, 'ok');
		lengthSuccess = true;
	}
	
	
	// Check email
	if (args.indexOf("email") >= 0)
	{
		var regEx  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
		
		if ( regEx.test(inputValue) )
		{
			//setInfo(infoHandle, 'ok');
			success = true;
		}
		else
		{
			msgType = 'invalid';
			msgText = 'Not the correct email address syntax';
			//setInfo(infoHandle, 'Invalid', 'Not the correct email address syntax');
		}
		
	}
	
	// Check postcode
	else if (args.indexOf("postcode") >= 0)
	{
		var regEx = /[a-zA-Z]{1,2}[a-zA-Z0-9]{1,2} ?[0-9][a-zA-Z]{2}/i;
		
		if (regEx.test(inputValue) )
		{
			success = true;
		}
		else
		{
			msgType = 'invalid';
			msgText = 'Incorrect postcode syntax';
		}
	}
	
	
	else if (args.indexOf("time") >= 0)
	{
	
		inputValue = inputValue.replace(".", ":");
		field.value = inputValue;
	
		var regEx = /[0-9]{1,2}[:]{1}[0-9]{2}/i;
		
		if ( regEx.test(inputValue) )
		{
			if(inputValue.length == 4)
			{
				inputValue = '0' + inputValue;
				field.value = inputValue;
			}
			
			success = true;
		}
		else
		{
			msgType = 'invalid';
			msgText = 'Incorrect time syntax (00:00)';
		}
	}
	
	else if ( args.indexOf("money") >= 0 )
	{
	
		inputValue = inputValue.replace(":", ".");
		field.value = inputValue;
		
		var regEx = /[0-9]{1,2}[.]{1}[0-9]{2}/i;
		
		if ( regEx.test(inputValue) )
		{
			success = true;
		}
		else
		{
			msgType = 'invalid';
			msgText = 'Incorrect money syntax (00.00)';
		}
	}
	
	
	// Check if numerical
	else if (args.indexOf("num") >= 0)
	{
		if ( isNaN(inputValue) )
		{
			msgType = 'invalid';
			msgText = 'must only be numerical';
		}
		else
		{
			success = true;
		}
	}
	
	
	// Check for specialchars
	else if (args.indexOf("stripspecial") >= 0)
	{
		// Input is a username, directory name, or whatever - we shouldnt have 'special' characters.
		
		var invalidChars = new Array("!", "?", "'", "\"", "\\", "+", "-");
		
		for (i = 0, max = invalidChars.length; i < max; i++)
		{
			if (inputValue.indexOf(invalidChars[i]) >= 0)
			{
				msgType = 'invalid';
				msgText = 'You cannot use the following - ! ? \' \" \\ +';
			}
			else
			{
				success = true;
			}
		}
	}
	else
	{
		//Default - validation is for text, so were just concerned about length
		success = true;
	}
	
	
	// if set to warning, then allow success regardless of error.
	if ( msgType != 'ok' && warn == true )
	{
		msgType = 'warn';
		success = true;
		
		if ( message.length > 0 )
		{
			msgText = message;
		}
	}
	
	setInfo(infoHandle, msgType, msgText);
	
	return ((lengthSuccess == true) && (success == true));
	
};


function compare(elem1, elem2, infoHandle)
{
	var handle 		= document.getElementById(infoHandle);
	
	if (elem1 != elem2)
	{
		setInfo(infoHandle, 'invalid', 'Emails do not match');
		return false;
	}
	
	setInfo(infoHandle, 'Ok');
	
	return true;
};


/*
	VOID setInfo(OBJ infoHandle, STR msgType [, STR msgText])
	
	Used to change the text of the contents of OBJ infoHandle to a message defined
	in both STR msgType and STR msgText.

	Does not return a value.

*/
function setInfo(infoHandle, msgType, msgText)
{
	var handle = document.getElementById(infoHandle);
	var msgText = (msgText == null) ? '' : msgText;
	var fullMesg = '';
	var msgColor = '';
	
	if (msgType == 'short')
	{
		msgType = 'Too short';
		msgColor = 'red';
	}	
	else if (msgType == 'invalid')
	{
		msgType = 'Invalid';
		msgColor = 'red';
	}
	else if (msgType == 'ok')
	{	
		msgType = 'Ok';
		msgColor = 'green';
	}
	else if (msgType == 'warn')
	{	
		msgType = 'Warning';
		msgColor = 'orange';
	}
	
	//msgType = (msgType.length > 1) ? msgType + " -- " : '' ;
	msgText = (msgText.length > 0) ? ' -- ' + msgText : '';
		
	handle.firstChild.nodeValue = msgType + msgText;
	handle.style.color = msgColor;
	
};


function trim(string)
{
	return string.replace(/^\s+|\s+$/g, '');
};






