// especifica maior número de anos que uma pessoa pode ter nos cadastros
var cAnoMax = 120;

// especifica menor data aceita nos cadastros

/* as vars abaixo estão sendo criadas pelo php para que a data seja recuperada do servidor
d = new Date();
ano = d.getFullYear();
mes = d.getMonth()+1;
dia = d.getDate();
*/
//alert('data: '+dia+'/'+mes+'/'+ano);
//var cMenorData = dia + '/' + mes + '/' + (ano-cAnoMax);
//var dataHoje = dia + '/' + mes + '/' + ano;
// instanceof RegExp para validar data
var expRData = /^([0-9]{1,2})[\/]([0-9]{1,2})[\/]([0-9]{1,4})$/;
//Objeto contendo a posição onde se encontra cada componente da data na expressão regular. formato é o seguinte: {d: posicaoDoDia, m: posicaoDoMes, y: posicaoDoAno} 
var oExpRdata = {d: 1, m: 2, y: 3};

//LISTA DE CONSTANTES COM DEFINIÇÃO DE MASCARA PARA UTILIZAR COM maskInput NOS FORMULÁRIOS
/**
* Mascara para telefone. Permite somente números e espaços.
* @var string
*/
maskFone = "9999-9999";
/**
* Mascara para ddd do telefone. Permite somente números com 2 dígitos.
* @var string
*/
maskDDDFone = "99";
maskDV = "9999-9";
maskANO = "9999";
maskDIA = "99";
/**
* Mascara para CPF. Permite somente números com 11 dígitos.
* @var string
*/
maskCPF = "99999999999";
/**
* Mascara para Identidade. Permite somente números com 11 dígitos.
* @var string
*/
maskIDENTIDADE = "99999999999";
/**
* Mascara para número residencial. Permite somente números com 10 dígitos.
* @var string
*/
maskNumRes = "9999999999";
/**
* Mascara para CEP residencial. Permite somente números com 08 dígitos.
* @var string
*/
maskCEPRes = "99999999";

/**
* Mascara para data de nascimento. Permite somente datas no formato dd/mm/aaaa.
* @var string
*/
maskDataBr = "99/99/9999";

/******************************************************
Arquivo para funções javascript que tenham como objetivo o 
mascaramento.

Lista de funções:
  - addEvent: Adiciona uma função que será disparada quando ocorrer determinado evento no objeto. 
  - removeEvent: Remove um listener previamente adicionado em um objeto.
  - autoTab: A função irá adicionar a tabulação automática em todos os inputs.
  - maxLength: Controla o tamanho máximo de um campo removendo os excedentes.  
  - maskInput: Adiciona máscara a um campo. 
  - maskDec: Adiciona máscara (apenas para campos monetários e valor decimal) a um campo. 
  - resetForm: Reseta dados de um formulário.
  - noctrlv: Bloquea o tecla v para evitar ctrl + v. Exemplo de uso onkeydown="noctrlv(event)"

TODO:
  - Fazer o MaskInput aceitar array, para executar ele apenas uma vez para vários campos.
    Hoje para cada campo precisa ser criado um MaskInput
******************************************************/


/******************************************************
formatCurrency(field: HTMLInput, [floatPoint: Integer = 2], [decimalSep: String = ","], [thousandsSep: String = "."]): String 
Formata o input de forma que ele assuma o comportamento de um campo monetário. 
- field: Campo que receberá a formatação 
- floatPoint: Número de casas decimais 
- decimalSep: String representando o separador decimal 
- thousandsSep: String representando o separador de milhar 

Exemplo de uso:
maskDec(f.salario, 2);
******************************************************/

