function ValidateForm(form, formvars, bWait)
{

	//window.scrollTo(0,0);

	// Disable the submit button
	if(bWait)
	{
		var sb = findSubmitBtn(form);
		sb.disabled = true;
	}

	// Process the validation
	var formValid = true;
	for (x in formvars)
	{
		var result = validateField(form, formvars[x]);
		if(result == false)
		{
			formValid = false;
		}
	}

	if(bWait)
	{
		// If validation fails, re-enable the submit button to allow re-submit, otherwise change to 'Please Wait'
		if(!formValid)
			sb.disabled = false;
		else
			sb.value = "Please Wait...";
	}

	return formValid;
}

function findSubmitBtn(form)
{
	var sb = null;
	for(var i=0;i<form.getElementsByTagName('input').length;i++)
	{
		if(/submit/i.test(form.getElementsByTagName('input')[i].type))
		{
			sb=form.getElementsByTagName('input')[i];
			break;
		}
	}
	return sb;
}

function isArray(obj){return(typeof(obj.length)=="undefined")?false:true;}


function validateField(form, formvar)
{
	if(formvar.length < 4)
		return true;

	var field_name = formvar[0];
	var field_requred = (formvar[1] == 'required') ? true : false;
	var field_val_type = formvar[2];
	var field_val_param = formvar[3];

	var field_value = form[field_name].value;

	var errMsg = (formvar.length == 5) ? formvar[4] : '';
	var isValid = true;

	if ( form[field_name].disabled == false && (field_requred || field_value.length > 0))
	{
		switch (field_val_type)
		{
			case 'length':
			{
				var trimmed = field_value.replace(/^\s+|\s+$/g, '') ;
				isValid = validateLength(trimmed, field_val_param);
				if(errMsg == '')
					//errMsg = 'Please enter at least '+field_val_param+' character(s).';
					errMsg = '&nbsp; Should not be empty.';
				break;
			}
			case 'numlength':
			{
				isValid = validateNumLength(field_value, field_val_param);
				errMsg = 'Please enter a '+field_val_param+' digit number.';
				break;
			}
			case 'numlengthminmax':
			{
				var minmax = field_val_param.split(':');
				isValid = validateNumLengthMinMax(field_value, field_val_param);
				errMsg = 'Please enter a number between '+minmax[0]+' and '+minmax[1]+' digits long.';
				break;
			}
			case 'email':
			{
				isValid = validateEmail(field_value);
				if(errMsg == '')
					errMsg = 'Please enter a valid email address.';
				break;
			}
			case 'phone':
			{
				isValid = validatePhone(field_value);
				errMsg = 'Please enter a valid phone number.';
				break;
			}
			case 'postcode':
			{
				isValid = validatePostcode(field_value);
				errMsg = 'Please enter a valid postcode.';
				break;
			}
			case 'password':
			{
				var pass_value = form[field_val_param].value;
				isValid = validatePassword(field_value, pass_value);
				errMsg = 'Passwords do not match.';
				break;
			}
			case 'date':
			{
				isValid = validateDate(field_value);
				errMsg = 'Please enter a date in '+field_val_param+' format.';
				break;
			}
			case 'time':
			{
				isValid = validateTime(field_value);
				errMsg = 'Please enter a time in '+field_val_param+' format.';
				break;
			}
			case 'select':
			{
				isValid = validateSelect(field_value);
				errMsg = field_val_param;
				break;
			}
			case 'custom':
			{
				var retval = field_val_param(form);
				isValid = retval[0];
				errMsg = retval[1];

				break;
			}
		}
	}

	else if (field_val_type == 'password')
	{
		var pass_value = form[field_val_param].value;
		if(pass_value.length > 0)
		{
			isValid = validatePassword(field_value, pass_value);
			errMsg = 'Passwords do not match.';
		}
	}



	if (!isValid)
	{
		document.getElementById("err_"+field_name).innerHTML  = errMsg;
		document.getElementById("err_"+field_name).style.display = 'block';
   		form[field_name].className = 'input-warn';

	}
	else
	{
		document.getElementById("err_"+field_name).style.display = 'none';
		var clsname = 'textbox';
		if (form[field_name].type == 'textarea')
			clsname = 'textarea';

   		form[field_name].className = clsname;
	}

	return isValid;
}

