$.fn.maskedTo.set({
	required : {
		events : 'blur:2',
		validate : function(o) {
			var val = $.trim(o.val());
			if(o[0].type == 'radio') {
				var radios = $(':radio[name=' + o[0].name + ']');
				for(var i = 0; i < radios.length; i++) {
					if(radios[i].checked 
						&& radios[i].value.length > 0) 
					{
						return true;
					}
				}
				
				return false;
			}
			
			return val.length > 0;
		},
		validatedTrue : function(o) {
			o.removeClass('fieldError')
				.addClass('fieldSuccess');
		},
		validatedFalse : function(o) {
			o.addClass('requiredError')
				.addClass('fieldError')
				.removeClass('fieldSuccess');
		}
	},
	maskedMail : {
		events : 'blur:3',
		validate : function(o) {
			var val = $.trim(o.val());
			o.val(val);
			
			return val.length > 0 
				&& !(/^[a-z0-9_\.\-]+@[a-z0-9_\-]+(\.[a-z0-9_\-]{2,})+$/).test(val) 
				? false
				: true;
		},
		validatedTrue : function(o) {
			o.removeClass('mailError');
			
			if(!o.is('.requiredError')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val(); 
			o.addClass('mailError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	},
	maskedInteger : {
		events : 'blur:3',
		validate : function(o) {
			var val = $.trim(o.val());
			o.val(val);
			
			return val.length == 0 
				|| (/^\d+$/).test(val);
		},
		validatedTrue : function(o) {
			o.removeClass('integerError');
			
			if(!o.is('.required')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val();
			o.addClass('integerError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	},
	cpf : {
		events : 'keydown,blur:3',
		onReady : function(o) {
			o.attr('maxlength',14);
		},
		validate : function(o,e) {
			var val = $.trim(o.val());
			
			if(val.length == 0) return true;

			val = val.replace(/\D/gi, '');
			// a pessoa esta digitando 
			if(e && e.type == 'keydown') {
				if(e.keyCode == 8 
					|| e.keyCode == 46) 
					return true;
				
				val = val
					.replace(/^(\d{3})/,'$1.')
					.replace(/^(\d{3}\.)(\d{3})/,'$1$2.')
					.replace(/^(\d{3}\.)(\d{3}\.)(\d{3})/,'$1$2$3-');
				
				if(val.length > 14){
					var re = v.substr(14);
					var r = new RegExp(re+'$');
					
					val = val.replace(r,'');
				}
				
				o.val(val);
				
				return true;
			}
			else {
				val = val.replace(/\D/gi, '');
				if(val.length != 11
					|| /^0{11}|1{11}|2{11}|3{11}|4{11}|5{11}|6{11}|7{11}|8{11}|9{11}$/.test(val)
				) {
					return false;
				}
				
				// Aqui começa a checagem do cpf
				var position, i, sum, dg, dg_inf;
				var digit = new Array(10);
				dg_inf = val.substr(9, 2); // Retira os dois últimos dígitos do número informado
				
				// Desemembra o número do cpf na array digit
				for (i=0; i<=8; i++) {
					digit[i] = val.substr( i, 1);
				}
				
				// Calcula o valor do 10º dígito da verificação
				position = 10;	
				sum = 0;
				
				for (i=0; i<=8; i++) {
					sum = sum + digit[i] * position;
					position = position - 1;
				}
					digit[9] = sum % 11;
				if (digit[9] < 2) {
					digit[9] = 0;
				}
				else{
					digit[9] = 11 - digit[9];
				}
				
				// Calcula o valor do 11º dígito da verificação
				position = 11;
				sum = 0;
				
				for (i=0; i<=9; i++) {
					sum = sum + digit[i] * position;
					position = position - 1;
				}
				
				digit[10] = sum % 11;
				
				if (digit[10] < 2)
					digit[10] = 0;
				else
					digit[10] = 11 - digit[10];
				
				// Verifica se os valores dos dígitos verificadores checkm
				dg = digit[9] * 10 + digit[10];
				
				if (dg != dg_inf)return false;
				else return true;
			}
		},
		validatedTrue : function(o) {
			
			o.removeClass('cpfError');
			
			if(!o.is('.required')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val();
			
			o.addClass('cpfError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	},
	cnpj : {
		events : 'keydown,blur:3',
		onReady : function(o) {
			o.attr('maxlength',18);
		},
		validate : function(o,e) {
			var val = $.trim(o.val());
			
			if(val.length == 0) return true;

			val = val.replace(/\D/gi, '');
			// a pessoa esta digitando 
			if(e && e.type == 'keydown') {
				if(e.keyCode == 8 
					|| e.keyCode == 46) 
					return true;
				
				val = val
					.replace(/^(\d{2})/,'$1.')
					.replace(/^(\d{2})\.(\d{3})/,'$1.$2.')
					.replace(/^(\d{2}\.)(\d{3}\.)(\d{3})/,'$1$2$3/')
					.replace(/^(\d{2}\.)(\d{3}\.)(\d{3}\/)(\d{4})/,'$1$2$3$4-');
				
				if(v.length > 18){
					var re = v.substr(18);
					var r = new RegExp(re+'$');
					
					val = val.replace(r,'');
				}
				
				o.val(val);
				
				return true;
			}
			else {
				val = val.replace(/\D/gi, '');
				if(val.length != 14
					|| /^0{14}|1{14}|2{14}|3{14}|4{14}|5{14}|6{14}|7{14}|8{14}|9{14}$/.test(val)
				) {
					return false;
				}
				
				// Aqui começa a checagem do cnpj
				var num, digits, sum, i, result, pos, size, eqDigits;
				eqDigits = 1;
				cnpj = cnpj.replace(/\D/gi,'');
				
				if (cnpj.length != 14)
					return false;
				
				for (i = 0; i < cnpj.length - 1; i++) {
					if (cnpj.charAt(i) != cnpj.charAt(i + 1)){
						eqDigits = 0;
						break;
					}
				}
				
				if (!eqDigits){
					size = cnpj.length - 2;
					num = cnpj.substring(0,size);
					digits = cnpj.substring(size);
					sum = 0;
					pos = size - 7;
					
					for (i = size; i >= 1; i--){
						sum += num.charAt(size - i) * pos--;
						if (pos < 2)
							pos = 9;
					}
					
					result = sum % 11 < 2 ? 0 : 11 - sum % 11;
					
					if (result != digits.charAt(0))
						return false;
					
					size = size + 1;
					num = cnpj.substring(0,size);
					sum = 0;
					pos = size - 7;
					
					for (i = size; i >= 1; i--){
						sum += num.charAt(size - i) * pos--;
						
						if (pos < 2)
							pos = 9;
					}
					
					result = sum % 11 < 2 ? 0 : 11 - sum % 11;
					
					return result != digits.charAt(1);
				}
				else
					return false;
			}
		},
		validatedTrue : function(o) {
			
			o.removeClass('cnpjError');
			
			if(!o.is('.required')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val();
			
			o.addClass('cnpjError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	},
	cep : {
		events : 'keydown,blur:1',
		onReady : function(o) {
			o.attr('maxlength',10);
		},
		validate : function(o,e) {
			var val = $.trim(o.val());
			
			val = val.replace(/\D/gi, '');
			
			if(e && e.type == 'keydown') {
				if(e.keyCode == 8 
					|| e.keyCode == 46) 
					return true;
				
				val = val.replace(/^(\d{5})/,'$1-');
				
				if(val.length > 9){
					var re = val.substr(9);
					var r = new RegExp(re+'$');
					
					val = val.replace(r,'');
				}
				o.val(val);
				
				return true;
			}
			else {
				return val.length == 0 || val.length == 8;
			}
		},
		validatedTrue : function(o) {
			o.removeClass('cepError');
			
			if(!o.is('.required')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val();
			
			o.addClass('cepError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	},
	phone : {
		events : 'keydown,blur:3',
		onReady : function(o) {
			o.attr('maxlength',13);
		},
		validate : function(o,e) {
			var val = $.trim(o.val());
			
			val = val.replace(/\D/gi, '');
			
			if(e && e.type == 'keydown') {
				// 8 : backspace
				// 46 : delete
				if(e.keyCode == 8 || e.keyCode == 46) 
					return true;
				
				val = val.replace(/^(\d)/,'($1')
					.replace(/^(\(\d{2})/,'$1)')
					.replace(/^(\(\d{2}\))(\d{4})/,'$1$2-');
				
				if(val.length > 13){
					var re = val.substr(13);
					var r = new RegExp(re+'$');
					val = val.replace(r,'');
				}
				o.val(val);
				
				return true;
			}
			else {
				return val.length == 0 || val.length == 10;
			}
		},
		validatedTrue : function(o) {
			o.removeClass('phoneError');
			
			if(!o.is('.required')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val();
			o.addClass('phoneError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	},
	date : {
		events : 'keydown,blur:3',
		onReady : function(o) {
			o.attr('maxlength',10);
		},
		validate : function(o,e) {
			var regex = [
			    /^(0[1-9]|[12][0-9]|3[01]).?(0[1-9]|1[012]).?([12][0-9]{3}|[0-9]{2})$/,
			    /^(\d{2})/,
			    /^(\d{2}\/)(\d{2})/
			];
			
			var val = $.trim(o.val());
			
			//if(e && e.type == 'keydown') {
				val = val.replace(/\D/gi, '');
				// 8 : backspace
				// 46 : delete
				if(e && ( e.keyCode == 8 || e.keyCode == 46) ) 
					return true;
				
				val = val.replace(regex[1],'$1\/')
					.replace(regex[2],'$1$2\/');
				
				if(val.length > 10){
					var re = val.substr(10);
					var r = new RegExp(re+'$');
					val = val.replace(r,'');
				}
				o.val(val);
				
				return true;
			/*}
			else {
				if(val.length == 0) return true;
				
				var _date = val.split('/');
				
				if (regex[0].test(val)){
					var Y,m,d;
					Y = parseInt(_date[0].length == 4 ? _date[0] : _date[2]);
					m = parseInt(_date[1]);
					d = parseInt(_date[0].length == 2 ? _date[0] : _date[2]);
										
					var _Y,_m,_d,check;
					check = new Date(Y,m-1,d);
					
					_d = check.getDate();
					_m = check.getMonth()+1;
					_Y = check.getFullYear();
					
					return _d == d && _m == m && _Y == Y;
				}
				
				return false;
			}*/
		},
		validatedTrue : function(o) {
			o.removeClass('dateError');
			
			if(!o.is('.required')) {
				o.removeClass('fieldError');
			}
		},
		validatedFalse : function(o) {
			var val = o.val();
			o.addClass('dateError');
			
			if(val.length > 0)
				o.removeClass('fieldSuccess')
					.addClass('fieldError');
		}
	}
});

/**
 * Exibe ou oculta elementos se o campo:radio tiver valor SIM
 * @return
 */
function showHideLinked() {
	var $this = $(this);
	var linkedArgs = $this.getLinkedArgs();
	var $linked = $(this).getLinked();
	var $checked = $('[name=' + $this.attr('name') + ']:checked');
	
	if($checked.length > 0) {
		if(( 
				($checked[0].value == 'sim' && linkedArgs.length == 1) 
				||
				(linkedArgs.length == 2 && $checked[0].value != linkedArgs[1])
			) && $checked[0].checked) {
			$linked.show();
			$linked.find(':maskedTo').enableMaskedTo();
		}
		else if(( 
				($checked[0].value != 'sim' && linkedArgs.length == 1) 
				||
				(linkedArgs.length == 2 && $checked[0].value == linkedArgs[1])
			)){
			$linked.hide();
			$linked.find(':maskedTo').disableMaskedTo();
		}
	}
	else {
		$linked.hide();
		$linked.find(':maskedTo').disableMaskedTo();
	}
}

function toMaskFields($parent) {
	function success() {
		var $this = $(this);
		
		setTimeout(function(){
			if(!$this.is('.fieldError')) {
				$this.addClass('fieldSuccess');
			}
		},4);
	}
	
	if(!$parent) $parent = $('body');
	
	$parent.find(':text').unbind('blur',success).blur(success);
	$parent.find('.required').setMaskedTo('required');
	$parent.find('.ipt_maskedMail').setMaskedTo('maskedMail');
	$parent.find('.ipt_maskedInteger').setMaskedTo('maskedInteger');
	$parent.find('.ipt_maskedPhone').setMaskedTo('phone');
	$parent.find('.ipt_maskedDate').setMaskedTo('date');
	$parent.find('.ipt_maskedCPF').setMaskedTo('cpf');
	$parent.find('.ipt_maskedCEP').setMaskedTo('cep');
}

/**
 * Validar os campos dos formulários
 */
$(function(){
	$(':radio,:checkbox').css({
		border:'none',
		background:'transparent'
	});
	var $forms = $('FORM');
	function checkThisFields() {
		var form = $(this);
		
		form.submit(function(){
			var noError = $(':maskedTo').maskedToNow(true).noValidSize() == 0;
			
			if(!noError) {
				var numError = 1;
				var msg = 'Foram encontrados os seguintes erros:\n';
				
				if(form.find('.requiredError').length > 0) {
					msg += '\n\t' + (numError++) + '. Os campos obrigatórios precisam ser preenchidos corretamente;';
				}
				
				if(form.find('.mailError').length > 0) {
					msg += '\n\t' + (numError++) + '. O campo de e-mail não possui um endereço válido;';
				}
				
				alert(msg);
			}
			return noError;
		});
	}
	
	$forms.each(checkThisFields);
	toMaskFields();
	$forms.find(':linked').each(function(){
		var $this = $(this);
		var $childs = $('[name=' + $this.attr('name') + ']').setLinked($this.getLinkedArgs().join('|'));
		$childs.each(showHideLinked).click(showHideLinked);
	});
});