(function($){
	
	var settings = { //defaults
			errorclass:'fcheck-error',
			containerclass:'fcheck-error-container',
			strings:{},
			lang:'en'
	};
	
	var errors=[]; //global var for errors
	
	var methods= {
		init:function(th,fields,options){ //init function checks for requested checks and performs them
			$(th).bind('submit',function(){
				$.extend(settings,options);
				
				// reset from previous checks
				errors=[];
				$("."+settings.containerclass).remove();
				$("."+settings.errorclass).removeClass(settings.errorclass);
				
				//main section
				for (var i in fields){
					if(fields[i].empty===true) methods.isempty(th,fields[i].selector,i);
					if(fields[i].numeric===true) methods.isnumeric(th,fields[i].selector,i);
					if(fields[i].email==true) methods.isemail(th,fields[i].selector,i);
					if(fields[i].piva===true) methods.ispiva(th,fields[i].selector,i);
					if(fields[i].codfisc===true) methods.iscodfisc(th,fields[i].selector,i);
					if(fields[i].alpha===true) methods.isalpha(th,fields[i].selector,i);
					if(fields[i].alphanum===true) methods.isalphanum(th,fields[i].selector,i);
				}
				
				//after all checks are performed write errors
				return methods.writeerrors(th);
			});
		},
		
		//checks
		isempty:function(th,selector,label){ //empty field check
			if($(selector).val()==''){
				methods.showerror(th,selector,'empty',label);
			}
		},
		
		isemail:function(th,selector,label){ //email check
			if($(selector).val()!=''){
				mailreg=/^([a-z0-9]+)([a-z0-9.\-_]*)([@].)([a-z0-9.\-_]*)([.].)([a-z]{1,2})$/;
				value=$(selector).val();
				if(mailreg.test(value)==false){
					methods.showerror(th,selector,'email',label);
				}
			}
		},
		
		isnumeric:function(th,selector,label){ //numeric field check
			if($(selector).val()!=''){
				numreg=/[^0-9]/;
				value=$(selector).val();
				if(numreg.test(value)==true){
					methods.showerror(th,selector,'numeric',label);
				}	
			}
		},
		
		ispiva:function(th,selector,label){ //partita iva (VAT) check, (11 numbers)
			if($(selector).val()!=''){
				numreg=/[^0-9]/;
				value=$(selector).val();
				if(value.length!=11 || numreg.test(value)==true){
					methods.showerror(th,selector,'piva',label);
				}
			}
		},
		
		iscodfisc:function(th,selector,label){ //codice fiscale
			if($(selector).val()!=''){
				fiscreg=/^([a-zA-Z]{6})+([0-9]{2})+([a-zA-Z]{1})+([0-9]{2})+([a-zA-Z]{1})+([0-9]{3})+([a-zA-Z]{1})$/;
				value=$(selector).val();
				if(value.length!=16 || fiscreg.test(value)==false){
					methods.showerror(th,selector,'codfisc',label);
				}
			}
		},
		
		isalpha:function(th,selector,label){ //only letters field
			if($(selector).val()!=''){
				alphareg=/[^a-zA-Z]/;
				value=$(selector).val();
				if(alphareg.test(value)==true){
					methods.showerror(th,selector,'alpha',label);
				}
			}
		},
		
		isalphanum:function(th,selector,label){ //only letters and numbers
			if($(selector).val()!=''){
				alnumreg=/[^0-9a-zA-Z]/;
				value=$(selector).val();
				if(alnumreg.test(value)==true){
					methods.showerror(th,selector,'alphanum',label);
				}
			}
		},
		//end checks
		
		showerror:function(th,selector,error,label){ //adds an error to errors global variable and changes input class
			errorstring=methods.translate(error,label);
			errors.push(errorstring);
			$(selector).addClass(settings.errorclass);
		},
		
		writeerrors:function(th){ //final function, create a div containing the error messages and authorize or not form submission
			if(errors.length>0){
				var string=settings.strings[settings.lang].errors;
				$(th).before('<div class="'+settings.containerclass+'"><span>'+string+'</span><ul></ul></div>');
				for(var x in errors){
					$("."+settings.containerclass+" ul").append('<li>'+errors[x]+'</li>');
				}
				return false;
			}
			return true;
		},
		
		translate:function(string,label){ //function for string localization
			reg=/%s/;
			return settings.strings[settings.lang][string].replace(reg,label);
		}
	};
	
	//main plugin section
	jQuery.fn.formCheck = function(options){
		
		if(options.method=="translation"){
			$.extend(settings.strings,options.strings);
			return false;
		}
		
		return this.each(function(){
			
			var th = $(this);
			
			var fields=options.fields; 
			
			if(options){
				
				methods.init(th,fields,options);
			}
		});
	};
})(jQuery);