function maskDec(o, n, dig, dec){
    o.c = !isNaN(n) ? Math.abs(n) : 2;
    o.dec = typeof dec != "string" ? "," : dec, o.dig = typeof dig != "string" ? "" : dig;
    addEvent(o, "keypress", function(e){
        if(e.key > 47 && e.key < 58){
            var o, s, l = (s = ((o = this).value.replace(/^0+/g, "") + String.fromCharCode(e.key)).replace(/\D/g, "")).length, n;
            if(o.maxLength + 1 && l >= o.maxLength) return false;
            l <= (n = o.c) && (s = new Array(n - l + 2).join("0") + s);
            for(var i = (l = (s = s.split("")).length) - n; (i -= 3) > 0; s[i - 1] += o.dig);
            n && n < l && (s[l - ++n] += o.dec);
            o.value = s.join("");
        }
        e.key > 30 && e.preventDefault();
    });
}

/******************************************************
maskInput(field: HTMLInputElement, mask: String): void 
Adiciona máscara a um campo. 
- field: campo que vai receber a máscara 
- mask: máscara que será aplicada 

Regras Padrões
- a = A-Z e 0-9 
- A = A-Z, acentos e 0-9 
- 9 = 0-9 
- C = A-Z e acentos 
- c = A-Z 
- * = qualquer coisa 

Regras Especiais
- E = (Except) exceção 
- O = (Only) somente 

Criação de Máscaras
- Máscara simples: nesse tipo de máscara o usuário pode digitar no máximo a mesma 
  quantidade de caracteres que a máscara contém. 
Exemplo: 
  Telefone = (99)9999-9999 
  Data = 99/99/9999 

Máscara especial "regra^exceções": esse tipo de máscara é composto por 2 partes, 
separadas por "^", o lado esquerdo especifica a regra e o direito as exceções para a regra selecionada. 
Exemplo: 
  9^abc = a regra é aceitar somente números "9" e a exceção são os caracteres a, b e c 
  c^123 = aceita somente caracteres de a-z e a exceção são os números 1, 2 e 3 

Uso das regras especiais: ela é semelhante a máscara especial, porém o lado esquerdo 
tem um significado diferente, podendo ser "E" (qualquer coisa, exceto...) ou "O" (somente...) 
Exemplo: 
  E^abc: aceita qualquer coisa, menos a, b e c 
  O^123: só permite os caracteres 1, 2 e 3

Exemplos de uso:
maskInput(f.nome, "C^ ");
maskInput(f.dtnasc, "99/99/9999");
maskInput(f.telefone, "(99) 9999-9999");
maskInput(f.email, "a^@-_.");
maskInput(f.cpf, "999.999.999-99");
maskInput(f.cnpj, "99.999.999/9999-99"); 
maskInput(f.edta0116_numero, "9999999999");  
******************************************************/
function maskInput(f, m){
    function mask(e){
    	
    	//verifica se precionou teclas de movimento.
    	if(e.keyCode==35 || e.keyCode==36 || e.keyCode==37 || e.keyCode==38 || e.keyCode==39 || e.keyCode==40){
    		return;
    	}
    	
        var patterns = {"1": /[A-Z]/i, "2": /[0-9]/, "4": /[À-ÿ]/i, "8": /./ },
            rules = { "a": 3, "A": 7, "9": 2, "C":5, "c": 1, "*": 8};
        function accept(c, rule){
            for(var i = 1, r = rules[rule] || 0; i <= r; i<<=1)
                if(r & i && patterns[i].test(c))
                    break;
                return i <= r || c == rule;
        }
        
        var k, mC, r, c = String.fromCharCode(k = e.key), l = f.value.length;
        
        (!k || k == 8 ? 1 : (r = /^(.)\^(.*)$/.exec(m)) && (r[0] = r[2].indexOf(c) + 1) + 1 ?
            r[1] == "O" ? r[0] : r[1] == "E" ? !r[0] : accept(c, r[1]) || r[0]
            : (l = (f.value += m.substr(l, (r = /[A|9|C|\*]/i.exec(m.substr(l))) ?
            r.index : l)).length) < m.length && accept(c, m.charAt(l))) || e.preventDefault();
            
    }
    for(var i in !/^(.)\^(.*)$/.test(m) && (f.maxLength = m.length), {keypress: 0, keyup: 1})
        addEvent(f, i, mask);
};

