/*---------------------------------------------------------------------------------------------------------------
Ag. Dotes - Otimizando seus dons - http://www.dotes.com.br - +55(62)3514.1227 | url: http://formoo.dotes.com.br
Criado por : Luiz Jr. Fernandes | email: contato@dotes.com.br / luizbox@msn.com | Update: 22/05/2007
---------------------------------------------------------------------------------------------------------------*/
var forMoo = new Class({
		Implements: Options,			   
        options: {
			form:'',				//Form in question
			onSubmit : true,		//onSubmit handler
			errorFields:[],			//Array Error Fields 
			errorMsgs:[],			//Array Error messages
			dateFormat: 'EURO', 	//ISO , EURO , ANSI
			timeFormat: '24',		//12 | 24
						
			/*Plugins*/
			showMsgs: true,			//Show or hidden error msgs
			scrollOnError:false,	//Scroll for error field onSubmit
			tips: false,			//Turn on or off tips for fields 		
			foc: false,				//Turn on or off focus on fields
			
			/*Classes*/
			original:'',			//Original fields class |required for focus|
			valid:'',				//Valid fields class
			invalid:'',				//Invalid fields class
			msg:'',					//Error Msgs class
			tipClass:'',			//Tips Class
			focClass:'',				//Focus Class
			
			/*Ajax*/
			url:'',			//Ajax form processing...
			waiting:'',
			update:'',
			onSuccess:''
        },
        initialize: function(options){
                this.setOptions(options);
				this.options.tipClass=this.options.tipClass.replace(".","")
				this.options.msg=this.options.msg.replace(".","")
				if (this.options.tips){ this.showTips(); }
				if (this.options.foc){ this.onFocus(); }
				this.form=$(this.options.form);
				if (this.form){this.form.reset();}
				if(this.options.onSubmit){
					if (this.form){
						this.form.addEvents({
							"submit": this.onSubmit.bind(this),
							"reset": this.onReset.bind(this)
						});
					}else{return false;}
				}
        },

		onSubmit :  function(ev){// onSubmit tests with validate if has errors. If yes it stops the submiting process	
			if(!this.validate()) {new Event(ev).stop(); }
		},
		onReset: function(ev){ // onReset turn back original field state
			var invalid=this.options.invalid;
			var valid = this.options.valid;
			var original = this.options.original;
			var update = this.options.update;
			var form = this.options.form;
			if (update != ""){	$(update).set("html","");	}
			this.options.errorFields.each(function(field){
						var morpher = new Fx.Morph(field, {wait: false});
						morpher.start(original);
						var span=field+'_span'
						if (!$(span)){}else{if($(span).getStyle("opacity")!=0){$(span).fade("out");}}
			});
			var valids = $$("#"+form+" .valid");
			valids.each(function(valid){
				var morpher = new Fx.Morph(valid, {wait: false});
				morpher.start(original);				 
			});
		},
		validate:function(){// Check if error array has itens
			var update = this.options.update;
			var waiting = this.options.waiting;
			var success = this.options.onSuccess;
			if (waiting == ""){waiting = "Aguarde . . ."}
			if (!this.options.errorFields.getLast()){
				if (this.options.url == ""){ //The old way...
					return true;	//Post the form
				}else{	//The new old way (ajax)
					var query =$(this.options.form).toQueryString();
					  new Request({
						  url: this.options.url, 
						  method: 'post',
						  encoding: 'iso-8859-1',
						  onRequest:function(){$(update).set("html",waiting)},
						  onSuccess:function(response){
								$(update).set("html",response);
								$(update).fade("in");
								if (success != '') eval(success);
						  }
					  }).send(query);
					  return false;
				}
			}else 	{		//Show errors for any field
				var invalid=this.options.invalid;
				var labels=$$("#"+this.options.form+" label");			var select_label;
				this.options.errorFields.each(function(field){
					var morpher = new Fx.Morph($(field), {wait: false});
					morpher.start(invalid);								   
				});
				this.options.errorMsgs.each(function(field,i){
					if (i==0){ff=field}
					var tmp=field.split("||")
					var field=tmp[0];
					var msg=tmp[1];
					labels.each(function(item){if ($(item).getProperty('for')==field){select_label=item}});
					if (!$(field+'_span')){
						var span =	new Element('span', {'styles': {'opacity': '0'},	'class': 'msg',	'id': field+'_span'}).set('html', msg).inject(select_label, 'after');
						$(span).fade("in");
					}else{
						var span=field+'_span';
						$(span).fade("in");
					}
				});				
				if (this.options.scrollOnError){
					ff = ff.toString()
					var ffs = ff.split("||")
					new Fx.Scroll(window).start(0,($(ffs[0]).getCoordinates().top - 30 ))
				}
				return false;
			}
		},
		
		aggErrors:function(field,msg){
			this.options.errorFields.include(field);
			this.options.errorMsgs.include(field +"||"+ msg);
		},
		
		clearErrors:function(field,msg){
			this.options.errorFields.erase(field)
			this.options.errorMsgs.erase(field +"||"+ msg);
			this.hideErrors(field,msg);
		},
		
		showErrors:function(field,msg){
				
				var morpher = new Fx.Morph(field, {wait: false});
				morpher.start(this.options.invalid);
				$(field).set("class","invalid");
				var labels=$$("#"+this.options.form+" label");			var select_label;
						labels.each(function(item){
									 if ($(item).getProperty('for')==field){
										 select_label=item
									}
				});
				
				if (!$(field+'_span')){
					if (this.options.showMsgs==true){
						var span=new Element('span', {'styles': {'opacity': '0'},	'class': this.options.msg,	'id': field+'_span'}).set('html', msg).inject(select_label, 'after'); 
					}else{ 
						var span=new Element('span', {'styles': {'opacity': '0'},	'class': 'msg',	'id': field+'_span'}).inject(select_label, 'after'); 
					}
					$(span).fade("in");
				}else{
					var span=field+'_span';
					$(span).fade("in");
				}
				
		},
		hideErrors:function(field,msg){
			var morpher = new Fx.Morph(field, {wait: false});
			morpher.start(this.options.valid);
			$(field).set("class","valid");
			var span=field+'_span'
			if (!$(span)){}else{if($(span).getStyle("opacity")!=0){$(span).fade("out");}}
		},
		showTips:function(){ //Mostar tips
			var tipClass=this.options.tipClass;
			var errorFields=this.options.errorFields;
			$$("#"+this.options.form +" *").each(function(field){
					var enter,leave;
					switch($(field).type){
						case 'text':
						case 'password':
						case 'textarea':
							enter="focus";leave="blur";
						break;
						case 'select-one':
							enter="focus";leave="blur";
							$(field).addEvent("change", function () {if ($(field).getProperty("title") && errorFields.contains($(field).id)){var tip=$(field).id+'_tip';var tween = new Fx.Tween(tip, 'opacity');tween.start(1,0)}}.bind(this) );	
						break;
						/*case 'checkbox':
						case 'radio':				
							enter="focus";leave="blur";				
						break;*/	
						case 'reset':
						case 'submit':
							$(field).addEvent("mouseenter", function () {if ( $(field).getAttribute("title")){var div=new Element('div', {'styles': {'opacity': '0','position':'absolute'},	'id': $(field).id+'_tip','class':tipClass}).set('html', $(field).getAttribute("title")).inject(field, 'bottom');var tween = new Fx.Tween(div, 'opacity');tween.start(0,1);}}.bind(this) );
							$(field).addEvent("mouseleave", function () {if ($(field).getProperty("title")){	var tip=$(field).id+'_tip';var tween = new Fx.Tween(tip, 'opacity');tween.start(1,0);(function(){$($(field).id+'_tip').destroy()}).delay(500, this);}}.bind(this) );	
						break;
					};
					$(field).addEvent(enter, function () { //Start tips for focus field
						if ( $(field).getAttribute("title") && errorFields.contains($(field).id)  ){
							var div=new Element('div', {'styles': {'opacity': '0','position':'absolute'},	'id': $(field).id+'_tip','class':tipClass}).set('html', $(field).getAttribute("title")).inject($(field).id, 'after');
							var tween = new Fx.Tween(div, 'opacity');
							tween.start(0,1);
							
						}
					}.bind(this) );			
					$(field).addEvent(leave, function () { //Hide tips for focus field
						if ( ($(field).getProperty("title")) && (errorFields.contains($(field).id)) ){
							var tip=$(field).id+'_tip';
							var tween = new Fx.Tween(tip, 'opacity');
							tween.start(1,0);
							(function(){$($(field).id+'_tip').remove()}).delay(500, this);
						}
					}.bind(this) );	
			});
		},
		onFocus:function(){
			var enter; var leave; var original = this.options.original; var focusClass= this.options.focClass;var errorFields=this.options.errorFields;
			$$("# "+this.options.form + " *").each(function(field){
				switch($(field).type){
						case 'text':
						case 'password':
						case 'textarea':
						case 'submit':
						case 'reset':
						case 'select-one':
						case 'file':
							enter="focus";leave="blur";
						break;
						default:
							enter="never";leave="land";
						break;
				}
				if (!(Browser.Engine.trident)){
					$(field).addEvent(enter, function () { 	var morpher = new Fx.Morph(field, {wait: false});morpher.start(focusClass);}.bind(this) );	
					$(field).addEvent(leave, function () { if (!errorFields.contains($(field).id)){var morpher = new Fx.Morph(field, {wait: false});							morpher.start(original);	}				}.bind(this) );	
				}
			});
		},
		Required: function(field,msg){//Validation for required fields

			switch($(field).type)
			{
				case 'text':
				case 'password':
				case 'file':
				case 'textarea':
					$(field).addEvent('blur', function () { this.textRequired(field,msg);	}.bind(this) );		
					this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);return false;
					break;
				case 'checkbox':
				case 'radio':
					var status=false;
					var fields=document.getElementsByName($(field).name);
					for(i=0;i<fields.length;i++){$(fields[i].id).addEvent('click', function () {this.checkradioRequired(field,msg);}.bind(this) )	}
					this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
					break;
				case 'select-one':
					$(field).addEvent('change', function () { this.selectRequired(field,msg,err);	}.bind(this) );	
					this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
					break;
			}
		
		},
		textRequired: function(field,msg){//Text fields validation
			if ($(field).value.replace(/ /g, '') == ""){this.aggErrors(field,msg);this.showErrors(field,msg);return false;}
			else{this.clearErrors(field,msg);this.hideErrors(field,msg);return true;}
		},
		checkradioRequired: function(field,msg){//CHECKBOX and RADIO validation
			var status=false;
			var fields=document.getElementsByName($(field).name);
			for (var i = 0; i < fields.length; i++){ if(fields[i].checked==true){status=true;}}
			if (!status){			this.aggErrors(field,msg);this.showErrors(field,msg);
			}else{this.clearErrors(field,msg);this.hideErrors(field,msg);}
		},
		selectRequired: function(field,msg,err){//SELECT fields validation
			if ($(field).value == ""){this.aggErrors(field,msg);this.showErrors(field,msg);return false;}
			if ($(field).value == err){this.aggErrors(field,msg);this.showErrors(field,msg);return false;}
			else{this.clearErrors(field,msg);this.hideErrors(field,msg);return true;}
		},
		emailRequired: function(field,msg){//EMAIL fields validation
			$(field).addEvent('blur', function () { this._emailRequired(field,msg);	}.bind(this) );	
			this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
		},
		_emailRequired:function(field,msg){
			if ($(field).value.search(/^\w+((-\w+)|(\.\w+))*\@\w+((\.|-)\w+)*\.\w+$/) == -1){this.aggErrors(field,msg);this.showErrors(field,msg);return false;}
			else{this.clearErrors(field,msg);this.hideErrors(field,msg);return true;}
		},
		urlRequired:function(field,msg){//URL fields validation
			$(field).addEvent('blur', function () { this._urlRequired(field,msg);	}.bind(this) );	
			this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
		},
		_urlRequired:function(field,msg){
			if ($(field).value.search(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i) == -1){this.aggErrors(field,msg);this.showErrors(field,msg);}
			else{this.clearErrors(field,msg);this.hideErrors(field,msg);}
		},
		integerRequired:function(field,msg){//INTEGER fields validation
			$(field).addEvent('blur', function () { this._integerRequired(field,msg);	}.bind(this) );
			this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
		},
		_integerRequired:function(field,msg){
			if ( ! ( parseInt($(field).value) == $(field).value ) ){this.aggErrors(field,msg);this.showErrors(field,msg);}
			else{this.clearErrors(field,msg);this.hideErrors(field,msg);}
		},
		cpfRequired:function(field,msg){//BRAZILIAN CPF validation
			$(field).addEvent('blur', function () { this._cpfRequired(field,msg);	}.bind(this) );
			this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
		},
		_cpfRequired:function(field,msg){
			 cpf=$(field).value;  exp = /\.|\-/g;  cpf = cpf.toString().replace( exp, "" );  var numeros, digitos, soma, i, resultado, digitos_iguais;			  digitos_iguais = 1;
			  if (cpf.length != 11){this.aggErrors(field,msg);this.showErrors(field,msg);return false;}
			  else{
				  for (i = 0; i < cpf.length - 1; i++)
						if (cpf.charAt(i) != cpf.charAt(i + 1)){digitos_iguais = 0; break;}
				  if (!digitos_iguais)
						{
						numeros = cpf.substring(0,9);digitos = cpf.substring(9);soma = 0;
						for (i = 10; i > 1; i--)
							  soma += numeros.charAt(10 - i) * i;
						resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
						if (resultado != digitos.charAt(0)){this.aggErrors(field,msg);this.showErrors(field,msg);}
						numeros = cpf.substring(0,10);	soma = 0;
						for (i = 11; i > 1; i--)
							  soma += numeros.charAt(11 - i) * i;
						resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
						if (resultado != digitos.charAt(1)){this.aggErrors(field,msg);this.showErrors(field,msg);}
						else{this.clearErrors(field,msg);this.hideErrors(field,msg);}
						}
				  else{this.aggErrors(field,msg);this.showErrors(field,msg);return true;}
			  }
		},
		matchRequired:function(field1,field2,msg){ //Field COMPARASION
			$(field2).addEvent('blur', function () { this._matchRequired(field1,field2,msg);	}.bind(this) );
			this.options.errorFields.include(field2);this.options.errorMsgs.include(field2 +"||"+ msg);
			this.options.errorFields.include(field1);this.options.errorMsgs.include(field1 +"||"+ msg);
		},
		_matchRequired:function(field1,field2,msg){
			
			if($(field1).value != $(field2).value || $(field2).value.replace(/ /g, '') == ""){this.aggErrors(field1,msg);this.aggErrors(field2,msg);this.showErrors(field1,msg);this.showErrors(field2,msg);}
			else{this.clearErrors(field1,msg);this.clearErrors(field2,msg);this.hideErrors(field1,msg);this.hideErrors(field2,msg);}
			
		},
		maskIt:function(field, mask, msg, event){  // MASKIT - field masks for numeric fields |--> date, time, phone, ids, serial numbers etc.
			$(field).addEvent('keypress', function () { this._maskIt(field, mask, msg, this.event);	}.bind(this) );
			//$(field).addEvent('blur', function () { this._maskIt(field, mask, msg, this.event);	}.bind(this) );
		//	this.options.errorFields.include(field);this.options.errorMsgs.include(field +"||"+ msg);
		},
		_maskIt:function(field, mask, msg, event){ 
	
			var sMask = mask;	var objeto = $(field);	var evtKeyPress = event;var i, nCount, sValue, fldLen, mskLen,bolMask, sCod, nTecla;
		/*
			 if (evtKeyPress.which == null){
				 char = String.fromCharCode(evtKeyPress.keyCode);    // IE
			 }else if (event.which > 0){
				 char = String.fromCharCode(evtKeyPress.which);	  // All others
			 }

			
			if(document.all){nTecla = evtKeyPress.keyCode;} 
			else if(document.layers) {alert("");nTecla = evtKeyPress.which;} 
			*/
			sValue = objeto.value;sValue = sValue.toString().replace( "-", "" );sValue = sValue.toString().replace( "-", "" );sValue = sValue.toString().replace( ".", "" );sValue = sValue.toString().replace( ".", "" );sValue = sValue.toString().replace( "/", "" );sValue = sValue.toString().replace( "/", "" );sValue = sValue.toString().replace( ":", "" );sValue = sValue.toString().replace( ":", "" );sValue = sValue.toString().replace( "(", "" );sValue = sValue.toString().replace( "(", "" );sValue = sValue.toString().replace( ")", "" );sValue = sValue.toString().replace( ")", "" );sValue = sValue.toString().replace( " ", "" );sValue = sValue.toString().replace( " ", "" );fldLen = sValue.length; mskLen = sMask.length;
			i = 0;	nCount = 0;	sCod = "";	mskLen = fldLen;
			while (i <= mskLen) {
			  bolMask = ((sMask.charAt(i) == "-") || (sMask.charAt(i) == ".") || (sMask.charAt(i) == "/") || (sMask.charAt(i) == ":"))
			  bolMask = bolMask || ((sMask.charAt(i) == "(") || (sMask.charAt(i) == ")") || (sMask.charAt(i) == " "))
			  if (bolMask) {sCod += sMask.charAt(i); mskLen++; }
			  else {sCod += sValue.charAt(nCount);nCount++;}
			  i++;
			}
			objeto.value = sCod;
			if (nTecla != 8) {
				if (nTecla==0){/* return true; this.clearErrors(field,msg);this.hideErrors(field,msg);*/}
				if (sMask.charAt(i-1) == "9") { return ((nTecla > 47) && (nTecla < 58));
				}else {/* return true; this.clearErrors(field,msg);this.hideErrors(field,msg);*/ }
			}else { /* return true; this.clearErrors(field,msg);this.hideErrors(field,msg);*/}
		
		}
		
});
