/**
 *  @author Eduardo Gheller Morschbacher (egheller@trt4.jus.br)
 */

Event.observe(window, 'load', inicializa, true);

var validaCampos;

function inicializa() {
  validaCampos = new ValidaCampos();
}


var ValidaCampos = new Class.create();

ValidaCampos.prototype = {

  initialize: function() {
	this.eventoCampo('.valida_processo', 'blur', this.validaProcesso.bind(this)); // associa validação de processo a todos os campos da classe valida_processo
  },

  eventoCampo: function(seletor, evento, funcao) {
	$$(seletor).each(
	  function(campo) {
	    Event.observe(campo, evento, funcao);
	  }
	);
  },

  validaProcesso: function(e) {
	  var elemento = Event.element(e);
		if (!elemento.present())
			return;
		var valor = '' + elemento.value;
		var msgErro;
		for(i = 0; i<6; i++) {
			msgErro = this.valida(e, regraProcesso);
			if(!msgErro)
				return;
			elemento.value = '0' + elemento.value; 
		}
		elemento.value = valor;
		this.validaCampo(e, regraProcesso);
		Event.stop(e);
  },

  validaCampo: function(e, regra) {
	  var msgErro = this.valida(e, regra);
	  if(msgErro){
			alert(msgErro);
			Event.stop(e);
			Event.element(e).activate();
			return false;
		}
		return true;
	  },
  
  valida: function(e, regra) {
	  var elemento = Event.element(e);
		if (!elemento.present())
			return false;
		var msgErro;
		var valor = elemento.value;
		if (!regra.mascaraEntrada.test(valor)) {
			msgErro = regra.msgErro;
		} else {
			valor = !!regra.mascaraSaida ? eval(valor.replace(regra.mascaraEntrada,
					regra.mascaraSaida)) : valor;
			if (regra.regras && regra.regras.length > 0) {
				var atual = regra.regras.find( function(r) {
					return r.mascaraEntrada.test(valor);
				});
				if (!atual || atual.length == 0) {
					msgErro = regra.msgErro;
				} else {
					elemento.value = valor.replace(atual.mascaraEntrada,
							atual.mascaraSaida);
					if (atual.regras && atual.regras.length > 0) {
						var erros = atual.regras.findAll( function(r) {
							return !eval(valor.replace(r.mascaraEntrada,
									r.validacao));
						});
						if (erros.length > 0)
							msgErro = atual.msgErro;
						erros.each( function(m) {
							msgErro += '\n' + m.msgErro;
						});
					}
				}
			} else {
				elemento.value = valor;
			}
		}
		return msgErro;
  }
}

var regraProcesso = {
  mascaraEntrada: /^(\D*)(\d.+)$/,
  mascaraSaida: '"$1".toUpperCase() + "$2".replace(/[^0-9]/g, "")',
  msgErro: 'O processo informado não corresponde a um dos formatos aceitos abaixo:\n\nNNNNNNN-DD.AAAA.5.04.OOOO\nNNNNN-AAAA-VV-04-SS-D\nNNNNN.VVV/AA-D\n\nOnde: N = Número do processo, A = Ano, V = Vara, S = Seqüência, D = Dígito Verificador\n      O = Unidade de origem.\n\nDigite o número completo do processo, incluindo zeros à frente onde couber.\nHífens, pontos e barras são opcionais.', //'O número informado não corresponde. Favor retificar o campo.',
  regras: [
    { mascaraEntrada: /^(\d{5})(\d{4})(\d{3})(\d{2})(\d{2})(\d)$/
	, mascaraSaida: '$1-$2-$3-$4-$5-$6'
	, msgErro: 'Verifique os erros seguindo o formato do processo NNNNN-AAAA-VVV-RR-SS-D:\n'
	, regras: [
	    { mascaraEntrada: /^(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)$/
	    , validacao: '($1 * 9 + $2 * 8 + $3 * 7 + $4 * 6 + $5 * 5 + $6 * 4 + $7 * 3 + $8 * 2 + $9 + $10 * 9 + $11 * 8 + $12 * 7 + $13 * 6 + $14 * 5 + $15 * 4 + $16 * 3) % 11 % 10 == $17'
	    , msgErro: 'Dígito verificador inválido (campo D).'
	    },
	    { mascaraEntrada: /^\d{12}(\d{2})\d{3}$/
	    , validacao: '$1 == 4'
	    , msgErro: 'Para consulta de processos do TRT da 4� Regi�o, o valor informado deve ser 04 (campo RR).'
	    }
      ]
	},
	{ mascaraEntrada: /^(\d{5})(\d{3})(\d{2})(\d)$/
	, mascaraSaida: '$1.$2/$3-$4'
	, msgErro: 'Verifique os erros seguindo o formato do processo NNNNN.VVV/AA-D:\n'
	, regras: [
	    { mascaraEntrada: /^(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)$/
		, validacao: '(11 - ($1 * 11 + $2 * 10 + $3 * 9 + $4 * 8 + $5 * 7 + $6 * 6 + $7 * 5 + $8 * 4 + $9 * 3 + $10 * 2) % 11) % 11 % 10 == $11'
		, msgErro: 'Dígito verificador inválido (campo D).'
		}
	  ]
	},
	{ mascaraEntrada: /^(\d{7})(\d{2})(\d{4})(\d)(\d{2})(\d{4})$/
		, mascaraSaida: '$1-$2.$3.$4.$5.$6'
		, msgErro: 'Verifique os erros seguindo o formato do processo NNNNNNN-DD.AAAA.J.TR.OOOO:\n'
		, regras: [
		    { mascaraEntrada: /^(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)$/
			, validacao: 'validaNovoProcesso(parseInt(\'$1$2$3$4$5$6$7\',10), \'$10$11$12$13$14$15$16\', \'$17$18$19$20\', parseInt(\'$8$9\',10))'
			, msgErro: 'Dígitos verificadores inválidos (campo DD).'
			},
			{ mascaraEntrada: /^(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)$/
			, validacao: '\'$14$15$16\' == \'504\''
			, msgErro: 'O campo J deve ser igual a 5 e o campo TR deve ser igual a 04 para processos do TRT da 4ª Região.'
			}
		  ]
		}
  ]
}

function validaNovoProcesso(a, b, c, d) {
	  // O número é muito grande, faremos mod pelo teorema chinês
	  c = c+'00';
	  var r1 = a % 97; //R1 = (N6 N5 N4 N3 N2 N1 N0 mod 97)
	  // Deve-se explicitar a base 10 porque o javascript pode errar de base na conversão implícita
	  var r2 = parseInt((r1.toString() + b),10) % 97; //R2 = ((R1 concatenado com A3 A2 A1 A0 J2 T1 R0) mod 97)
	  var r3 = parseInt((r2.toString() + c),10) % 97; //R3 = ((R2 concatenado com O3 O2 O1 O0 01 00) mod 97)
	  return (d == (98 - r3)); //D1 D0 = 98 - R3
}