/**
* Bloquea o tecla v para evitar ctrl + v. Exemplo de uso onkeydown="noctrlv(event)"
* @return void
*/
function noctrlv(e)
{	
	try{
		if(e.keyCode==86)
			e.preventDefault();
			
		/*
		Em caso de não usar jquery:
		if(window.event){
			//IE
			if(e.keyCode==86)
				e.returnValue = false;
		}else{
			//Netscape/Firefox/Opera		
			if(e.keyCode==86)
				e.preventDefault();
		}*/
	}catch(e){
		alert('Erro:\n'+e.message);
	}
}
/**
* Cancela um evento de acordo com navegador.<b> 
* @return void.
*/
function cancelEvent(e){
	if(window.event){
		//IE
			e.returnValue = false;
	}else{
		//Netscape/Firefox/Opera		
		e.preventDefault();
	}
}

/******************************************************
maxLength(campo: String, tammax: Integer): void
Controla o tamanho máximo de um campo removendo os excedentes.
- campo: Objeto do campo
- tammax: Tamanho máximo que deve ter o campo
******************************************************/
function maxLength(campo, tammax) {
  if (campo.value.length > tammax) campo.value = campo.value.substr(0,tammax);
}

/******************************************************
autoTab(void): void 
Apenas chame a função depois das tags <form> ou então no evento onload. 
A função irá adicionar a tabulação automática em todos os inputs que tiverem 
o atributo maxlenght setado. Os inputs devem estar dentro de uma tag form, 
caso contrário eles não receberão o comportamento. 
******************************************************/
function autoTab(){
    var c = 0, lastKey = function(e){c = e.key;}, next = function(e){
        try{
	        var i, j, f = (e = e.target).form.elements, l = e.value.length, m = e.maxLength;
	        if(c && m > -1 && l >= m){
	            for(i = l = f.length; f[--i] != e;);
	            for(j = i; (j = (j + 1) % l) != i && (!f[j].type || f[j].disabled || f[j].readOnly || f[j].type.toLowerCase() == "hidden"););
	            	try{j != i && f[j].focus();}catch(e){}
	            	/*
	            	O try catch acima foi inserido devido ao fato de em determinada situação 
	            	(quando o próximo elemento não dar suporte ao método focus(). Aconteceu quando chegou no 
	            	último elemento do form e não exitia nenhum input visível depois.) gerar erro.
	            	*/
	        }
        }catch(e){
        	/* em determinadas situações (ex: clicando ctrl+v seguidamente e mudando de campos com o mouse) 
        	gera erro de form.elements = nulo ou não é um objeto. Em função deste erro foi inserido este try catch para não mostrar este
        	erro pelo fato de que a mascara continua funcionando.
        	*/
        }
        
    };
    for(var f, i = (f = document.forms).length; i; addEvent(f[--i], "keyup", next), addEvent(f[i], "keypress", lastKey));
};


/**
* Deixa somente numeros na string.
* @return string
*/
String.prototype.sonumero = function(){
	return this.replace(/[^0-9]/gi,"");
};


