//regular expressions
var teclasEscape = /[\x00\x03\x08\x09\x0D\x16\x18\x1A\x25\x26\x27\x28]/;
var teclasClipboard = /[cvxz]/i;

// Retorna o código do evento de acordo com o browser
function getKeyCode(objEvent){
	return (objEvent.which) ? objEvent.which : objEvent.keyCode;
}

// Retorna o elemento que gerou o evento
function getSource(objEvent){
	return (objEvent.srcElement) ? objEvent.srcElement : objEvent.target;
}

// Checa se o evento eh um Ctrl + C, Ctrl + V, Ctrl + X ou Ctrl + Z (para browsers NS6)
function checkClipboardCode(objEvent, strKey) {
	return (objEvent.ctrlKey) ? objEvent.ctrlKey && teclasClipboard.test(strKey) : false;
}

/**
*	Funcao que recebe uma mascara de formato e retorna a expressao regular
*	para esse formato. Ex:
*	mascara: ##/##/@@@@ retorna um regular expression para 22/33/abcd por exemplo
*	se for passado um 'index', retorna uma regular expression para a mascara até
* 	aquele índice. Ex:
*   mascara: ##-@@/#### e index = 8 equivale a passar apenas a mascara: ##-@@/##
*	Obs: # - Indica qualquer número
*		 @ - Indica qualquer letra
*/
function makeRegEx(mascara, index){
	var regex = "^(";
	var tmp = mascara.length;
	if(index && index <= mascara.length) tmp = index;
	for(var i=0; i<tmp; i++){
		if(mascara.charAt(i) == "#") regex = regex + "\\d";
		else if(mascara.charAt(i) == "@") regex = regex + "[a-zA-Z]";
		else regex = regex + "[" + mascara.charAt(i) + "]";
	}
	regex = regex + ")$";
	return new RegExp(regex);
}

/**
*	Funcao que aplica o formato da mascara passada.
*	Uso: onkeypress="return maskKeyPress(event,'##.@##@@##-@')"
*	Se for passado um botao, ele executará botao.click() se a
* 	tecla pressionada for Enter (keyCode = 13).
*/
function maskKeyPress(objEvent,mascara,botao) {
	if(!mascara) return true; // Se nao passar mascara, aceita tudo
	var iKeyCode, strKey, objInput, regex;  
	isKeyCode = getKeyCode(objEvent); // Obtém Código da Tecla pressionada
	objInput = getSource(objEvent); // Obtém o campo que disparou o evento
	strKey = String.fromCharCode(isKeyCode); // Transforma o código da tecla em um caractere
	
	if(botao){
		if(executaSeEnter(objEvent,botao)){
			return true;
		};
	}
	// Se for tecla de escape, ou de clipboard, deixa passar...
	if(teclasEscape.test(strKey) || checkClipboardCode(objEvent, strKey)){
		return true;
	}
	
	// Cria uma expressão regular para a mascara passada, de acordo com o tamanho atual da entrada
	regex = makeRegEx(mascara,objInput.value.length);
	if (objInput.value.length == 0 || regex.test(objInput.value)) {
		// Se for valida a entrada atual, guardamos seu valor em objInput.validValue
		objInput.validValue = objInput.value;
		
		// Criamos uma nova expressão regular, para ver se o conjunto formado pela 
		// entrada atual + tecla pressionada é válido.
		regex = makeRegEx(mascara,objInput.value.length + 1);
		if (!regex.test(objInput.value + strKey)) {
			
			/* Se não for válido, verificamos se auxiliamos o usuário na formatação
			 inserindo automaticamente caracteres vindos da formatação como uma "/" para
			 formatos de data, ou um "-" em outros casos 	 */
			var carac = mascara.charAt(objInput.value.length);
			if(carac != "#" && carac != "@"){
				while(carac != "#" && carac != "@" && mascara.length > objInput.value.length){
					objInput.value = objInput.value + mascara.charAt(objInput.value.length);
					carac = mascara.charAt(objInput.value.length);
				}
				
				// Depois de auxiliar a insercao dos caracteres de formato, verificamos novamente o conjunto
				regex = makeRegEx(mascara,objInput.value.length + 1);
				if (regex.test(objInput.value + strKey)){
					// Se for valido, guardamos o valor valido, e deixamos passar a entrada.
					objInput.validValue = objInput.value;
					return true;
				}
			}
			return false;
		}
	}
	else {
		// Se o valor atual por algum motivo nao for valido, retorna para o ultimo valor valido armazenado
		objInput.value = (objInput.validValue) ? objInput.validValue : "";
		return false;
	}
	return true;
}

/**
*	Funcao que protege o formato da mascara passado mesmo em casos
*	de Ctrl + V por exemplo.
*	Uso: onchange="maskChange(event)"
*/
function maskChange(objEvent,mascara) {
	if(!mascara) return true; // Se nao passar mascara, aceita tudo
  	var objInput = getSource(objEvent);
	var regex = makeRegEx(mascara,objInput.value.length);
  	if (objInput.value.length != 0 && !regex.test(objInput.value)) {
		objInput.value = (objInput.validValue) ? objInput.validValue : "";
		objInput.focus();
	   	objInput.select(); 
 	}
	else objInput.validValue = objInput.value;
}

