/************************************************************************************
	Gavin's unobstrusive barebonesValidation script
	version 1.1
	
	info
		Wanted to create very simple script for validation. Many current scripts do too much for
		you. Many times I have needed just a simple tool that lets me know if a given field
		is or is not valid, and provides me with callback hooks so I can provide my own methods
		and the script just leaves me alone after that.
		
		barebonesValidation takes a very straightforward object that lets you install the validtion
			{
				form: The form you want to apply this script to, works on child descendants of form
				event: The event trigger to apply to the form
				rules: takes a object literal with the properties that hold a regular expression
				on_success: simple callback method if validation passes, returns elements
				on_failure: simple callback method if validation fails, returns elements
			}
	
	example usage:
	
	<script type="text/javascript>
			$().ready(function() {
				var validation = new barebonesValidation({
					form: $('#client-login'),
					event: 'submit',
					rules: { required: { expression: /[^.*]/ } },
					on_failure: function(invalid_fields) {
						var field_names = [];
						for (var item in invalid_fields) { field_names.push(invalid_fields[item].title) };
						$($('<'+'div id="validation-error"'+'>' + field_names.join('<'+'br /'+'>') + '<'+'/div'+'>')).modal();
					}
				});
			});
		</script>
		
		example markup:
		
			<form id="client-login" action="/" method="post">
				<p>
					<label for="username" class="label">Username:</label>
					<input id="username" type="text" name="username" value="" class="validate:required" title="Please enter a valid User Name." />
				</p>
				<p>
					<label for="password">Password:</label>
					<input id="password" type="password" name="password" value="" class="validate:required" title="Please enter a valid Password." />
				</p>
				<p>
					<button type="submit">Login</button>
				</p>
			</form>
		
************************************************************************************/
	
	function barebonesValidation(validation_data) {
		this.options = validation_data;
		this.failures = [];
		this.successes = [];
		this.initialize();
	};
	var barebonesValidation_methods = {
		initialize: function() {
			if ( this.dataExists( this.options, [ 'form', 'event', 'rules' ] ) ) {
				this.options.form.bind(this.options.event, this, this.validate);
			}
		},
		validate: function(event) {
			var options = event.data.options;
			var validation = event.data;
			var hasSuccessCallback = validation.dataExists(options, 'on_success');
			var hasFailureCallback = validation.dataExists(options, 'on_failure');
			validation.failures = [];
			validation.successes = [];
			options.form.find('input').each(function() {
				var rule_name = validation.determineValidationRule(this);
				if (rule_name && validation.dataExists(options.rules, rule_name)) {
					var rule_object = options.rules[rule_name];
					if (validation.dataExists(rule_object , 'expression')) {
						if ( this.value.match(rule_object.expression)) {
							if (hasSuccessCallback) { validation.successes.push(this); }
						} else {
							if (hasFailureCallback) { validation.failures.push(this); }
						}
					}
				}
			});
			if (validation.failures.length > 0) {
				options.on_failure(validation.failures, event);
			}
			if (validation.successes.length > 0) {
				options.on_success(validation.successes);
			}
		},
		determineValidationRule: function(element) {
			var result = {};
			var rule_name_filter = /validate:(\w*)\s*?/;
			return (result = rule_name_filter.exec($(element).attr('class'))) ? result[1] : false;
		},
		dataExists: function(object, required_data) {
			if (required_data instanceof Array) {
				var required_data_present = true;
				for (var item in required_data) { required_data_present &= this.dataExists(object, required_data[item]) };
				return required_data_present;
			} else {
				return (typeof object[required_data] != 'undefined') ? true : false;
			}
		}
	};
	barebonesValidation.prototype = barebonesValidation_methods;
