/**
 * jQuery form validation plugin
 */
 (function($) {


/**
 * gmcFormValidate() provides a mechanism for validating an HTML form using AJAX.
 *
 * @name gmcFormValidate
 * @type jQuery
 * @param options  object literal containing options which control the form submission process
 * @cat Plugins/Form
 * @return jQuery
 */
$.fn.gmcFormValidate = function(options) {

    options = $.extend({
        loader: this.attr('loader') || '',
		success: this.attr('success') || null,
		error: this.attr('error') || null
    }, options || {});

	var validForm = false;

	var ajaxOptions = {
		url:		options.url,					// validation url
		async:		false,							// do a synchronous call
		data:		$(this).serialize(),		// serialized form data
		dataType:	'json',							// response type is json
		type:		'POST',							// http type
		success:	processValidationResponse,		// success callback
		error:		processValidationError			// error callback
	};

	var $$ = $(this);

	// show loading
	showLoader();

	// call the validation url
	$.ajax(ajaxOptions);

	return validForm;


	/**
	 * Process the response from the server side validation
	 */
	function processValidationResponse(data) {

		// clear all errors
		$('.bgccerror', $$).remove();

		if (data.success) {
			validForm = true;
			hideLoader();
			if (typeof options.success == 'function') {
				options.success(data);
			}
		}
		else {
			
			var errorCount = 0;
			var offsetFirstError;	// offset of the first error message

			for (var name in data.messages) {
				//alert(data.messages[name]);
				if ($(':input[name="' + name + '[]"]', $$).is(':checkbox')) {
					selector = ':input[name="' + name + '[]"]:last';
				}
				else {
					selector = ':input[name="' + name + '"]';
					if (typeof $(selector, $$)[0] == 'undefined') {
						selector = ':input[name="' + name + '[]"]';
					}
				}
				var html = '';
				var oldMessage = '';
				//for (var i=0; i < data.messages[name].length; i++) {
				//	if (oldMessage != data.messages[name][i]) {
				//		html += '<li>' + data.messages[name][i] + '</li>';
				//	}
				//	oldMessage = data.messages[name][i];
				//}
				$.each(data.messages[name], function(key, value) {
					if (oldMessage != value) {
						html += '<li>' + value + '</li>';
					}
					oldMessage = value;
				});
				html = '<div class="bgccerror" style="display:none"><ul>' + html + '</ul></div>';
				//$(selector, $$).parent().append(html);
				//$(selector, $$).parents('.formline').append(html);
				if ($(selector, $$).parents('.formline').length) {
					appendSelector = $(selector, $$).parents('.formline');
				}
				else {
					appendSelector = $(selector, $$).parent().append(html);
				}
				appendSelector.append(html);
				if (!offsetFirstError) {
					offsetFirstError = appendSelector.offset();
				}
				errorCount++;
			}

			// scroll to first error
			if (offsetFirstError) {
				window.scrollTo(0, offsetFirstError.top);
			}

			/*$('input, select, textarea', $$).each(function() {
				//alert($(this).is(":checkbox"));
				// ich hab eine ahnung
				name = $(this).attr('name');
				if (name != undefined) {
					name = name.replace(/\[\]$/g, "");	// remove trailing []
				}
				if (data.messages[name] != undefined) {
					var html = '';
					for (var i=0; i<data.messages[name].length; i++) {
						html += '<li>' + data.messages[name][i] + '</li>';
					}
					html = '<div class="error" style="display:none"><ul>' + html + '</ul></div>';
					//$(this).after(html);
					$(this).parent().append(html);
					errorCount++;
				}
			});*/
			
			$('.bgccerror', $$).fadeIn("slow", hideLoader);

			if (typeof options.error == 'function') {
				options.error(data);
			}

		}

	}


	/**
	 * An error occurred while trying to call the validation url
	 */
	function processValidationError(xmlObj, errorType, e) {

		hideLoader();

		// ignore the error
		//alert('Error validating form data: ' + errorType + "\n" + xmlObj);
		validForm = true;

	}


	/**
	 * Show spinning wheel
	 */
	function showLoader() {
		if (options.loader != '') {
			$(options.loader).css('display', '');
		}
	}


	/**
	 * Show spinning wheel
	 */
	function hideLoader() {
		if (options.loader != '') {
			$(options.loader).css('display', 'none');
		}
	}


};


})(jQuery);
