/*

JQUERY FORM VALIDATION SCRIPT 
Author: Abendago Media Group
Version 1.1

UPDATES:
-------------------------------------------------------------------------------------------------------------

1.1	(29/05/2009)
+ Bug fixes with variable placement
+ Can reference errordiv by class or id now
+ Added support for multiple "waiting" when using ajax calls
1.1.1	(2/07/2009)
+ Bug fix with fieldsetGroup function

NOTES:
-------------------------------------------------------------------------------------------------------------

+ The 1st (theform) parameter is a string used to reference the form name.
+ The 3rd (callback) parameter is a string used to define the javascript function.
+ The 2nd (errordiv) parameter is a string used to define the ID of the error container element.
+ Callback is only run if the callback parameter is set and there are no errors.
+ When a form does not pass validation, all invalid elements are appended the the "error" class.
+ If an element name has "email" in it then a valid email check will run
+ If an element name has "password" in it then a char length check will run (must be larger than 6)
+ If an element name has "email" & "confirm" in it then a comparison with a saved email is run
+ If an element name has "password" & "confirm" in it then a comparison with a saved password is run
+ If an element name has "captcha" in it then we ajax captcha.php

Below is an example of what you may need:
-------------------------------------------------------------------------------------------------------------

<script type="text/javascript" src="themes/default/js/jquery.js"></script>
<script type="text/javascript" src="themes/default/js/form-validation.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	$("form[name='test'] input.submit").click(function(){
		validateForm("test","#error","verify");
	});
});
function verify (theform) {
	// Maybe do some extra validation here
	document.forms[theform].submit();
}
</script>
<div id="error"></div>
<form name="test" method="post" action="submit.php" >
	<fieldset required="please check off one of the boxes">
		<label>Option 1</label><input type="checkbox" name="1" value="1" />
		<label>Option 2</label><input type="checkbox" name="2" value="2" />
		<label>Option 3</label><input type="checkbox" name="3" value="3" />
	</fieldset>
	<input type="text" name="field" value="" required="please give me some info" />
	<input class="submit" type="button" value="Submit" />
</form>

*/

// GLOBAL VARS

var theform = ""; // Global function parameter
var errordiv = ""; // Global function parameter
var callback = ""; // Global function parameter
var bWait = 0; // Used to avoid finalizing until ajax is complete
var strErrorMessage = ""; // Error message to be printed if any
var strSaveEmail = ""; // Used to save email for confirmation compare
var strSavePassword = ""; // Used to save password for confirmation compare
var strRegEmail = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; // Regular Expression used to test emails
var strGroupTypes = "span,input,textarea,select,label"; // Allowable tags for the fieldset groups
var strFormTypes = "input,select,textarea,fieldset"; // Allowable tags when looping form elements

$.fn.tag = function() { return this.get(0).tagName.toLowerCase(); }

function strstr (haystack,needle,bool) {
	var pos = 0;
	haystack += '';
	pos = haystack.indexOf(needle);
	if (pos == -1) {
		return false;
	} else {
		if (bool) {
			return haystack.substr(0,pos);
		} else{
			return haystack.slice(pos);
		}
	}
}

function fieldsetGroup (obj) {
	var req = $(obj).attr("required");
	if ( req && $(obj).tag() == "fieldset" ) {
		$("form[name='"+theform+"']").find(strGroupTypes).removeClass("error");
		var inc = 0;
		$(obj).find("input[type='radio'],input[type='checkbox']").each(function(){ if ($(this).attr("checked")) { inc ++; } });
		$(obj).find("input[type='text'],input[type='password'],textarea").each(function(){ if (val!="") { inc ++; } });
		$(obj).find("select").each(function(){ if($(obj).find("option:first").attr("selected")==false) { inc ++; } });
		if (inc == 0) {
			strErrorMessage += "<li>" + req + "</li>";
			$(obj).find(strGroupTypes).addClass("error");
		}
	}
}

