﻿/**

All attributes are included in the appropriate element tag an follow the normal attribute="value" process.

All items prefixed with an '*' are required.

<form> attributes :
	*rbh_onsubmit : must be set to 'validate'
	rbh_validate_succeed : callback for form wide successful validation
	rbh_validate_fail : callback for form wide failed validation
	rbh_validate_defaultfail : callback for form and all elements that don't define a failed validation callback

Element attributes :
	rbh_validate : must be set to asemail, aszipcode, bylength, byregexp, hascontent, asnumeric, asinteger
	rbh_validate_succeed : callback for successful element validation
	rbh_validate_fail : callback for failed element validation
	rbh_validate_errormessage : error message to display
	
	Extra element attributes by validation type (rbh_validate)
		rbh_validate="bylength" :
			rbh_maximumlength : maximum length in characters allowed for element
			rbh_minimumlength : minimum length in characters allowed for element
		rbh_validate="byregexp" :
			rbh_validate_regexp : the full regular expression to test against
		rbh_validate="asnumeric" and rbh_validate="asinteger":
			rbh_validate_maximum_value : maximum value of the number allowed for element
			rbh_validate_minimum_value : minimum value of the number allowed for element

The following elements can contain the associated validation type(s)
	type="text" : asemail, aszipcode, bylength, byregexp, hascontent
	
*/
(function( $ ) {
  $.fn.rbh_formvalidator = function(m) {
		var _methods = {
			'submit' : function() {
				var c = null,
						r = true,
						a = null,
						cb = null;
				c = $('form[name=' + this.name + '] :input[rbh_validate]');
				$.each(c, function(k, v) {
					a = $(v).attr('rbh_validate');
					a = a.split(' ');
					$.each(a, function(k2, v2) {
						switch(v2.toLowerCase()) {
							case 'asemail':
								if($(v).data('asemail_changeset') != 'true') {
									$(v).change(_methods.asEmail);
									$(v).data('asemail_changeset', 'true');
								}
								if(!_methods.asEmail(v))
									r = false;
								break;
							case 'aszipcode':
								if($(v).data('aszipcode_changeset') != 'true') {
									$(v).change(_methods.asZipcode);
									$(v).data('aszipcode_changeset', 'true');
								}
								if(!_methods.asZipcode(v))
									r = false;
								break;
							case 'bylength':
								if($(v).data('bylength_changeset') != 'true') {
									$(v).change(_methods.byLength);
									$(v).data('bylength_changeset', 'true');
								}
								if(!_methods.byLength(v))
									r = false;
								break;
							case 'byregexp':
								if($(v).data('byregexp_changeset') != 'true') {
									$(v).change(_methods.byRegExp);
									$(v).data('byregexp_changeset', 'true');
								}
								if(!_methods.byRegExp(v))
									r = false;
								break;
							case 'hascontent':
								if($(v).data('hascontent_changeset') != 'true') {
									$(v).change(_methods.hasContent);
									$(v).data('hascontent_changeset', 'true');
								}
								if(!_methods.hasContent(v))
									r = false;
								break;
							case 'asnumeric':
								if($(v).data('asnumeric_changeset') != 'true') {
									$(v).change(_methods.asNumeric);
									$(v).data('asnumeric_changeset', 'true');
								}
								if(!_methods.asNumeric(v))
									r = false;
								break;
							case 'asinteger':
								if($(v).data('asinteger_changeset') != 'true') {
									$(v).change(_methods.asInteger);
									$(v).data('asinteger_changeset', 'true');
								}
								if(!_methods.asInteger(v))
									r = false;
								break;
							default:
								break;
						}
					});
				});
				if(r) {
					cb = $(this).attr('rbh_validate_success');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb)) {
							cb(this)
						} else {
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form succeed handler');
						}
					}
				} else {
					cb = $(this).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(this)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form fail handler');
					}
				}
				return r;
			},
			'asEmail' : function(el) {
				if(!($(el).data('asemail_changeset'))) {
					el = this;
				}
				var r = /^[a-z0-9._-]+@[a-z0-9._-]+\.[a-z]{2,4}$/i,
						cb = false,
						errmsg = '',
						ret = true;
				if(_methods._regexptest(el.value, r)) {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
				} else {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" fail handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = 'Please enter a valid email address';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					ret = false;
				}
				return ret;
			},
			'asInteger' : function(el) {
				if(!($(el).data('asinteger_changeset'))) {
					el = this;
				}
				var cb = false,
						errmsg = '',
						ret = true,
						max = $(el).attr('rbh_validate_maximum_value'),
						min = $(el).attr('rbh_validate_minimum_value'),
						minmaxtest = (el.value == parseInt(el.value));
				max = max == parseInt(max) ? max : '';
				min = min == parseInt(min) ? min : '';
				if(minmaxtest) {
					if(!min == '' && !max == '') {
						if(el.value < min || el.value > max)
							minmaxtest = false;
						else
							minmaxtest = true;
					} else if(!min == '' && max == '') {
						if(el.value < min)
							minmaxtest = false;
						else
							minmaxtest = true;
					} else if(min == '' && !max == '') {
						if(el.value > max)
							minmaxtest = false;
						else
							minmaxtest = true;
					}
				}
				if(minmaxtest) {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
					return true;
				} else {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" fail handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = 'Please enter a valid integer value.';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					return false;
				}
			},
			'asNumeric' : function(el) {
				if(!($(el).data('asnumeric_changeset'))) {
					el = this;
				}
				var cb = false,
						errmsg = '',
						ret = true,
						max = $(el).attr('rbh_validate_maximum_value'),
						min = $(el).attr('rbh_validate_minimum_value'),
						minmaxtest = false;
				max = max == parseFloat(max) ? max : '';
				min = min == parseFloat(min) ? min : '';
				if(!min == '' && !max == '') {
					if(el.value == parseFloat(el.value) && el.value >= min && el.value <= max)
						minmaxtest = true;
					else
						minmaxtest = false;
				} else if(!min == '' && max == '') {
					if(el.value == parseFloat(el.value) && el.value >= min)
						minmaxtest = true;
					else
						minmaxtest = false;
				} else if(min == '' && !max == '') {
					if(el.value == parseFloat(el.value) && el.value <= max)
						minmaxtest = true;
					else
						minmaxtest = false;
				}
				if(minmaxtest) {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
					return true;
				} else {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" fail handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = 'Please enter a valid numeric value.';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					return false;
				}
			},
			'asZipcode' : function(el) {
				if(!($(el).data('aszipcode_changeset'))) {
					el = this;
				}
				var r = /^([0-9]{5}(?:-[0-9]{4})?)*$/,
						cb = false,
						errmsg = '';
				if(_methods._regexptest(el.value, r)) {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
					return true;
				} else {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" fail handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = 'Please enter a valid zipcode.';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					return false;
				}
			},
			'byLength' : function(el) {
				if(!($(el).data('bylength_changeset'))) {
					el = this;
				}
				var min = 0,
						max = 0,
						t = '',
						cb = false,
						errmsg = '',
						ret = true,
						failed = false;
						min = $(el).attr('rbh_validate_minimumlength');
						max = $(el).attr('rbh_validate_maximumlength');
						t = el.value;
				if(min && max) {
					if(t.length < min || t.length > max)
						failed = true; 
				} else if(min) {
					if(t.length < min)
						failed = true;
				} else if(max) {
					if(t.length > max)
						failed = true;
				}
				if(failed) {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" fail handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = t.length < min ? 'too few' : 'too many';
							errmsg = 'A field has ' + errmsg + ' characters entered.';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					ret = false;
				} else {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
				}
				return ret;
			},
			'byRegExp' : function(el) {
				if(!($(el).data('byregexp_changeset'))) {
					el = this;
				}
				var r = '',
						cb = false,
						errmsg = '',
						ret = true;
				r = $(el).attr('rbh_validate_regexp');
				try {
					r = eval(r);
				} catch(ex) {
					errmsg = $(el).attr('rbh_validate_errormessage');
					if(!errmsg) {
						errmsg = 'An invalid regular expression has been passed as a regexp test.';
					}
					_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					ret = false;
					return;
				}
				if(_methods._regexptest(el.value, r)) {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
				} else {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" fail handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = 'An element was tested against a regular expression and failed.';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					ret = false;
				}
				return ret;
			},
			'hasContent' : function(el) {
				if(!($(el).data('hascontent_changeset'))) {
					el = this;
				}
				var t = '',
						cb = false,
						errmsg = '',
						ret = true;
				if(el.value.length > 0) {
					cb = $(el).attr('rbh_validate_succeed');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					}
				} else {
					cb = $(el).attr('rbh_validate_fail');
					if(cb) {
						if(!$.isFunction(cb)) {
							cb = eval(cb);
						}
						if($.isFunction(cb))
							cb(el)
						else
							alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form element "' + el.name + '" succeed handler');
					} else {
						errmsg = $(el).attr('rbh_validate_errormessage');
						if(!errmsg) {
							errmsg = 'A required field has not been filled in.';
						}
						_methods.defaultErrorHandler({'form':$(el).parent(),'msg':errmsg});
					}
					ret = false;
				}
				return ret;
			},
			'defaultErrorHandler' : function(inob) {
				var cb = $(inob.form).attr('rbh_validate_defaultfail');
				if(cb) {
					if(!$.isFunction(cb)) {
						cb = eval(cb);
					}
					if($.isFunction(cb))
						cb(el)
					else
						alert('RBH_FORMVALIDATOR ERROR: invalid function passed as form wide default fail handler');
				} else {
					alert(inob.msg);
				}
			},
			'_regexptest' : function(t, r) {
				if(t == '' || r == '') return false;
				if(t.search(r) > -1)
					return true;
				else
					return false;
			}
		};
		/** Bind the form submit event */
  	$('form[rbh_onsubmit=validate]').submit(_methods.submit);
  };
})( jQuery );
