$.fn.vForm = function(optss){
	/*
		plugin que valida os formularios no retorno do script.asp. Deve ser aplicada em um único objeto e não a uma coleção.
		
		em $(this) retorna ao próprio formulário. 
		
		parâmetros optss:
			options.btSubmit		- (string) seltor jquery do botão submit do formulario
			options.selectorMsg		- (string) seletor jquery onde será exibido a mensagem de retorno
			options.funcBefore(f)	- (function (parametro obj form)) função a ser executada antes do submit
			options.funcAfter(f,r)	- (function (parametros: obj = form, r = string de retorno)) função a ser executada depois do retorno submit
	*/
	
	function fnstring(v){//converte o parametro 'value' para '' (vazio) caso o mesmo seja: null, undefined or typeof!= number or string. Em geral usado para acaptura de valores de atributos.
		if(v==undefined || v==null || (typeof(v)!='string' && typeof(v)!='number')){return '';}else{return v;}
	};
	
	var obj;
	var objParent;
	var options = $.extend({
		btSubmit:null,
		seletorMsg:null,
		funcBefore:null,
		funcAfter:null
	},optss);
	
	var oForm=$(this);
	if(options.seletorMsg!=null)options.seletorMsg = oForm.find(options.seletorMsg);
	if(options.btSubmit!=null)options.btSubmit = oForm.find(options.btSubmit);
	var oIframe=$('<iframe src="" id="'+oForm.attr('id')+'_iframe" name="'+oForm.attr('id')+'_iframe" width="100" height="100" scrolling="no" frameborder="1" class="post"></iframe>').appendTo(oForm.attr('target',oForm.attr('id')+'_iframe'));

	var isSubmit=false;
	var fieldCurr=null;

	oForm.find('textarea').each(function(){
		var th=$(this);
		var maxlength=fnstring(th.attr('maxlength'));
		var countChar=fnstring(th.attr('countChar'));
		
		if(maxlength!='')maxlenght(th);
		//console.debug(countChar)
		if(countChar!=undefined && countChar!=''){
			th.data('countChar',$('#'+countChar+':eq(0)'))
			th.bind('keydown',function(e){
				e.stopPropagation();
				$(this).data('countChar').text($(this).val().length);
			});
		};
		
		th=null;
		mensagem_countChar=null;
		maxlength=null;
	});

	oForm.bind({
		'submit':function(e){
			if(fieldCurr!=null)fieldCurr.removeClass('alert');
			
			if(typeof(options.funcBefore)=='function')if(options.funcBefore.call(undefined,oForm)==false)return false;
			$(this).find('span.alert').html('');
			if(options.btSubmit!=null)options.btSubmit.attr({'disabled':true});
			isSubmit=true;
		},
		'msg':function(e,opts){
			/*
				parâmetro opt:
					field	- campos do form
					msg		- string da mensagem
			*/
			var opt = $.extend({
				field:'',
				msg:'',
				ok:false
			},opts);
			
			var obj=null;
			if(opt.field!=''){
				obj=oForm.find('#'+opt.field).addClass('alert').focus();
				var oMsg=obj.parent().find('span.alert');
				fieldCurr=obj;
			
				if(oMsg.length>0){
					oMsg.html(opt.msg);
				}else{
					oMsg=$("<span class='alert'></span>").insertAfter(obj).html(opt.msg);
				};
				
				oMsg=null;
			};
			
			if(options.seletorMsg!=null){
				options.seletorMsg.html(opt.msg);
				setTimeout(function(){
					if(obj!=null)obj.removeClass('alert');
					options.seletorMsg.html('');
				},10000);
			};
			//if(options.btSubmit!=null)options.btSubmit.attr({'disabled':false});
	
			//executa depois do submit
			//if(typeof(options.funcAfter)=='function' && ok)options.funcAfter.call(undefined,oForm);
			
			opt=null;
			opts=null;
			
		}
	});
	
	
	oIframe.bind('load',function(e){
		e.stopPropagation();
		if(isSubmit){//verfica se ocorreu o submit, para não executar antes
			isSubmit=false;
			if(options.btSubmit!='')options.btSubmit.attr({'disabled':false});
			var r=$(this).contents().find('body').html();
			
			
			if(r.indexOf('|')>-1){
				/*
					0 E ou R, 1 msg, 2 campo
					E - apenas mensagem, R - resposta OK
				*/
				var nx=r.split('|');
				if(nx[0]=='R'){//ok
					oForm.trigger('msg',{ msg:nx[1] })
					//executa depois do submit
					if(typeof(options.funcAfter)=='function')options.funcAfter.call(undefined,oForm,r);
					
				}else{//erro
					oForm.trigger('msg',{ field:nx[2]  ,msg:nx[1] })
				};
				nx=null;
			}else{//erro interno ou erro interno de servidor
				oForm.trigger('msg',{ msg:'Ocorreu um erro interno. Tente novamente.' })
			};
			r=null;
		};
	 });
	
	opt=null;
	opts=null;

	return oForm;
};

