(function($) {
	
	$.fn.formValidation = function(o) {
		return this.each(function() {
			new $fv(this,o);
		});
	};
	
	var defaults = {
		formClass: 'ajax-validation',
		requiredClass: 'required',
		errorClass: 'error',
		selectOtherClass: 'other',
		ajaxLoaderImg: '/images/ajax-loader.gif',
		ajaxLoaderClass: 'loader',
		successMsg: 'Thank you, form successfully submitted'
	};
	
	$.formValidation = function(el,o) {
		
		this.options = $.extend({}, defaults, o || {});
		
		//called on ul
		if (el.tagName.toLowerCase() !== 'form')
			return;
		
		this.valid = true; //true unless proved false
		this.$form = $(el);
		this.formBackup = this.$form.html();
		
		if (!this.$form.hasClass(this.options.formClass))
			this.$form.addClass(this.options.formClass);
		
		this.strInputs = 'input[type=text].'+this.options.requiredClass+',textarea.'+this.options.requiredClass;
		this.strSelects = 'select.'+this.options.requiredClass;
		this.strEmailInputs = 'input[name*=email]';
		
		var self = this;
		
		this.funcSubmitForm = function() { self.initValidate(this); return false; };
		this.funcInputCheck = function() { self.inputCheck(this); };
		this.funcEmailInputCheck = function() { self.emailInputCheck(this); };
		this.funcSelectCheck = function() { self.selectCheck(this); };
		
		this.init();
		
	};
	
	var $fv = $.formValidation;

    $fv.fn = $fv.prototype = {};

    $fv.fn.extend = $fv.extend = $.extend;

    $fv.fn.extend({
		init: function() {
			
			this.$reqInputs = this.$form.find(this.strInputs);
			this.$emailInputs = this.$form.find(this.strEmailInputs);
			this.$reqSelects = this.$form.find(this.strSelects);
		
			//console.log(this.$reqInputs);
		
			this.$reqAll = this.$form.find(this.strInputs + ',' + this.strEmailInputs + ',' + this.strSelects);
			this.$reqAll.each(function() {
				this.isValid = false;
			});
			
			this.$form.submit(this.funcSubmitForm);
			this.$reqInputs.not(this.$emailInputs).blur(this.funcInputCheck);
			this.$emailInputs.blur(this.funcEmailInputCheck);
			this.$reqSelects.change(this.funcSelectCheck);
			$("input." + this.options.selectOtherClass).hide();
			
		},
		inputCheck: function(el) {
			//console.log(el);
			this.validateField(el);
			this.valid=true; //return to original state
		},
		selectCheck: function(el) {
			this.validateField(el);
			if ($(el).val().toLowerCase()=='other') {
				var selectAlt = $(el).attr('name') + '_other';
				$(el).hide();
				$('input[name=' + selectAlt + ']').show().focus().blur(this.funcInputCheck);
			}
			
		},
		initValidate: function(el) { //submit
			//this.clearErrors();
			if (this.valid==true) {
				var self = this;
				this.$reqAll.each(function() {
					self.validateField(this);
				});
			}
			
			//console.log('Final '+this.valid);
			
			if (this.valid) {			
				//submit form
				var domEl = $("input[type=submit]",this.$form).get(0);
				domEl.disabled=true;
				$(domEl).after('<img src="'+this.options.ajaxLoaderImg+'" class="'+this.options.ajaxLoaderClass+'">');
				var self = this;
				$.post(this.$form.attr('action'),this.$form.serializeArray(),function(data) {
					$("img."+self.options.ajaxLoaderClass,self.$form).remove();
					if (data=='success') {
						self.$form.empty().append('<p>' + self.options.successMsg + '</p>');
						setTimeout(
							function(){
								setTimeout(
									function() {
										self.$form.empty().append(self.formBackup);
										self.init();
									},1200
								);
								$("#TB_closeWindowButton").click();
								
							},4000
						);
				
					}
				});
			}
		},
		validateField: function(el,regex) {
			var pass = true;
			
			if (typeof regex != 'undefined') {
				if (!regex.test($(el).val()))
					pass=false;
			} else
				if ($.trim($(el).val())==='')
					pass=false;
			
			if (!pass) {
				this.showError(el);
				el.isValid=false
				this.valid=false;
			} else {
				this.hideError(el);
				el.isValid=true;
				this.valid=true;
				//check all other elements for true states
				var self = this;
				this.$reqAll.not(el).each(function() {
					if (!this.isValid) {
						self.valid=false;
					}
				});
			}
			//console.log('Input: '+pass);
			//console.log('Input overall: '+this.valid);
			//return pass;
		},
		showError: function(el) {
			if (!$(el).hasClass(this.options.errorClass))
				$(el).addClass(this.options.errorClass);
		},
		hideError: function(el) {
			if ($(el).hasClass(this.options.errorClass))
				$(el).removeClass(this.options.errorClass);
		},
		emailInputCheck: function(el) {
			//console.log(el);
			this.validateField(el,/^[a-z0-9'\.\-_\+]+@[a-z0-9\-_]+\.([a-z0-9\-_]+\.)*?[a-z]+$/i);
		}
	});
		  
})(jQuery);