/******************************************************
addEvent(object: Object, event: String, handler: Function(e: Event): Boolean, [scope: Object = object]): Boolean 
Adiciona uma função que será disparada quando ocorrer determinado evento no objeto. 
- object: objeto que receberá o listener 
- event: nome do evento sem o prefixo "on" (click, mouseover, ...) 
- handler: função que será chamada quando o evento ocorrer, será enviado como argumento 
              para esta função o objeto de evento, que além das propriedades normais, *sempre* irá conter: 
              - target: objeto que gerou o evento 
              - key: código do caractere em eventos de teclado 
              - stopPropagation: método para evitar a propagação do evento 
              - preventDefault: método para evitar que a ação default ocorra. O preventDefault pode ser emulado retornando "false" na função 
- scope: escopo (quem o "this" irá referenciar dentro do handler) que será usado quando a função for chamada, o default é o objeto no primeiro argumento 
******************************************************/
function addEvent(o, e, f, s){
	try{
    var r = o[r = "_" + (e = "on" + e)] = o[r] || (o[e] ? [[o[e], o]] : []), a, c, d;
    r[r.length] = [f, s || o], o[e] = function(e){
        try{
            (e = e || event).preventDefault || (e.preventDefault = function(){e.returnValue = false;});
            e.stopPropagation || (e.stopPropagation = function(){e.cancelBubble = true;});
            e.target || (e.target = e.srcElement || null);
            e.key = (e.which + 1 || e.keyCode + 1) - 1 || 0;
        }catch(f){}
        for(d = 1, f = r.length; f; r[--f] && (a = r[f][0], o = r[f][1], a.call ? c = a.call(o, e) : (o._ = a, c = o._(e), o._ = null), d &= c !== false));
        return e = null, !!d;
    }
  }catch(e){
  	alert(e.message);
  }
};

/******************************************************
removeEvent(object: Object, event: String, handler: function(e: Event): Boolean, [scope: Object = object]): Boolean 
Remove um listener previamente adicionado em um objeto e retorna true em caso de sucesso. 
- object: objeto que recebeu o listener 
- event: nome do evento sem o prefixo "on" (click, mouseover, ...) 
- handler: mesma função que foi atribuida no addEvent 
- scope: escopo em que a função foi adicionada, caso você tenha fornecido um escopo diferente no addEvent, 
            é necessário que você passe como parâmetro o mesmo objeto, 
            caso contrário a remoção do evento não será realizada 
******************************************************/
function removeEvent(o, e, f, s){
    for(var i = (e = o["_on" + e] || []).length; i;)
        if(e[--i] && e[i][0] == f && (s || o) == e[i][1])
            return delete e[i];
    return false;
};

/**
* Limpa dados de um formulário.
*
* @param frm : object form  - objeto do tipo formulário.
*/
function resetForm(frm){
	try{  
	  // Para cada um dos elementos do formulário
	  for (var i=0;i<frm.elements.length;i++) {
			if(frm.elements[i].type != 'button'){
		    switch(frm.elements[i].type){		    
		    	case 'radio':
		    		frm.elements[i].checked = false;
		    	break;
		    	
		    	case 'checkbox':
		    		frm.elements[i].checked = false;
		    	break;
		    	
		    	case 'select-multiple':
		    		frm.elements[i].value=0;
		    	break;
		    	
		    	case 'select-one':
		    		frm.elements[i].value=0;
		    	break;	    	
		    	
		    	case 'select':
		    		frm.elements[i].value=0;
		    	break;	    	
	
		    	case 'text':
		    		frm.elements[i].value = '';
		    	break;	   
		    	
		    	case 'password':
		    		frm.elements[i].value = '';
		    	break;	 
		    	
		    	case 'hidden':
		    		frm.elements[i].value = '';
		    	break;	 	    		    	 
		    }
	    }
	  }
	}catch(e){
		alert(msgErroResetForm + ': ' + e.message);
	}
}


/**
* Muda propriedade display do objeto.
* @param string  id - propriedade id do elemento
* @param boolean vl - 1 será mudado para block e 0 para none
*/
function mudaDisplay(id,vl){
	try{
		 st = document.getElementById(id).style;
		 if(vl){
		  st.display  = '';
		  //alert(st.id+ ' mostrando');
		 }else{
		  st.display  = 'none';
		  //alert(st.id+ ' escondendo');
		 }
	}catch(e){
		alert(e.message);
	}
}