function emptyFields (obj) {
	var req = $(obj).attr("required");
	var type = $(obj).attr("type");
	var value = $(obj).attr("value");
	var check = $(obj).attr("checked");
	var index = $(obj).get(0).selectedIndex;
	if(req) {
		if (((type=="text"||type=="password"||type=="hidden"||type=="textarea")&&value=="")||((type="select-one")&&index==0)||((type=="radio"||type=="checkbox")&&check==false)) {
			if (strErrorMessage.search(req) == -1) { strErrorMessage += "<li>" + req + "</li>"; }
			$(obj).addClass("error");
		}
	}
}

function regExpressions (obj) {
	var name = $(obj).attr("name");
	var value = $(obj).attr("value");
	if (name&&value) {
		name = name.toLowerCase();
		if (strstr(name,"email") && !strstr(name,"confirm")) {
			strSaveEmail = value;
			if (!strRegEmail.test(value)) {	
				strErrorMessage += '<li>The email address "'+value+'" contains illegal characters</li>';
				$(obj).addClass("error");
			}
		}
		if (strstr(name,"email") && strstr(name,"confirm") && value != strSaveEmail) {
			strErrorMessage += '<li>The confirmation email "'+value+'" does not match "'+strSaveEmail+'"</li>';
			$(obj).addClass("error");
		}
		if (strstr(name,"password") && !strstr(name,"confirm")) {
			strSavePassword = value;
			if (value.length < 6) {
				strErrorMessage += '<li>This password must be over 6 characters in length</li>';
				$(obj).addClass("error");
			}
		}
		if (strstr(name,"password") && strstr(name,"confirm") && value != strSavePassword) {
			strErrorMessage += '<li>This confirmation password does not match</li>';
			$(obj).addClass("error");
		}
	}
}

function captcha (obj) {
	var name = $(obj).attr("name");
	var value = $(obj).attr("value");
	if (strstr(name,"captcha")) {
		if (name&&value) {
			bWait ++;
			$.get("captcha.php",{"ajax":"yes","captcha":value,"form":theform},function(data){
				if (data.substring(0,6)=="window") {
					// It wants to submit but we will just ignore it for now
				} else {
					strErrorMessage += '<li>The provided captcha was incorrect</li>';
					$(obj).addClass("error").empty();
					$("#captcha").html(data);
				}
				bWait --;
			});
		} else {
			strErrorMessage += '<li>Please fill in the captcha</li>';
			$(obj).addClass("error");
		}
	}
}

function finalize () {
	if (timeout) clearTimeout(timeout); // Clear old timeout so we can make a new one / move on
	if (bWait > 0) { // If bWait is more than zero that means we are waiting for some ajax to finish
		var timeout = setTimeout("finalize();",99); // Try again in a 10th of a second
	} else { // We are no longer waiting so check for errors
		if (strErrorMessage) { // We have some errors
			$(errordiv).html("<h3>You Have Missed Some Required Fields/Steps</h3><ul>" + strErrorMessage + "</ul>").fadeIn(500); // Show the errors on screen
			window.scrollTo(0,0); // Scroll to the top so we can see the errors
		} else { // No errors, good job :)
			if (callback) { // Callback runs a parameter defined function instead of the default form submit
				window[callback](theform); // Dynamic function call
			} else { // No callback
				document.forms[theform].submit(); // Default form submit
			}
		}
	}
}

function validateForm(a,b,c) {
	
	/* ### PARAMS ARE GLOBAL ### */

	theform = a;
	errordiv = b;
	callback = c;

	/* ### Reset each time ### */

	strErrorMessage = "";
	strSaveEmail = "";
	strSavePassword = "";
	bWait = 0;

	$("form[name='"+theform+"']").find(strFormTypes).each(function() {
		
		$(this).removeClass("error"); // Remove all error classes so we can start fresh
		
		/* ### KEEPIN' IT SIMPLE ### */

		fieldsetGroup(this); // Check for fieldsets marked "required" and make sure at least one child has a value
		emptyFields(this); // Check for empty form elements that are marked "required"
		regExpressions(this); // Do some extra validation ie: email/password checking
		captcha(this); // Validate our captcha with AJAX

	});

	finalize();
	
}
