/*
	jquery validation plugin v. 0.1
	author: Rick Quantz
	
	This is intended to be a super lightweight validator. To validate a form, wrap the fields you want to validate in a jQuery object, like so:
		$('form input').tcsValidate();
	The function validates each field for whatever criteria are specified in the field's class:
		<input type="text" class="required email" />
	This will be checked that its value contains something other than whitespace, and that it is a valid email address. Right now, criteria that are available are:
		required
		email
		phone
	
	The tcsValidate function returns an object: { valid: boolean, message: array }.
		valid will be false if any fields are not valid
		message will contain, without duplication, an array of messages for any validation errors. If valid is true, message will be an empty array.
	
	The function accepts an object map as an argument:
		chain: boolean, default: false. If set to true, tcsValidate will return the original jQuery object for chaining.
		errorClass: string, default: 'error'. The class applied to an input that fails validation (unless the default errorFilter is overridden). It will be removed on focus.
		errorFilter: the function applied to an invalid input. It is passed two arguments: the invalid input, and the errorClass.
		messages: object. These are messages returned when an input does not validate. The key for each message should correspond to one of the criteria.
		criteria: object. These are functions applied to the value of each element in the jQuery object that has a class matching the function's name. The function should return true for a valid value and false for an invalid one.
		
	Extending:
		This plugin can be extended three ways:
		- Passing additional criteria and messages through the object map when the function is called
		- Setting defaults for a page by accessing $.tcsValidate
		- Editing the jquery.tcsvalidate.js script. Feel free to do this if you're adding new validation criteria, but be sure to change the version number and add notes about when, how, and by whom it was altered.
*/


(function($, undefined){

	$.tcsValidate = {
		getMessage: function(criteria) {
			return this.messages[criteria];
		},
		messages: {
			email: 'The email address must be valid',
			required: 'Fields marked with a * are required',
			phone: 'The phone number does not appear to be valid',
			maxLength: 'Some fields appear to be too long'
		},
		criteria: {
			email: function(val) {
				if (val) {
					var rEmail = /^[\w\-\.]+\@[\w\-\.]+\.\w+$/;
					return rEmail.test(val);
				}
				else {
					return true;
				}
			},
			required: function(val) {
				var rReq = /\S/;
				return rReq.test(val);
			},
			phone: function(val) {
				if (val) {
					rPhoneChars = /[\(\)\-\. ]/g;
					rNonDigits = /\D/;
					numsOnly = val.replace(rPhoneChars, "");
					return (numsOnly.length == 10 && !rNonDigits.test(numsOnly));
				}
				else {
					return true;
				}
			},
			maxLength: function(val, max) {
				if (val) {
					return val.length <= parseInt(max);
				}
				else {
					return true;
				}
			}
		},
		errorFilter: function(input, errorClass) {
			$(input).addClass(errorClass).focus(function(){
				$(this).removeClass(errorClass);
			});
		}
	}
	
	$.fn.tcsValidate = function(options) {
		var validation = {
			valid: true,
			message: []
		}
		var errorFilter;
		var defaultOptions = {
			chain: false,
			errorClass: 'error'
		}
		options = $.extend(defaultOptions, options);
		$.extend($.tcsValidate.messages, options.messages);
		$.extend($.tcsValidate.criteria, options.criteria);
		errorFilter = options.errorFilter || $.tcsValidate.errorFilter;
		
		this.each(function(){
			var input = this;
			// create an array of the element's classes that match the plugin's validation criteria
			var criteria = $.grep(this.className.split(' '), function(cssClass){
				var functName = cssClass.split('-')[0];
				return ($.tcsValidate.criteria[functName]);
			});
			
			$.each(criteria, function(i, val) {
				var result, msg, splitVals = val.split('-');
				if (splitVals.length > 1) {
					result = $.tcsValidate.criteria[splitVals[0]](input.value, splitVals[1]);					
				}
				else {
					result = $.tcsValidate.criteria[val](input.value);
				}
				
				if (!result) {
					validation.valid = false;
					errorFilter(input, options.errorClass);
					msg = $.tcsValidate.getMessage(val);
					if ($.inArray(msg, validation.message) === -1) {
						validation.message.push(msg);
					}
				}
			});
		});
		
		if (options.chain) {
			return this;
		}
		else return validation;
	}

})(jQuery);
