/* 
 * imVlalidateForm version 1.2
 * jQuery Form Validation plug-in version 1.2
 * @author Les Green
 * Copyright (c) 2008 Intriguing Minds, Inc.
 * http://www.intriguingminds.com/
 *
 * Version 1.2
 * Date: June 10, 2009
 * 1. Bug fix. Click submit and receive error because a field is not entered. Enter field and click submit again: [object][object] appears. Now fixed.
 *
 * Version 1.1
 * Date: Feb 8, 2009
 * Change Log:
 * 1. Changed "greaterThanZero" rule to "meetsCondition". Tests < <= > >= == !=
 * 2. Changed isAlpha and isNum to regular expressions
 * 3. Result in show message can now be either json or text
 * 4. Added 'complete' option to be used to when result type is not json or text
 * 
 *  
 * Version: 1.0 
 * Date: Oct 10, 2008
 * New features:
 * onError event
 * Add call back support - callback function is called when validation is error, return true form will be submited otherwise not.
 * Error list in the alert msg
 * Alias to field name
 * Select diff html attributes for validation rules instead off using custom html attributes
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.

 *   Demo and Documentation can be found at:   
 *   http://www.grasshopperpebbles.com
 *
 * Description
* Validate Form based upon a json validation map
* Can apply 9 types of validation:
* deleteRecord
* dbDupCheck - checks for duplicate records in a database based upon fields specified
* hasValue - For required fields. Checks if field is not empty
* isValidEmail - very basic email validation, only ensures that the '@' and the '.' appear in the field
* eitherOr - another required field check, checks if either of the two fields are empty. At least 1 field must have a value
* isChecked - checks wether a field is checked
* isAlpha - is an alpha
* isNum - is a number
* isEqual - whether two fields have equal values
//Basic concept (and some code) taken from "Beginning Ajax with PHP" by Lee Babin (APRESS)
// Created js class file 11/13/2007
//  
*/
if (!window.jQuery) {
	throw("jQuery must be referenced before using imValidateForm");
} else {
	;(function($){
		var canSubmit = true;
		var resultMsg = '';
		var message = '';
		var aMessages = new Array();
		aMessages["hasValue"] = " cannot be blank";
		aMessages["isValidEmail"] = " is not a valid";
		aMessages["eitherOr"] = " must be entered";
		aMessages["isEqual"] = " does not match";
		aMessages["isChecked"] = " must be selected";
		aMessages["isNum"] = " must be numeric";
		aMessages["isAlpha"] = " must contain alphas only";
		aMessages["greaterThanZero"] = " must be selected";
		
		$.fn.extend({
        	imValidateForm: function(options) { 
        		opts = $.extend({}, defaults, options);
            	$this = $(this);
				if (opts.submit_button != '') {
					$('#'+opts.submit_button).attr('disabled','disabled');	
				}
				if (opts.ajax_success) {
					if ((opts.ajax_success.func) && (opts.ajax_success.listener)) {
						$('#'+opts.ajax_success.listener).ajaxSuccess(function(evt, request, settings){
							if (!resultMsg.match("Error:")) {														
								var pVal = '';
								$.each(opts.ajax_success.func, function(i, itm) {
									var fn = eval(itm.name);
									if (itm.params) {
										$.each(itm.params, function(j, prm) {
											pVal += prm.param + ", ";
										});
										pVal = pVal.substr(0, pVal.length-2);
										fn (pVal);
									} else {
										fn ();	
									}
								});
							}
						});
					}
				}
				doValidate();
        	}
    	});	  
		
		var defaults = {
			responseDiv: '',
			validate_func: 'validateFields',
			validate_map: '',
			url: '',
			data_type: 'json',
			ajax_success: '',
			complete: '',
			submit_button: ''
		};
		
		function doValidate() {
			var formData = getFormValues(opts.validate_func);
			if (canSubmit) {
				$.ajax({
					type: "POST",
					url: opts.url,
					data: formData,
					dataType: opts.data_type,
					//beforeSend: function(){$("#loading").show("fast");}, //show loading just when link is clicked
					//complete: function(){ $("#loading").hide("fast");}, //stop showing loading when the process is complete
					success: showMessage//{ //so, if data is retrieved, store it in html
				 }); //close $.ajax(
			} else {
				showMessage(message);
				canSubmit = true;
				message = '';
			}
		};
			
		//function exitField() {
		//	if (opts.validate_func == 'dbDupCheck') {
		//		var formData = fn ();
		//	} 
		//};
			
		//function deleteRecord() {
		//	var answer = confirm("Confirm Delete");
		//	if (answer) {
		//		//this.imAjax.doGet(serverPage, imValidate.showMessage);
		//	}
		//};
			
		function dbDupCheck() {
			var str = "";
				
			$.each(opts.validate_map.fields[0].rules[0].fields, function(i, itm) {
				str += "&" + itm.id + "=" + escape($(itm.id).val()) + "&";								 
			});
			str = str.substr(0, str.length-1);
			return str;
		};
			
		function getFormValues(fncName) {
			var str = "";
			var fn = eval(fncName);
			$(':input', $this).each(function(i) {	
				if ((fn) && (opts.validate_map != '')) {
					message += fn (this);
				}
				if ((this.type == 'radio') || (this.type == 'checkbox')) {
					if (this.checked) {
						str += this.name + "=" + escape(this.value) + "&";		
					}
				} else {
					str += this.name + "=" + escape(this.value) + "&";
				}
			});
			str = str.substr(0, str.length-1);
			message = {"type": "message", "label": ""+message+""};
			return str;
		};
		
		function validateFields(el) {
			var msg = '';
			var bSubmit = false;
			$.each(opts.validate_map.fields, function(i, itm) {
				if (itm.id == el.name) {
					$.each(itm.rules, function(j, rule) {
						//don't use eval						   
						var fn = eval(rule.name);
						if (rule.fields) {
							bSubmit = fn (el.value, rule.fields);
						} else if (rule.exclude)	{
							bSubmit = fn (el.value, rule.exclude)
						} else if ((rule.value)	&& (rule.condition)) {
							bSubmit = fn (el.value, rule.value, rule.condition)
						} else {
							bSubmit = fn (el.value);
						}
						if (!bSubmit) {
							msg += itm.label + aMessages[rule.name] + "<br />";
							canSubmit = false;
						}						   
					});
				}
			});
			return msg;
		};
			
		function hasValue(val) {
			if (arguments.length > 1) {
				var retVal = ((val == arguments[1]) || (val == "")) ? false : true;		
			} else {
				var retVal = (val == "") ? false : true;
			}
			return retVal;
		};
							
		function isValidEmail(val) {
			var filter=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i
			if (filter.test(val)) {
				return true;
			} else {
				return false;
			}
		};
			
		function eitherOr(val, fields) {
			var isNotEmpty = false;
			if (hasValue(val)) {
				isNotEmpty = true;
			} else {
				$.each(fields, function(i, itm) {
					if (hasValue($('#'+itm.id).val())) {
						isNotEmpty = true;
						return false;
					}						   
				});
			}
			return isNotEmpty;
		};
			
		function isChecked(val, fields) {
			var ischecked = false;
			if (fields[0].id == 'all') {
				ischecked = isCheckedForm();
			} else {
				$.each(fields, function(i, itm) {
					if ($("#"+itm+":checked")) {
						ischecked = true;
						return false;
					}
				});
			}
			return ischecked;
		};
			
		//checks the entire form to find any checked elements
		function isCheckedForm() {
			var nL = $("input:checked", $this).length;
			var ischecked = (nL>0) ? true : false;
			return ischecked;
		};

		function isEqual(val, fields) {
			var bEqual = (val == $('#'+fields[0].id).val()) ? true : false;
			return bEqual;
		};
			
		//function isNum(val) {
		//	var retVal = (isNaN(val)) ? false : true;
		//	return retVal;	
		//};
	
		function isNum(val) {
			var patt = /\D/;
			var retVal = (patt.test(val)) ? false: true; 
			return retVal;	
		};
		
		//function isAlpha(val) {
		//	return isNaN(val);	
		//};
		
		function isAlpha(val) {
			var patt = /[^A-Z]/i;
			var retVal = (patt.test(val)) ? false: true; 
			return retVal;	
		};
		
		function isAlphaNumeric(val) {
			var patt = /\W/;
			var retVal = (patt.test(val)) ? false: true; 
			return retVal;	
		};
	
		//function greaterThanZero(val) {
		//	var retVal = (val < 0) ? false : true;
		//	return retVal;
		//};
		
		function meetsCondition(val, compVal, condition) {
			var retVal = false;
			switch (condition) {
			case "==":
				retVal = (val == compVal) ? true : false;
				break;
			case "!=":
				retVal = (val != compVal) ? true : false;
				break;
			case "<":
				retVal = (val < compVal) ? true : false;
				break;
			case "<=":
				retVal = (val <= compVal) ? true : false;
				break;
			case ">":
				retVal = (val > compVal) ? true : false;
				break;
			case ">=":
				retVal = (val >= compVal) ? true : false;
				break;	
			}
			return retVal;
		};
		
		
		function showMessage(result) {
			var loc = '';
			if (opts.submit_button != '') {
					$('#'+opts.submit_button).attr('disabled','');	
			}
			if (opts.complete) {
				var fn = eval(opts.complete);
				fn (result);
			} else if (result.type) {
				if (result.type == 'message') {
					resultMsg = result.label;
					$("#" +opts.responseDiv).html(result.label);
				} else if (result.type == 'continue') {
					loc += result.label;
					if (result.params) {
						loc += '?';
						$.each(result.params, function(i, itm) {
							loc += itm.name + '=' + itm.value + '&';						   
				 		});
						//remove last '&'
						loc = loc.substr(0, loc.length-1);
					}
					location.href = loc;
				}
			} else {
				$("#" +opts.responseDiv).html(result);
			}
		};
		
		function goTo(loc) {
        	location.href = loc;
        };
		
	})(jQuery);	
}
		


