//+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+#
// 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.
//
//	Thanks to:	   Ben Clayton, Marc Woodhead :)													   
//
//+=+=+=+=+=+=+=+=+=+=+=+=+=[ (C) Chris Merry - Do not copy this script in anyway without permission. ]=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=#

var errorTxt = "Some of the fields below are required or the information given is not valid.<BR>Please move your mouse over the highlighted boxes below for more information.";

// ---------- 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-Za-z]{1,2})([0-9]{2,3})([A-Za-z]{2})$/;
// -------------------------------------------------------------------------------------------------------------------------------------
var dateRegxp			=	/^([0-9]){1,2}\/{1}([0-9]){1,2}\/([0-9]){2}$/;
// -------------------------------------------------------------------------------------------------------------------------------------
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 notblankRegxp		= /[a-zA-Z_0-9]+/;   // used by the isBlank function
// -------------------------------------------------------------------------------------------------------------------------------------



function verifylist(formobj,chklist){
	
	var good = new Array();
	var alt_tags = new Array();
	var fail=0;

	var debug=0;
	var debugTxt="";

	for (var i=0; i<formobj.length; i++){
		var e=formobj.elements[i];

		var opt_flag = -1;

		var name = e.name;
		var valObj;

		//~~ SITE SPECIFIC STUFF ----------------
		//if(name.indexOf('drop_') > -1){
		//	valObj = chklist['drop'];
		//}else if(name.indexOf('totalwidth_') > -1){
		//	valObj = chklist['totalwidth'];
		//}else{
		//========================================
			valObj = chklist[name];
		//}
		//========================================

		if (!good[name]) good[name] = 0;
		debugTxt += "FIELD NAME: " + name;

		if(valObj){	
			var valtype = valObj.valtype;
			//alert(valtype);
			//alert(e.type);
			debugTxt += " - IN CHECKLIST ("+valtype+")";
			if	(isdisplayed(e) && e.type != 'hidden'){					
				debugTxt += " - VISIBLE\n";
				
				if(valtype.indexOf('opt~') != -1){
					//alert("OPTIONAL VALUE" + typ.replace(/opt_/,''));
					valtype = valtype.replace(/opt~/,'');
					opt_flag = 1;
				}

				//###############################################################
				var bits = validate_field_value(e,name,valObj,valtype,opt_flag,good[name],chklist);											// VALIDATE A SINGLE FORM ELEMENT
				good[name] = bits[0];
				alt_tags[name] = bits[1];
				//###############################################################

			}else{
				debugTxt += " - INVISIBLE";
				good[name]=1; // hidden so say it is good													 
			}
		}else{
			debugTxt += " - NOT IN CHECKLIST";
			good[name]=1; // not in list so say it is good													 
		}
		if(good[name]) 	debugTxt += " - GOOD\n";
		else debugTxt += " - " + alt_tags[name] + " - ERROR\n";
	}

	// BC new group checker
	for (ck in chklist){
		if (ck.indexOf('[') == 0){ // is there a group item in the chklist?
			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(',');
				for (var x=0;x<field_array.length ;x++){
					var gf = document.getElementById(field_array[x]);
					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
							qty--;
						}
					}else{
						alert("field "+field_array[x]+" not found");
					}
				}
				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]]=vo.variableB+" of the "+s+" fields must be completed";
					}
				}
			}
		}
	}


	if(debug) alert(debugTxt);

	for (g in good){
		//alert("Name: "+g+"  Result: "+good[g]+"  Error txt: "+alt_tags[g]);
		if (good[g]==0){
			DispError(g,alt_tags[g]);
			fail = 1;
		}
		else if(good[g]==1){
			ClrError(g);
		}
	}

	fail = check_curtain_heading('curtain_heading',fail);

	display_error_dialogue(errorTxt,fail,1);

	return (fail)?false:true;
}

function validate_single_field(e,chklist){
	//alert("validate_single_field:\ne="+e+"\ne.name="+(e.name)+"\nchklist="+chklist);
	var valObj = chklist[e.name];
	//alert(e.name);
	var result = 0;
	var alt_tag = '';
	var opt_flag = 0;
	if(valObj){
		var valtype = valObj.valtype;
		if(isdisplayed(e)){					
			if(valtype.indexOf('opt~') != -1){
				valtype = valtype.replace(/opt~/,'');
				opt_flag = 1;
			}

			var bits = validate_field_value(e,e.name,valObj,valtype,opt_flag,result);											// VALIDATE A SINGLE FORM ELEMENT
			result = bits[0];
			alt_tag = bits[1];
		}else{
			result=1; // hidden so say it is good													 
		}
	}
	if(result == 0)	DispError(e.name,alt_tag);
	else if(result == 1) ClrError(e.name);
	return result;
}