function validateLength(field_value, min_length)
{
	return (field_value.length >= min_length) ? true : false;
}

function validateSelect(field_value, min_length)
{
	return (field_value=="") ? false : true;
}

function validateNumLength(field_value, length)
{
	return ((field_value.length == length) && !isNaN(field_value)) ? true : false;
}
function validateNumLengthMinMax(field_value, length)
{
	var minmax = length.split(':');
	return ((field_value.length >= minmax[0] && field_value.length <= minmax[1]) && !isNaN(field_value)) ? true : false;
}

function validateEmail(field_value)
{
	if (field_value.search(/^[A-z0-9][\w.-]*@[A-z0-9][\w\-\.]+\.[A-z0-9]{2,6}$/) != -1)
		return true;
	else
		return false;
}

function validatePhone(field_value)
{
	if (field_value.search(/^(0{1})([1-9]{3})\s?\d{3}\s?\d{4}$/) != -1)
		return true;
	else
		return false;
}

function validateDate(field_value)
{
	if (field_value.search(/^(?:(?:0?[1-9]|1\d|2[0-8])(\/|-)(?:0?[1-9]|1[0-2]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:31(\/|-)(?:0?[13578]|1[02]))|(?:(?:29|30)(\/|-)(?:0?[1,3-9]|1[0-2])))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(29(\/|-)0?2)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/) != -1)
		return true;
	else
		return false;
}

function validateTime(field_value)
{
	if (field_value.search(/^(20|21|22|23|[01]\d|\d)(([:][0-5]\d){1,2})$/) != -1)
		return true;
	else
		return false;
}

function validatePassword(field_value, pass_value)
{
	if(field_value == pass_value && pass_value.length > 0)
		return true;
	else
		return false;
}

function validatePostcode(toCheck)
{
  // Permitted letters depend upon their position in the postcode.
  var alpha1 = "[abcdefghijklmnoprstuwyz]";                       // Character 1
  var alpha2 = "[abcdefghklmnopqrstuvwxy]";                       // Character 2
  var alpha3 = "[abcdefghjkstuw]";                                // Character 3
  var alpha4 = "[abehmnprvwxy]";                                  // Character 4
  var alpha5 = "[abdefghjlnpqrstuwxyz]";                          // Character 5


  // Array holds the regular expressions for the valid postcodes
  var pcexp = new Array ();

  // Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
  pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1,2})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));

  // Expression for postcodes: ANA NAA
  pcexp.push (new RegExp ("^(" + alpha1 + "{1}[0-9]{1}" + alpha3 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));

  // Expression for postcodes: AANA  NAA
  pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1}" + alpha4 +"{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));

  // Exception for the special postcode GIR 0AA
  pcexp.push (/^(GIR)(\s*)(0AA)$/i);

  // Standard BFPO numbers
  pcexp.push (/^(bfpo)(\s*)([0-9]{1,4})$/i);

  // c/o BFPO numbers
  pcexp.push (/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);

  // Load up the string to check
  var postCode = toCheck;

  // Assume we're not going to find a valid postcode
  var valid = false;

  // Check the string against the types of post codes
  for ( var i=0; i<pcexp.length; i++) {
    if (pcexp[i].test(postCode)) {

      // The post code is valid - split the post code into component parts
      pcexp[i].exec(postCode);

      // Copy it back into the original string, converting it to uppercase and
      // inserting a space between the inward and outward codes
      postCode = RegExp.$1.toUpperCase() + " " + RegExp.$3.toUpperCase();

      // If it is a BFPO c/o type postcode, tidy up the "c/o" part
      postCode = postCode.replace (/C\/O\s*/,"c/o ");

      // Load new postcode back into the form element
      valid = true;

      // Remember that we have found that the code is valid and break from loop
      break;
    }
  }

  // Return with either the reformatted valid postcode or the original invalid
  // postcode
  if (valid) {return postCode;} else return false;
}

