//+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+#
// JAVASCRIPT VALIDATION -- validate.js	v2																										     UPDATED: 07/11/06 CHRIS  #
//+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+#
//
//  Script Author: Chris Merry
//     
//	Description:   This script will validate any form data and enforce certain rules on the data entered via a validation obj alowing for multi level validation
//				   for formatting / extra validation objects via regular expressions.
//
//  Prerequisites: Needs submit form function from pagesupport.js
//
//	Thanks to:	   Ben Clayton, Marc Woodhead :)													   
//
//+=+=+=+=+=+=+=+=+=+=+=+=+=[ (C) Chris Merry - Do not copy this script in anyway without permission. ]=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=#

var error_text = "<b>Some of the fields below are required or the information given is not valid,</b> for further information move your mouse over the highlighted boxes below.";

// ---------- VALIDATION REGULAR EXPRESSIONS ---------------------------------------------------------------------------------------
var urlRegxp			=	/^((http|https):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i
// -------------------------------------------------------------------------------------------------------------------------------------
var emailRegxp			=	/^([\w_-]+)(\.[\w_-]+)*@([\w_-]+)(\.[\w_-]*){0,1}(\.[a-zA-Z]{2,4}){1,2}$/; 
// -------------------------------------------------------------------------------------------------------------------------------------
var pcodeRegxp 			= /^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {0,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var dateRegxp			=	/^([0-9]){2}\/{1}([0-9]){2}\/([0-9]){4}$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var passwordRegxp	=	/^[a-zA-Z0-9]{3,14}$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var timeRegxp			=	/^[0-9]{2}:{1}[0-9]{2}$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var usernameReqxp	=	/[a-zA-Z0-9]{6,20}/;
// -------------------------------------------------------------------------------------------------------------------------------------
var currencyRegxp	=	/^\d+(\.\d{1,2})?$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var telnoRegxp			=	/^(^[0-9\+ ]+)$/
// -------------------------------------------------------------------------------------------------------------------------------------
var numericRegxp		=	/^([0-9]+)$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var metersRegxp 		=	/^([0-9]+)$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var notblankRegxp		= /[a-zA-Z_0-9]+/;   // used by the isBlank function
// -------------------------------------------------------------------------------------------------------------------------------------
var ignoretagsRegxp		= /fieldset/i;  

// EXAMPLES
//{	'Name':'text',
//	'Title':'select-one',
//	'Surname':{'type':'text','change_case':'upper','optional':1},
//	'Email':{'type':'email','change_case':'lower','conf_email':'confirm_email'},
//	'Contact':{'type':'radio'}
//};	

function verifylist(formobj,chklist,error_div){
	
	var fail = 0;
	var debug = 0;
	var debug_text = "";

	//for(var p in chklist){
	//	alert(p + " = " + chklist[p]);
	//}
		
	var resultobj = new Array();
	
	for (var i=0; i<formobj.length; i++){
		var e = formobj.elements[i];
		if(ignoretagsRegxp.test(e.tagName) == true || e.tagName == '') continue;
		//alert("TAG NAME: '" +e.tagName + "' TEST: " + ignoretagsRegxp.test(e.tagName));
		var valobj = {};	
		var robj = {};
		var val = chklist[e.name];
		if (typeof val == 'string'){ valobj.type = val; }else{ valobj = val; }
		
		//var obj = chklist.Surname;
		//alert(obj.type + " " + obj.case);
		//return;
		
		//var str = "\nName: "+e.name;
		//for(var p in valobj){
		//	str += " - " + p + " = " + valobj[p] + " / ";
		//}
		//alert(str);

		debug_text += "FIELD NAME: " + e.name;

		if(valobj){	
			robj.element = e;
			robj.alt_tag = '';
			robj.good = 0;
			robj.type = valobj.type;
			
			//alert(valobj.type);
			//alert(e.type);
			debug_text += " - IN CHECKLIST ("+valobj.type+")";
			if	(isdisplayed(e) && e.type != 'hidden'){					
				debug_text += " - VISIBLE\n";
					
				//###############################################################
				// VALIDATE A SINGLE FORM ELEMENT
				//###############################################################
				validate_field_value(robj,valobj);											
				//###############################################################

			}else{
				debug_text += " - INVISIBLE";
				robj.good = 1; // hidden so say it is good													 
			}
			
			//ADD ONTO RESULTS OBJECT
			resultobj.push(robj);

			if(robj.good) 	debug_text += " - GOOD\n";
			else debug_text += " - " + robj.alt_tag + " - ERROR\n";
			
		}else{
			debug_text += " - NOT IN CHECKLIST\n";										 
		}
	}

	// BC new group checker
//		for (ck in chklist){
//			if (ck.indexOf('[') == 0){ // is there a group item in the chklist?
			//alert("Found Group Checker");
//				var vo=chklist[ck];
//				if (vo.extra_valtype == "notblank"){ // is the group test nonblank
//					var qty=vo.variableB; // how many nonblank do we need to be good
//					var field_array = vo.variableA.split(',');
				//alert("Qty required: "+qty+"  Fields:"+field_array[0]+','+field_array[1]);
//					for (var x=0;x<field_array.length ;x++){
//						var gf = document.getElementsByName(field_array[x]);
//						gf = gf[0];
//						if (gf){
						//alert("field "+field_array[x]+ " value=("+gf.value+") isblank="+isBlank(gf.value));
//							if (!isBlank(gf.value)||!isdisplayed(gf)){ // note: if not displayed assume they are not blank
							//alert("NOT BLANK");
//								qty--;
//							}
//						}else{
						//alert("field "+field_array[x]+" not found");
//						}
//					}
				//alert("Qty: " + qty);
//					if (qty>0){	// if qty > 0 then there are not enough filled out so report error and alttxt for elements
//						for (var x=0;x<field_array.length ;x++){
//							good[field_array[x]]=0;
//							var s = ck;
//							s=s.replace(/\[|\]/g,'');
//							var qtys = 	(vo.variableB==1)?"one":vo.variableB; // one is so common write it in words
//							alt_tags[field_array[x]]="At least "+qtys+" of these fields '"+s+"' must be completed to proceed.";
//						}
//					}
//				}
//				//return false;
//			}
//		}

	if(debug) alert(debug_text);

	for (var x=0;x<resultobj.length;x++){
		var robj = resultobj[x];
		//alert("Name: "+robj.element.name+"  Result: "+robj.good+"  Error txt: "+robj.alt_tag);
		if (robj.good == 0){
			hilite_error(robj);
			fail = 1;
		}else if(robj.good == 1){
			clear_error(robj);
		}
	}

	display_error_dialogue(error_text,error_div,fail,1);

	return (fail)?false:true;
}

function validate_single_field(e,chklist){
	var valobj = {};	
	var val = chklist[e.name];
	if (typeof val == 'string'){ valobj.type = val; }else{ valobj = val; }
				
	var robj={};
	robj.element = e;
	robj.alt_tag = '';
	robj.good = 0;
	robj.type = valobj.type;
	
	if(valobj){
		if(isdisplayed(e)){		
			//###############################################################
			// VALIDATE A SINGLE FORM ELEMENT
			//###############################################################
			validate_field_value(robj,valobj);
			//###############################################################
		}else{
			robj.good=1; // hidden so say it is good													 
		}
	}
	if(robj.good == 0)	hilite_error(robj);
	else if(robj.good == 1) clear_error(robj);
	return robj.good;
}

//#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
//SUB FUNCTIONS
//#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
																		  //USED FOR RADIO VALIDATION ONLY
function validate_field_value(robj,valobj){
	var value = '';

	//====[ REPLACEMENTS ]=============================================
	if(valobj.type != "wordcount" && valobj.type != "text"){
		value = robj.element.value.replace(/ /g,'');
		if(valobj.type == "currency"){
			value = value.replace(/[^0-9]*/g,'');
		}else if(valobj.type != "email" && valobj.type != "numeric" && valobj.type != "meters"){
			value = value.replace(/\./g,'');
			value = value.replace(/\,/g,'');
		}
	}else{
		value = robj.element.value;
	}

	//====[ TEXT VALIDATION ]=============================================
	if (valobj.type=="text"){
		if ((valobj.optional == 1) && (value == '') || (value != "") && (!isBlank(value))) {
			robj.good = 1;
		}else{
			robj.alt_tag = "This is a required field";
		}
	}
	//====[ CHECKBOX ]==================================================
	else if (valobj.type=="checkbox"){
		robj.good = 1;
	}
	//====[ SELECT-ONE ]================================================
	else if (valobj.type=="select-one"){
		if (robj.element.value != "-1" || (valobj.optional == 1 && value == '')){
			robj.good = 1;
		}else{
			robj.alt_tag = "Please select a value from the pulldown menu";
			robj.good = 0;
		}
	}
	//====[ RADIO ]======================================================
	else if (valobj.type=="radio"){
		if (robj.element.checked || (valobj.optional == 1 && value == '')){
			robj.good = 1;
		}else{
			robj.alt_tag="Please select at least one of these options"
		}
	}
	//====[ DATE ]=======================================================
	else if (valobj.type=="date"){
		if (dateRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1; 
		}else{ 
			robj.alt_tag = "Date format must be eg. dd/mm/yyyy";
		}
	}
	//====[ TIME ]======================================================
	else if (valobj.type=="time"){
		if (timeRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1; 
		}else{ 
			robj.alt_tag = "Time format must be in 24hr format eg. 16:00";
		}
	}
	//====[ NUMERIC ]===================================================
	else if (valobj.type=="numeric"){
		if (numericRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1;
		}else{
			robj.alt_tag = "Should only contain digits eg. 1234";
		}
	}
	//====[ INTEGER ]===================================================
	else if (valobj.type=="meters"){
		if (metersRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1; 
		}else{
			robj.alt_tag = "Fabrics can only be purchased in whole meters.";
		}
	}
	//====[ CURRENCY ]==================================================
	else if (valobj.type=="currency"){
		if (currencyRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1; 
		}else{ 
			robj.alt_tag = "Must contain a positive currency value eg. 10.99"; 
		}
	}
	//====[ POSTCODE ]=================================================
	else if (valobj.type=="postcode"){
		if (pcodeRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1; 
		}else{ 
			robj.alt_tag = "Ensure postcode is valid eg. BN27 2GH"; 
		}
	}
	//====[ TELEPHONE ]=================================================
	else if (valobj.type=="telephone"){
		value = value.replace(/ /g, '');
		if (telnoRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1; 
		}else{ 
			robj.alt_tag = "Ensure this is a valid UK phone number eg. 01424 753456"; 
		}
	}
	//====[ WEBSITE ADDRESS ]===========================================
	else if (valobj.type=="http"){
		if (urlRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1;
		}else{
			robj.alt_tag = "Please ensure you have entered a valid web address.";
		}
	}
	//====[ EMAIL ]=====================================================
	else if (valobj.type=="email"){
		//alert("RESULT: "+emailRegxp.test(value));
		if (emailRegxp.test(value) == true || (valobj.optional == 1 && value == '')){
			robj.good = 1;
		}else{ 
			robj.alt_tag = "Ensure this is a valid email address eg. somebody@domain.co.uk"; 
		}
	}

	//****[ SITE SPECIFIC VALIDATION ]***********************************
	else if (valobj.type=="cm" || (valobj.optional == 1 && value == '')){
		value = value.replace(/cm/,'');
		if (numericRegxp.test(value) == true){
			robj.good = 1;
		}else{
			robj.alt_tag = "This should be a value in cm eg. 100cm";
		}
	}
	//*******************************************************************

	//====[ NO VALIDATION TYPE FOUND ]===================================
	else{
		alert('Element ('+element.name+') has unknown validation type! ('+valobj.type+')');
		robj.good = 1;
	}

	//###########################################################################
	// EXTRA VALIDATION TYPE PROCESSING ---------------------------------------------------------------------
	//###########################################################################
	// can be used to run secondary validation on form objects or to format existing value eg. round down to the 
	// nearest multiple of a given number. 
	//###########################################################################
	
	//====[ CHANGE CASE ]=================================================================
	if(valobj.change_case){
		if(valobj.change_case == 'upper'){
			value.toUpperCase();
		}else if(valobj.change_case == 'lower'){
			value.toLowerCase();
		}else if(valobj.change_case == 'capitalise'){
			value = 'Coming soon to a validate script near you';
		}
	}

	//====[ MINIMUM ]=====================================================================
	if(valobj.minimum != null){
		if(value >= valobj.minimum){
			robj.alt_tag = "Entered value is below the minimum of " + valobj.minimum;
			robj.good = 0;
		}
	}
	//====[ MAXIMUM ]=====================================================================
	if(valobj.maximum != null){
		if(value <= valobj.maximum){
			robj.alt_tag = "Entered value is above the maximum of " + valobj.maximum;
			robj.good = 0;
		}
	}

	//====[ ROUND UP ]====================================================================
	if(valobj.round_up){
		value = parseInt((value * valobj.round_up) / valobj.round_up);
	}

	//====[ ROUND DOWN ]==================================================================
	if(valobj.round_down){
		value = (value / valobj.round_down) * valobj.round_down;
	}

	//====[ CONFIRMATION EMAIL ADDRESS ]====================================================
	if (valobj.conf_email){
		var errstr = "Please ensure both email address fields match before continuing";
		var confObj = $(valobj.conf_email);
		//alert(confObj);
		if(confObj){
			var test = (value == confObj.value)?1:0;
			if(test){
				clear_error({'element':confObj,'alt_tag':''});
			}else{
				robj.alt_tag = (robj.good)?errstr:robj.alt_tag;
				hilite_error({'element':confObj,'alt_tag':errstr});
				robj.good=0;
			}
		}else{
			alert("No email confirmation email field with id: "+valobj.conf_email);
		}	
	}

	// SET ELEMENT VALUE TO VALIDATED DATA AFTER PROCESSING
	robj.element.value = value;
}

//===========================================================

function clear_error(robj){
	if(robj.element.style) robj.element.style.backgroundColor = "";
	robj.element.backgroundColor = "";
	robj.element.title = (robj.alt_tag)?robj.alt_tag:"";
	robj.element.alt = (robj.alt_tag)?robj.alt_tag:"";
}

//===========================================================

function hilite_error(robj){
	if(robj.element.style) robj.element.style.backgroundColor = "#ffcca4";
	robj.element.backgroundColor = "#ffcca4";
	robj.element.title = (robj.alt_tag)?robj.alt_tag:"";
	robj.element.alt = (robj.alt_tag)?robj.alt_tag:"";
}

//===========================================================

function display_error_dialogue(error_txt,error_div,fail,scroll){
	var error_div_obj = $(error_div);
	//alert(errorDivObj);
	if(error_div_obj){
		if(scroll) window.scrollTo(0,320);
		var display = (fail)?'block':'none';
		error_div_obj.style.display = display;
		error_div_obj.innerHTML = error_txt;
	}
}

//===========================================================

function isBlank(s){  //BC 2006-12-05
	if (s == ''){return true}
	return !notblankRegxp.test(s);
}

//===========================================================

function isdisplayed(node){
	//This function is used to see if an INPUT is currently being displayed
	// ONLY looking for a encompassing DIV with a style including display:block or display:none
	// test with something like this:
	//       alert(isdisplayed($("surname")))
	var n=0;
	var fnd=0;
	while (fnd==0){
		if(n>1) { node = node.parentNode; }
		if (node){
			if (node.style){
				if (node.style.display){
					//alert(node.style.display);
					if (node.style.display=='block'){
						fnd=0;
						//return true;
					}
					if (node.style.display=='none'){
						fnd=1;
						//return false;
					}
				}
			}
		}else{
			fnd=3;
		}
		if (n>20){
			return true;
		}
		n++;
	}
	if(fnd==1){
		return false;
	}
	if(fnd==0||fnd==3){
		return true;
	}
}