//#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
//SUB FUNCTIONS
//#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

function valobj(valtype,extra_valtype,variableA,variableB){
	this.valtype = valtype;
	this.extra_valtype = extra_valtype;
	this.variableA = variableA;
	this.variableB = variableB;
}
																				  //USED FOR RADIO VALIDATION ONLY
function validate_field_value(element,element_name,valobj,valtype,optional,prevresult,chklist){

	var result = 0;
	var force = 0;
	var alt_tag = '';
	var value = '';
	
	if(extravaltype != "dual"){
		//====[ REPLACEMENTS ]=============================================
		if(valtype != "wordcount" && valtype != "text"){
			value = element.value.replace(/ /g,'');
			if(valtype == "currency"){
				value = value.replace(/\xA3/g,''); // \xA3 is the £ character , IE 6 complians if you use this not in hex reg ex
			}else if(valtype != "email" && valtype != "numeric" && valtype != "cm"){
				value = value.replace(/\./g,'');
				value = value.replace(/,/g,'');
			}
		}else{
			value = element.value;
		}

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

		//****[ SITE SPECIFIC VALIDATION ]***********************************
		else if (valtype=="cm" || (optional != -1 && value == '')){
			value = value.replace('cm','');
			//alert(value.indexOf(/m/));
			if(value.indexOf('m') != -1){
				value = value.replace('m','');
				//alert(value);
				value = parseInt(value * 100);
				//alert(value);
			}

			if (numericRegxp.test(value) == true){
				result=1;
			}else{
				alt_tag = "This should be a value in centimeters eg. 250cm";
			}
		}
		//*******************************************************************

		//====[ NO VALIDATION TYPE FOUND ]===================================
		else{
			alert('ERROR: Element ('+element_name+') has unknown validation type! ('+valtype+')');
			result=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. 
	//
	// It takes two parameters from the validation object. varA + varB these can be used for whatever purpose

	if(valobj.extra_valtype != '' && result || force){
		var extra_val_type_array = valobj.extra_valtype.split(',');
		var varA = valobj.variableA;
		var varB = valobj.variableB;

		//alert("Variable A: "+varA+"  Variable B: "+varB);
		for(var cnt=0;cnt<extra_val_type_array.length;cnt++){
			var extravaltype = extra_val_type_array[cnt];
			//alert("Cnt: "+cnt+" Valtype: "+extravaltype+" Var A: "+varA+" Var B: "+varB);
			//====[ MINIMUM AND MAXIMUM VALUES ]======================================================
		//	if(extravaltype == "minmax"){
		//		if(value < varA-1){
		//			alt_tag = "Please enter a value greater than "+varA+"m.";
		//			result=0;
		//		}else	if(value > varB+1){
		//			alt_tag = "Are you sure you want this much fabric. you have entered "+varB+"m.";
		//			result=0;
		//		}
		//	}
			//====[ DROP ]=====================================================================
			if(extravaltype == "drop"){
				if(varB == 'curtain'){
					varA = 50;
					varB = 400;
				}else if(varB == 'blind'){
					varA = 50;
					varB = 400;
				}else if(varB == 'fabric'){
					varA = 140;
					varB = 140;
				}
				if(value < varA-1){
					alt_tag = "Please enter a figure between "+varA+" and "+varB+"cm";
					result=0;
				}else if(value > varB+1){
					alt_tag = "Please enter a figure between "+varA+" and "+varB+"cm";
					result=0;
				}
			}
			//====[ DUAL ONE OR THE OTHER ]=====================================================================
			else if (extravaltype == "dual"){
				var obj1 = document.getElementById(varA);
				var obj2 = document.getElementById(varB);
				if(validate_single_field(obj1,chklist) || validate_single_field(obj2,chklist)){
					result=1;
				}
			}
			//====[ WINDOW NAME ]=====================================================================
			else if (extravaltype == "window_name"){
				if (value == 'eg. Dining room 1') {
					value = '';
					result = 0;
				}
			}
			//====[ TOTAL WIDTH ]=====================================================================
			else if(extravaltype == "totalwidth"){
				if(varB == 'curtain'){
					varA = 100;
					varB = 900; //BC2006-12-06 (was 500)
				}else if(varB == 'blind'){
					varA = 80;
					varB = 400;
				}else if(varB == 'fabric'){
					varA = 100;
					varB = 1000;
				}
				if(value < varA-1){
					alt_tag = "Please enter a figure between "+varA+" and "+varB+"cm";//"Please enter a value greater than "+varA+"m.";
					result=0;
				}else if(value > varB+1){
					alt_tag = "Please enter a figure between "+varA+" and "+varB+"cm";;
					result=0;
				}
			}
			//====[ MINIMUM ]=====================================================================
			else if(extravaltype == "minimum"){
				if(value >= varA){
					alt_tag = " "+varA+" ";
					result=0;
				}
			}
			//====[ MAXIMUM ]=====================================================================
			else if(extravaltype == "maximum"){
				if(value <= varA){
					alt_tag = " "+varA+" ";
					result=0;
				}
			}
			//====[ ROUND TO NEAREST ]=====================================================================
			else if(extravaltype == "round_up"){
				if(varB == 'fabric'){					//TEMP FOR CMOL ONLY
					var tmp = value;
					value = parseInt((value/varA)+0.99999) * varA;
					//alert("r4round="+value);
					if (tmp != value){
						alert("Information:\n\nYour dimension has been rounded up from "+tmp+(valobj.valtype)+" to "+value+(valobj.valtype));
					}
				}
			}
			//====[ ROUNDUP ]=====================================================================
			else if(extravaltype == "round"){
				var tmp = value;
				value = parseInt((value/varA)+0.5)*varA;
				if (tmp != value){
					alert("Information:\n\nYour dimension has been rounded  from "+tmp+(valobj.valtype)+" to "+value+(valobj.valtype));
				}
			}
			//====[ ROUNDDOWN ]==================================================================
			else if(extravaltype == "round_down"){
				var tmp = value;
				value = parseInt(value / varA) * varA;
				if (tmp != value){
					alert("Information:\n\nYour dimension has been rounded down from "+tmp+(valobj.valtype)+" to "+value+(valobj.valtype));
				}
			}
			//====[ POLE SIZE VALIDATION ]====================================================
//			else if(extravaltype == "pole_size"){
//
//				var selObj = document.getElementById('pole_size');
//				var totalwidth = document.getElementById('totalwidth').value;
//				var largestpole = selObj.options[selObj.length-1].innerHTML;
//				largestpole = largestpole.replace(/\./,'') + '0';
//
//				if(totalwidth > largestpole){
//					var user_result = window.confirm('We cannot supply a pole large enough to span the width entered, click OK if you would like us to remove the pole or click CANCEL to re-enter the width required.');
//					if(user_result){
//						setRadioIndex(varA,varB);
//					}
//				}else{
//					var ops = document.getElementById('pole_size').options;
//					var set_to = -1;
//					for (var x=0;x<ops.length;x++ ){
//						var pole_size = ops[x].innerHTML;
//						pole_size = (pole_size.length>1)?(pole_size * 10):(pole_size * 100);
//						set_to = (totalwidth > parseInt(pole_size) || x == 0)?-1:ops[x-1].value;
//						//alert("totalwidth: "+totalwidth+"  pole_size: "+pole_size+"  set: "+set_to+"  x:"+x);
//						if(set_to > 0){
//							//alert("Set select to "+set_to);
//							setSelectIndex(element_name,set_to,'basketform');
//							value = set_to;
//							result = 1;
//							//setSelectIndex('pole_size',set_to);
//						}
//					}
//				}
//			}
			//====[ CONFIRMATION EMAIL ADDRESS ]====================================================
			else if (extravaltype == "confirm_email"){
				var confObj = document.getElementById(varA);
				if(confObj){
					result = (value == confObj.value)?1:0;
					alt_tag = (!result)?"Please ensure both email address fields match before continuing":"";
				}
			}
		}
	}

	// SET ELEMENT VALUE TO VALIDATED DATA AFTER PROCESSING
	element.value = value;
	return [result,alt_tag];
}

function display_error_dialogue(error,fail,scroll){
	var errorDivObj = document.getElementById('form_error');
	if(errorDivObj){
		if(scroll) window.scrollTo(0,320);
		var display = (fail)?'block':'none';
		errorDivObj.style.display = display;
		errorDivObj.innerHTML = error;
	}
}

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

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

function ClrError(name){
	var obj = document.getElementById(name);
	if(obj){
		if(obj.className.indexOf('_err') != -1){
			obj.className = obj.className.replace(/_err/,'');
			obj.title = "";
			obj.alt = "";
		}
	}
}

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

function DispError(name,alt_tag){
	var obj = document.getElementById(name);
	//alert("objname="+name+" obj="+obj);
	if(obj){
		if(obj.className.indexOf('_err') == -1){
			obj.className = obj.className + "_err";
			//alert("objname="+name+" classname="+obj.className);
			//alert(alt_tag);
			if(alt_tag){
				obj.title = alt_tag;
				obj.alt = alt_tag;
			}
		}
	}
}

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

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(document.getElementById("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;
	}
}