;(function($) {
	
	var sky = window.sky || (window.sky = {});
	
	sky.verification = {
		verifyRuleContent: function(data) {
			var ruleVal = data.ruleVal;
			var field = data.field;
			var success = true;
			
			switch (ruleVal) {
				case "standardText":
					if (field.val) {
						success = (field.val.match(/^[A-Za-z\-\']+$/)) ? true : false;
					}
					else {
						// Empty string so should pass this rule
						success = true;
					}
				break;
				
				case "standardEmail":
					success = (field.val.match(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i)) ? true : false;
				break;
				
				default:
				break;
			}
			
			return success;
		},
		verifyRuleCharLength: function(data) {
			var ruleVal = data.ruleVal;
			var field = data.field;
			var minLength = parseInt(ruleVal.split("-")[0]);
			var maxLength = parseInt(ruleVal.split("-")[1]);
			return (field.val.length >= minLength && field.val.length <= maxLength);
		},
		verifyRuleSameAs: function(data) {
			var ruleVal = data.ruleVal;
			var field = data.field;
			var allFieldsByName = data.allFieldsByName;
			return (allFieldsByName[ruleVal] && field.val == allFieldsByName[ruleVal].val);
		},
		verifyRuleMandatory: function(data) {
			var ruleVal = data.ruleVal;
			var field = data.field;
			if (!ruleVal) {
				return true;
			}
			else {
				return (field.val != "");
			}
		},
		setupVerifications: function() {
			// This is the place to setup your form verification

		},
		emailBasketVerification: "",
		setupEmailBasketLightBoxVerification: function(data) {
			var successFunc = data.successFunc;
			var failFunc = data.failFunc;
			var domRoot = data.domRoot;
			// Email basket lightbox form verification
			this.emailBasketVerification = new sky.verification.Verifier({
				domFormContainer: $(domRoot).find(".formToVerify").get()[0],
				domSubmitButton: $(domRoot).find("#emailBasketMessageSendButton").get()[0],
				showOneErrorPerField: true, // Only show one rule error per field
				rules: { 
					"firstName": { // Error messages shown in order of rules
						Mandatory: true,
						Content: "standardText",
						CharLength: "2-40"
					},
					"lastName": {
						Mandatory: true,
						Content: "standardText", 
						CharLength: "2-40"
					},
					"emailAddress": {
						Mandatory: true,
						Content: "standardEmail",
						SameAs: "confirmEmailAddress"
					},
					"confirmEmailAddress": {
						Mandatory: true,
						Content: "standardEmail"
					}
				},
				successFunc: function(data) {
					// this is called if the form passed front end verification
					// Should do backend ajax call here
					var fields = data.fields;
					if ($.isFunction(successFunc)) {
						successFunc(data);
					}
					// Serialise data
				},
				failFunc: function(data) {
					// This is called if the form failed verification
					var fields = data.fields;
					failFunc(data);
					
					var fields = data.fields;
					var errorsByFieldName = [];
					$.each(fields, function() {
						errorsByFieldName[this.name]=this;
					});
					
					// We need to check for a specific case
					// If either emailAddress or confirmEmailAddress failed verification for reasons other than emails not the same
					// we need to hide the 'email not the same'		
					if (errorsByFieldName["confirmEmailAddress"].error && errorsByFieldName["emailAddress"].error == "SameAs") {
						$(domRoot).find(".fieldError_emailAddress_SameAs").removeClass("formToVerifyShowErrorMessage");
						$(domRoot).find(".fieldToVerify_emailAddress").removeClass("fieldToVerifyError");
					}
					
					// If emailAddress has a SameAs error, then we need to highlight confirmEmailAddress field
					if (errorsByFieldName["emailAddress"].error == "SameAs") {
						$(domRoot).find(".fieldToVerify_confirmEmailAddress").addClass("fieldToVerifyError");
					}
					// We trigger window.resize to centralise the lightbox;
					$(window).trigger("resize");
				}
			}).init();
			
		}
	}
	
	// Verifier Class
	// Create a new instance for each form that you need verifying
	// See emailBasketForm.ftl for how the html should appear
	sky.verification.Verifier = function(data) {
		var self = this;
		self.domFormContainer = data.domFormContainer;
		self.domSubmitButton = data.domSubmitButton;
		self.formFields = [];
		self.formFieldsByName = [];
		self.rules = data.rules;
		self.successFunc = data.successFunc;
		self.failFunc = data.failFunc;
		self.showOneErrorPerField = data.showOneErrorPerField;
	}
	
	sky.verification.Verifier.prototype = {
		init: function() {
			var self = this;
			
			//self.clearAllErrors();

			$(self.domFormContainer).find(".fieldToVerify").each( function() {
				var thisInput = $(this).find("input").get()[0];
				var thisName = $(thisInput).attr("name");
				
				var thisField = {
					domRoot: this,
					domValEl: thisInput,
					name: thisName,
					val: "",
					error: true
				}
				self.formFields.push(thisField);
				self.formFieldsByName[thisField.name] = thisField;
			});
			
			$(this.domSubmitButton).unbind("click").click( function() {
				var success = self.verify();
				return false;
			});
			self.dealWithSubmitOnReturnKeyPress();
			return self;
		},
		dealWithSubmitOnReturnKeyPress: function() {
			var self = this;
			$(self.domFormContainer).find("input[type='text']").keydown( function(e) {
				if (e.keyCode == 13) {
					self.verify();
					return false;
				}
			});
		},
		clearAllErrors: function() {
			var self = this;
			$(self.domFormContainer).find(".fieldToVerifyError").removeClass("fieldToVerifyError");
			$(self.domFormContainer).removeClass("formToVerifyShowErrors");
		},
		verify: function() {
			var self = this;
			// Firstly, get the values for each field
			// And remove any previous errors classes
			
			self.clearAllErrors();
			
			$.each(self.formFields, function() {
				this.val = $(this.domValEl).val();
			});
			// Now we verify each field against its rules
			var success = true;
			$.each(self.formFields, function() {
				var thisField = this;
				var passedVerification = true;
				var errorHasBeenDisplayedForThisField = false;
				var errorType = "";
				for (aRule in self.rules[thisField.name]) {
					var verifyRuleFuncName = "verifyRule"+aRule;
					var verifyRuleVal = self.rules[thisField.name][aRule];
					
					var verifyRes = sky.verification[verifyRuleFuncName]({
						ruleVal: verifyRuleVal,
						field: thisField,
						allFieldsByName: self.formFieldsByName 
					});
					
					//console.log(thisField.name+" "+verifyRuleVal+" "+verifyRes);
					
					// The error message is in the html and has a class of fieldError_fieldName_ruleType
					// for example: fieldError_firstName_Mandatory
					var domFieldRuleErrorMessage = $(self.domFormContainer).find(".fieldError_"+thisField.name+"_"+aRule).get()[0]; 

					if (verifyRes) {
						// All is fine with thsi rule so hidethe appropriate error message
						$(domFieldRuleErrorMessage).removeClass("formToVerifyShowErrorMessage");						
					}
					else {
						success = false;
						// We now need to highlight this field as having errored
						$(thisField.domRoot).addClass("fieldToVerifyError");
						// And show the appropriate error message
						
						if (errorHasBeenDisplayedForThisField && self.showOneErrorPerField) {
							// Don't show the error for this rule, as we have already
							// displayed an error and the flag for only showing one error is set
							$(domFieldRuleErrorMessage).removeClass("formToVerifyShowErrorMessage");
						}
						else {
							$(domFieldRuleErrorMessage).addClass("formToVerifyShowErrorMessage");
							errorType = aRule;
						}
						passedVerification = false;
						errorHasBeenDisplayedForThisField = true;
					}
				}
				
				thisField.error = (passedVerification) ? false : errorType;

			});
			
			if (success) {
				$(self.domFormContainer).removeClass("formToVerifyShowErrors");
				if (self.successFunc) {
					self.successFunc({
						fields: self.formFields
					});
				}
			}
			else {
				$(self.domFormContainer).addClass("formToVerifyShowErrors");
				if (self.failFunc) {
					self.failFunc({
						fields: self.formFields
					});
				}				}
			return success;
		}
	}
	
})(jQuery);