/**
* Método para mover um option de um campo select para outro campo select.
* @return void.
*/
function adicionaRemove(cpSelO,cpSelD) {
  if (cpSelO.selectedIndex>-1) {
    cpSelD.options[cpSelD.length]=new Option(cpSelO.options[cpSelO.selectedIndex].text, cpSelO.options[cpSelO.selectedIndex].value);
    cpSelO.options[cpSelO.selectedIndex]=null;
  }  
}

/**
* Método para mover todos os options de um campo select para outro campo select.
* @return void.
*/
function adicionaRemoveAll(cpSelO,cpSelD) {
	for(i=0;i < cpSelO.length; i++){
    cpSelD.options[cpSelD.length]=new Option(cpSelO.options[i].text, cpSelO.options[i].value);
	}
	cpSelO.length = 0;
}

/**
* Método para mover todos os options selecionados de um campo select para outro campo select ou somente remover selecionados.
* @param select cpSelO - (Obrigatório) objeto select do qual será removido options selecionados.
* @param select cpSelD - (Opcional) objeto select para o qual será adicionado options selecionados, se não passado os options selecionados são apenas removidos.
* @return void.
*/
function adicionaRemoveSelected(cpSelO,cpSelD){
	if(typeof(cpSelO.options)!='object') return;
	if(cpSelD==null || cpSelD==''){
		cpSelD = document.createElement('select');
	}
	
	//objeto select temp.
	var selTemp = document.createElement('select');
	
	for(i=0;i < cpSelO.length; i++){
		opt = new Option(cpSelO.options[i].text, cpSelO.options[i].value);
	
	   	if(typeof(cpSelD)=='object' && cpSelO[i].selected==true){
	   		//vai passar para cpSelD - destino options selecionados
	   		if(cpSelO[i].selected==true){
	   			cpSelD.options[cpSelD.length] = opt;
	  			}
	   	}else{
	   		selTemp.options[selTemp.length] = opt;
	   	} 
	}
	
	cpSelO.length=0;
	//passa todos os options de selTemp para cpSelO
	adicionaRemoveAll(selTemp,cpSelO);		
	setTimeout(function(){cpSelO.focus();},150);
}
 
function Esconder(sp) {
  var obj = document.getElementById(sp);
  obj.style.display = 'none';
  obj.style.visibility = 'hidden';
}

function Mostrar(sp) {
  var obj = document.getElementById(sp);
  obj.style.display = "block";
  obj.style.visibility = 'visible';
}

/**
* Método para retornar values de options de um select no formato de string separado por ;
* @return string
*/
function optionsToString(cp){
	var str = false;
	for(i=0;i<cp.length;i++){
		str = (str==false) ? cp.options[i].value :  str+';'+cp.options[i].value;
	}
	return str;
}

/**
* Seta mensagem de Carregando em option de um campo do tipo select.
* @param string - propriedade id do campo select.
* @return void
*/
function setMsgCarregandoCbo(strId){
	cpSelD = document.getElementById(strId);
	cpSelD.options[0]=new Option("Carregando...", 0);
}
/**
* Reseta options de um campo do tipo select.
* @param string - propriedade id do campo select.
* @return void
*/
function resetCbo(strId){
	sel = document.getElementById(strId);
	sel.length = 0;
	sel.options[0] = new Option("-- Selecione --",0);
	sel.value=0;
}
/**
* Seta mensagem de Carregando em um campo elemento html - div, td ou span.
* @param string - propriedade id do campo select.
* @return void
*/
function setMsgCarregandoEl(strId){
	el = document.getElementById(strId);
	el.innerHTML = "<span class='form_texto3' style='text-align:center; width:100%;'>Carregando...</span>";
}
/**
* Retorna valor da propriedade value do radio checked.
* @param string name - propriedade name do radio.
* @return string
*/
function getValueRadioMarcado(name){
	try{	
		rdo = document.getElementsByName(name);
		for(i=0; i< rdo.length; i++){
			if(rdo[i].checked)
				return rdo[i].value;			
		}		
	}catch(e){
		alert(e.message);
	}	
}