/**
*	Recebe um evento, a expressao regular para o caractere digitado e a expressao regular
*	para o valor do campo como um todo. Com isso, bloqueia ou não o que foi digitado
*/
function checkKeyPress(objEvent,regExpString,regExpChar){
	var iKeyCode, strKey, objInput, regex;  
	isKeyCode = getKeyCode(objEvent); // Obtém Código da Tecla pressionada
	objInput = getSource(objEvent); // Obtém o campo que disparou o evento
	strKey = String.fromCharCode(isKeyCode); // Transforma o código da tecla em um caractere
	if (regExpString.test(objInput.value) || objInput.value == "") {
		objInput.validValue = objInput.value;
		if(teclasEscape.test(strKey) || checkClipboardCode(objEvent, strKey)) return true;
		if (!regExpChar || !regExpChar.test(strKey)){
			// Verifica se o conjunto é aceito
			if(regExpString.test(objInput.value + strKey)){
				return true;
			}
			return false;
		}
	}
	else {
		objInput.value = (objInput.validValue) ? objInput.validValue : "";
		return false;
	}
	
	// Nunca chega aki =P
	return true;
}

/**
*	Função que garante integridade do campo em caso de Ctrl + V por exemplo
*/
function checkChange(objEvent,regExpString){
	var objInput = getSource(objEvent);
	if (!regExpString.test(objInput.value)) {
		objInput.value = (objInput.validValue) ? objInput.validValue : "";
		objInput.focus();
		objInput.select(); 
	}
	else{
		objInput.validValue = objInput.value;
	}
}

/**
*	Funcionalidade existente apenas no Internet Explorer, mas também não
*	é usada no Motion pois no struts não tem o atributo "onpaste="algumacoisa""
*	na taglib de html:text
*	uso: onpaste="return checkPaste(event,new RegExp('^\d$'))"
*/
function checkPaste(objEvent,regExpString) {
	var strPasteData = window.clipboardData.getData("Text");
	var objInput = objEvent.srcElement;
	if (!regExpString.test(strPasteData)) {
		objInput.focus();
		return false;
	}
	return true;
}

function filtroKeyPress(objEvent,combo) {
	var objInput = getSource(objEvent);
	strKey = String.fromCharCode(getKeyCode(objEvent));
	if(teclasEscape.test(strKey) || checkClipboardCode(objEvent, strKey)) return true;
	var regex = new RegExp("^" + objInput.value + strKey,"i");
    for (var i=0; i < combo.options.length; i++) {
		if(regex.test(combo.options[i].text)){
			combo.options[i].selected = true;
			objInput.validValue = objInput.value + strKey;
			return true;
		}
	}
	regex.compile("^" + objInput.value,"i");
	for (var i=0; i < combo.options.length; i++) {
		if(regex.test(combo.options[i].text)){
			combo.options[i].selected = true;
			objInput.validValue = objInput.value;
			return false;
		}
	}
	if(!objInput.validValue) objInput.validValue = "";
	return false;
}

function filtroChange(objEvent,combo){
	objInput = getSource(objEvent);
	if(!objInput.validValue) objInput.validValue = "";
	if(trim(objInput.value).length == 0){
		objInput.validValue = "";
		combo.options[0].selected = true;
	}
	var regex = new RegExp("^" + objInput.value, "i");
	for (var i=0; i < combo.options.length; i++) {
		if(regex.test(combo.options[i].text)){
			combo.options[i].selected = true;
			objInput.validValue = objInput.value;
			return;
		}
	}
  	if (!regex.test(objInput.validValue)) {
		objInput.value = objInput.validValue;
		objInput.focus();
		objInput.select(); 
 	}
}

/**	Funcao utilizada para teclas de atalho
*	Recebe o evento e um mapeamento, procura qual botão está associado 
*	a combinação das teclas acionadas, e se houver, simula o click do botão
*/
function hotKey(objEvent,mapeamento){
	var isKeyCode = getKeyCode(objEvent);
    var isShiftPressed = objEvent.shiftKey;
    var isCtrlPressed  = objEvent.ctrlKey;
    var isAltPressed   = objEvent.altKey;
    
    // Enter(13), Shift(16), Ctrl(17), Alt(18), CapsLock(20) keys?
    if (isKeyCode >= 13 && isKeyCode <= 20) return true;
	
	var nome_ou_idBotao = findKeyMap(isKeyCode,isShiftPressed,isCtrlPressed,isAltPressed,mapeamento);
	if(nome_ou_idBotao) {	//var botao = eval("document.forms[0]." + nomeBotao);
		var botao = null;
		botao = document.forms[0].elements[nome_ou_idBotao];
		// Se nao encontrou pelo nome ... procura pelo id
		if(!botao)	botao = document.getElementById(nome_ou_idBotao);
		if(botao)	botao.click();
	}
}

/**	Função que recebe um mapa, e as teclas precionadas e retorna o botão
*	que deve ser executado para aquela combinação de teclas
*/
function findKeyMap (keycode, shift, ctrl, alt,mapa) {
	for (var i = 0; i < mapa.length; i++)
		if (mapa[i].keyCode  == keycode && mapa[i].shift == shift
            && mapa[i].ctrl  == ctrl	&& mapa[i].alt   == alt)
               if (mapa[i].isMapped) return mapa[i].acao;
}

function IPKeyPress(objEvent){
	//var reDigitoChar = /[a-z&&[\d]]/;	// Expressao regular pra validar um caractere com numero 
	var reIPString = /^(\d\d{0,2}([\.](\d\d{0,2}([\.](\d\d{0,2}([\.]\d{0,3})?)?)?)?)?)?$/;	// Expressao regular pra validar IP
	return checkKeyPress(objEvent,reIPString);
}

function IPChange(objEvent){
	var reIPString = /^(\d\d{0,2}([\.](\d\d{0,2}([\.](\d\d{0,2}([\.]\d{0,3})?)?)?)?)?)?$/;	// Expressao regular pra validar IP
	checkChange(objEvent,reIPString);
}