$.fn.addValidation = function(options) {
	var defaults = {
		msg_prefix: '<p class="form-error">&darr;&nbsp;',
		msg_suffix: '&nbsp;&darr;</p>',
		msg_required: '{field} is required',
		msg_email: 'The email address is invalid',
		msg_digit: '{field} must contain only digits',
		callback : null
	};

	// Extend our default options with those provided.
    var opts = $.extend(defaults, options);

	var filledIn = false; // detects if any fields have been entered before form submission

	// for each form...
	return this.each(function() {
		var form = $(this);
		// find all fields with class 'validate', and for each field..
		form.find("[class*='validate']").each( function() {
			// add blur event to call validation
			$(this).blur( function() {
				validateField(this);
			});
		});
		// also add event to submit button
		form.submit(function() {
			// if form has not been filled in, dont' continue
			if(!filledIn) {return false;}

			// remove any lingering spam messages
			$("p.spam-error").remove();

			// if a callback function has been set, then call this if form is valid
			if (opts.callback != null) {
				if (validForm(this)) {
					opts.callback(this);
				}
				return false;
			}
			// otherwise return form validation for normal form submission
			else {
				return validForm(this);
			}
		});
	});

	function validateField(field) {
		filledIn = true;

		o = $(field);
		// remove previous message
		o.prev("[class='form-error']").remove();
	    var msg = "";
		// check for empty field
		if (o.hasClass('required') && o.val().length == 0) {
			msg = opts.msg_required;
		}
		// check for digit field, +ve numbers, ignore spaces
		if(msg == "" && o.hasClass('digit')) {
			var filter = /^([0-9\s])+$/;
			if (!filter.test(o.val())) {
				msg = opts.msg_digit;
			}
		}
		// check for email field
		if(msg == "" && o.hasClass('email')) {
			var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9])+$/;
			if (!filter.test(o.val())) {
				msg = opts.msg_email;
			}
		}
		// display error msg
	    if (msg != "") {
			label = o.prev("label").html();
			msg = msg.replace("{field}", label);
			o.before(opts.msg_prefix + msg + opts.msg_suffix);
		}
	}

	function validForm(form) {
		isValid = true;
		// find all fields with class 'validate', and for each field
		// check previous sibling for presence of error msg
		// When we find the first one, return false to prevent form submission
		$(form).find("[class*='validate']").each( function() {
			if($(this).prev().is("[class='form-error']")) {
				isValid = false;
			}
		});
		return isValid;
	}
};

// callback function for form submission
function ajaxSubmit(form) {
	// disable submit button and add spinner
	$("#contact-form :submit")
		.attr("disabled", "disabled")
		.after('<span id="ajax-form-msg">sending message...<img src="/images/ajax-loader.gif" height="16" width="16" /></span>');

	$.ajax({
	    url: '/contact',
		cache: false,
	    dataType: 'json',
	    type: 'POST',
		timeout: 5000, // 5secs
		data: $(form).serialize(),
	    success: function (result) {
			if(result.success) {
				// update message
				$("#ajax-form-msg").html("message successfully sent");
				var removeMsg = function() {
					// fade out message, reset form and remove disabling of submit button
					$('#ajax-form-msg').fadeOut('slow', function() {
						$("form")[0].reset();
						$(this).remove();
					});
				};
				window.setTimeout(removeMsg,1000);
			}
			else {
				// check if spam code failed
				if(result.field == "spam") {
					$("#ajax-form-msg").remove();
					$("#spam").before('<p class="spam-error">&darr;' + result.msg + '&nbsp;&nbsp;&darr;</p>');
				}
			}
			$("#contact-form :submit").removeAttr("disabled");
	    },
		error: function(request, type) {
			// report error message
			$("#ajax-form-msg").html('<p class="spam-error">We do apologise. There has been a problem sending your message</span>');
			var removeMsg = function() {
				// fade out message and remove disabling of submit button
				$('#ajax-form-msg').fadeOut('slow', function() {
					$(this).remove();
					$("#contact-form :submit").removeAttr("disabled");
				});
			};
			window.setTimeout(removeMsg,2000);
		}
	  });
}

$(function() {
	// add email address
	$("#contact-msg").after('<p>You can email us on <a href="mailto:sales@microbubble.co.uk" title="email address">sales@microbubble.co.uk</a></p>');
	// add validation
	$("#contact-form").addValidation({
			callback : ajaxSubmit
		});         
});