(function(window,$,undefined){
	var formMessageSelector = 'div.message';
	var formMessageElement = '<div class="message"></div>';
	
	var metis = $.extend(true,{},( window.metis || {} ) , {
		form : {
			event : {
				validationFailed : 'metis.form.event.validationFailed'
			},
			fn : {
			
			},
			options: {
				validateOptions: {
					formMessageSelector:formMessageSelector,
					formMessageElement:formMessageElement
				}
			}
		}
	});

	metis.form.fn = $.extend({},metis.form.fn, {
		validateForm : function(form,options) {
			/* internal function */
			var b=true;

			var m=$(form).find(metis.form.options.validateOptions.formMessageSelector);
			/* Reset message status */
			m.removeClass("notice,alert").html("");

			$(form).find(":input[type='submit']").hide();
			$(form).find(metis.form.options.validateOptions.formMessageSelector).hide();

			$(form).find(".fieldWithError").removeClass("fieldWithError");

			$(form).find(":input").each(function(){
				b = metis.form.fn.validateInput(this);
				return b;
			});
			if ( b == false )
				$(form).find(":input[type='submit']").show();
			return b;
		},
		validateInput : function(input,parameters) {

			var defaults = {
				required:false
			};

			var options = $.extend(defaults, parameters);

			function v_e(a){
				return /[a-z0-9!#$%&'*+=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/i.test(a);
			}
			try {
				var form = $(input).closest("form");
				var fieldName = $(input).attr('name');
				var fieldMessage = $(input).attr('message');

				var required = options.required;

				if ( $(input).attr("required") && ( $(input).attr("required").toString().toLowerCase() =="true" ) ) {
					required = true;
				}

				if ( $(input).val() != null )
					$(input).val($(input).val().replace(/^\s+|\s+$/,""));

				if ( $(input).attr("label") && $(input).attr("label") != '' ) {
					fieldName = $(input).attr("label");
				} else {
					$(form).find("label[for='"+ $(input).attr('name') +"']").each(function(){
						fieldName = $(this).html();
					});
				}

				if(!isNaN($(input).attr("minlength"))) {
					if($(input).val().length < parseInt($(input).attr("minlength"))){
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Il campo “"+fieldName+"” deve essere lungo almeno "+parseInt($(input).attr("minlength"))+" caratteri" ]);
						return false;
					}
				}
				if( $(input).attr("validate") && $(input).attr("validate").search(/\bemail\b/i) >= 0 && $(input).val() != null && $(input).val() != "" ) {
					if(!v_e($(input).val())){
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Devi fornire un'email valida" ]);
						return false
					}
				}
				if ( $(input).attr("validate") && $(input).attr("validate").search(/\beurodate\b/i) >= 0 && $(input).val() != null && $(input).val() != "" ) {
					if ( /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test($(input).val()) == false ) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Devi fornire una data nel formato yyyy-mm-dd" ]);
						return false
					}
				}
				if ( $(input).attr("validate") && $(input).attr("validate").search(/\binteger\b/i) >= 0 && $(input).val() != null && $(input).val() != "" ) {
					var v = parseInt($(input).val().replace(/,/gi,"."));
					if ( isNaN(v) ) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Devi fornire un valore numerico valido per " + fieldName ]);
						return false;
					}
				}
				if ( $(input).attr("validate") && $(input).attr("validate").search(/\bfloat\b/i) >= 0 && $(input).val() != null && $(input).val() != "" ) {
					var v = parseFloat($(input).val().replace(/,/gi,"."));
					if ( isNaN(v) ) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Devi fornire un valore numerico valido per " + fieldName ]);
						return false;
					} else {
						$(input).val(v.toFixed(2));
					}
				}
				if ( $(input).attr("validate") && $(input).attr("validate").search(/\bhh:mm\b/i) >= 0 && $(input).val() != null && $(input).val() != "" ) {
					if ( /^[0-9]{2}$/.test($(input).val()) ) {
						$(input).val( $(input).val() + ":00" );
					}
					if ( /^[0-9]{2}:[0-9]{2}$/.test($(input).val()) == false ) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Devi fornire un valore nel formato HH:mm per" + fieldName ]);
						return false;
					}
				}
				if ( $(input).attr("validate") && $(input).attr("validate").search(/\bmobilephone\b/i) >= 0 && $(input).val() != null && $(input).val() != "" ) {
					$(input).val( ($(input).val()).toString().replace(/\s+/gi,'') );
					if ( /^(\+[0-9]{2})?([0-9]{10})$/.test( $(input).val() ) == false ) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Devi fornire un " + fieldName + " valido" ]);
						return false;
					}
				}
				if($(input).attr("type")=="password") {
					var f=$(form).find(":input[name='"+$(input).attr("name")+"-confirm']");
					if(f.length>0&&f.val()!=$(input).val()){
						$(input).trigger(metis.form.event.validationFailed,[[input,f], fieldMessage || "Le due password non coincidono" ]);
						return false
					}
				}
				if ( required == true ) {
					if ($(input).attr("type")=="checkbox" && $(input).attr("checked")==false) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "È necessario selezionare il campo" + fieldName ]);
						return false
					} else if ( $(input).attr("type") == "radio" ) {
						var radios = $(":input[name='" + $(input).attr("name") + "']");
						if ( radios.length > 0 && $(radios).filter(":checked").length == 0 ) {
							$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "È necessario selezionare un'opzione per " + fieldName ]);
							return false;
						}
					} else if( $(input).val() == null || /^[\t ]*$/.test($(input).val())==true ) {
						$(input).trigger(metis.form.event.validationFailed,[input, fieldMessage || "Il campo "+fieldName+" non può essere vuoto" ]);
						return false
					}
				}
			}
			catch(d) {
				$(input).trigger(metis.form.event.validationFailed,[input, d.toString() ]);
				return false
			}
			return true;
		},
		manageInputError : function(event,input,message) {
			// this è il form
			$(this).find(metis.form.options.validateOptions.formMessageSelector).addClass("alert").html(message).fadeIn();
			$(input).addClass("fieldWithError");
			$(input).focus();
		},
		initForm : function(forms,options) {
			var defaults = {
				bind:true,
				message:metis.form.options.validateOptions.formMessageElement
			};
			var options = $.extend(defaults, options);
			$(forms).each(function(i,form){
				var msg = $(form).find(metis.form.options.validateOptions.formMessageSelector);
				if ( msg.length == 0 ) {
					$(form).prepend(options.message);
					msg = $(form).find(metis.form.options.validateOptions.formMessageSelector);
				}
				if ( msg.length > 0 ) {
					msg.hide();
					if ( msg.html().length > 0 )
						msg.fadeIn("slow");
				}
				if ( options.bind ) {
					$(form).submit(function(){
						return metis.form.fn.validateForm(form);
					});
				}
				$(form).find("input[type='submit']").click(function(){
					return metis.form.fn.validateForm(form);
				});
				$(form).find(".submit").click(function(){
					$(form).submit();
				});

				$(form).bind(metis.form.event.validationFailed,metis.form.fn.manageInputError);
			});
			/* return this to make function chainable - marco */
			return forms;
		},
		serializeObj : function(form,options) {
			var data = {};
			$.each( $(form).serializeArray() , function(i,field) {
				data[field.name] = field.value;
			});
			return data;
		}
	});

	$.fn.serializeObj = function(options) {
		return metis.form.fn.serializeObj(this,options);
	};

	$.fn.initForm = function(options){
		return metis.form.fn.initForm(this,options);
	};

	$.fn.validateForm = function(options) {
		return metis.form.fn.validateForm(this,options);
	};

	$.fn.validateInput = function(options){
		return metis.form.fn.validateInput(this,options);
	}
	
	window.metis = metis;
	
})(window,jQuery);
