(function($){
	$.fn.validate = function(options) {
		
		var callbacks = {
			hightlight_error: function($field, error_type){
				$field.addClass('input-error');
				
				setTimeout(function(){
					$field.removeClass('input-error');
				}, 5000);
			},
			validate: function(){

				var valid = true;
				var $form = $(this);
				$form.removeClass('xv-valid');
				var email_regex = new RegExp(settings.email_re);
				
				$form.find(':input[required]').each(function(){
					var local_valid = true;
					if ($(this).is(':checkbox') && !$(this).is(':checked'))
						local_valid = false;
					else if ($(this).is(':radio') && !$form.find(':radio[name="'+$(this).attr('name')+'"]:checked').length)
						local_valid = false;
					else if ($(this).val() == '')
						local_valid = false;
					
					if (!local_valid) {
						settings['hightlight_error']($(this), 'required');
						valid = false;
					}
				});
				
				$form.find(':input[type="email"]').each(function(){
					if ($(this).val() != '' && !email_regex.test($(this).val())) {
						settings['hightlight_error']($(this), 'email');
						valid = false;
					}
				});
				
				$form.find(':input[pattern]').each(function(){
					
					var regex = new RegExp($(this).attr('pattern'));
					if ($(this).val() != '' && !regex.test($(this).val())) {
						settings['hightlight_error']($(this), 'pattern');
						valid = false;
					}
				});
				
				$form.find(':input[xv\\:sameas]').each(function(){
					
					var $rel = $form.find($(this).attr('xv:sameas'));
					if ($(this).val() != $rel.val()) {
						settings['hightlight_error']($(this), 'sameas');
						valid = false;
					}
				});
				
				if (valid)
					$form.addClass('xv-valid');
				
				return valid;
			}
		};
		
		var settings = {
			hightlight_error: callbacks['hightlight_error'],
			email_re: '^[_\.0-9a-zA-Z-]+@([0-9a-zA-Z][0-9a-zA-Z_-]+\.)+[a-z]{2,4}$'
		};
		
		if (options) { 
			$.extend(settings, options);
		}
		  
		return this.each(function() {
			$(this).submit(callbacks.validate);
		});
	};
})(jQuery);
