/*
	Utilizacao:
	- Dentro da tag HEAD
		<script language="javascript" src="caminho/mascara.js"></script>
		<script language="javascript">
			function startMasks(){	
				var arrControl = new Array (new Array("nomecampo1", "mascara1"[, "nomeform"[, aceitaEspacos]]),
				                            new Array("nomecampo2", "mascara2"[, "nomeform"[, aceitaEspacos]]),
											(...)
											new Array("nomecampon", "mascaran"[, "nomeform"[, aceitaEspacos]]));
				maskStartup("nomeform", arrControl);
			}
		</script>
	- Na tag BODY
		<body onload="startMasks()">

	Para definir a mascara:
	- Zeros na mascara permitirão que sejam digitados numeros.
	- Letras "X" permitirão a digitação de letras.
	- Qualquer outro caractere sera considerado como parte fixa do valor.

	Exemplos de mascaras:
	- Data: 00/00/0000
	- CPF: 000.000.000-00
	- Placa de veiculo: XXX-0000
	- Fone (com DDD): (00) 0000-0000
    - Cnpj: 00.000.000/0000-00 
	Observacoes:
	- A propriedade maxlength do controle nao devera ser informada.

	Criado por:
	Jefferson Neves em 23/06/2004 e
	Geison M. Santos em 23/06/2004

*/
/**
* Constantes para os valores das teclas de navegacao.
*/
// teclas de navegacao
var VK_INS   = 45;
var VK_DEL   = 46;
var VK_HOME  = 36;
var VK_END   = 35;
var VK_PGUP  = 33;
var VK_PGDN  = 34;
var VK_LEFT  = 37;
var VK_UP    = 38;
var VK_RIGHT = 39;
var VK_DOWN  = 40;
var VK_BKSP  = 8;
var VK_TAB   = 9;
var VK_ENTER = 13;

// teclas de funcao
var VK_F1  = 112;
var VK_F2  = 113;
var VK_F3  = 114;
var VK_F4  = 115;
var VK_F5  = 116;
var VK_F6  = 117;
var VK_F7  = 118;
var VK_F8  = 119;
var VK_F9  = 120;
var VK_F10 = 121;
var VK_F11 = 122;
var VK_F12 = 123;

// teclas modificadores
var VK_SHIFT = 16;
var VK_CTRL  = 17;
var VK_ALT   = 0;

/**
* Array contendo as mascaras.
*/
var _maskedFields = new Array();

/*
* Nome do form
*/
var _formName;

/**
* Caractere usado para preechimento da mascara.
*/
var blankChar;

/**
* Caractere representativo de numeros na mascara
*/
var numberChar;

/**
* Caractere representativo de letras na mascara
*/
var charChar;

/**
* Browser utilizado
*/
var _browser;

/* Inicializacao */
/**
* Inicializa mascaras.
*/
function maskStartup(formName, arrMasks){
	_maskedFields = arrMasks;
	_formName     = formName;
	blankChar     = '_';
	numberChar    = '0';
	charChar      = 'X';

	_browser = detectBrowser();

	if (_browser == 'GK' || _browser == 'IE'){
		setupFormKeyPress(formName);
		adjustMasks(formName);
		resetMaskedFields("");
	}
}

/**
* Captura o evento OnKeyPress do formulario
*/
function setupFormKeyPress(formName) {
	targetEl = document.forms[formName];

	targetEl.onkeypress = masking;

	// limpa a propriedade maxlength do controle
	targetEl.maxlength  = null;

	if (_browser == 'IE'){ // IE
		// se for IE tem que capturar o evento
		// keydown tambem, para poder tratar as teclas
		// backspace e del.
		targetEl.onkeydown  = masking;
	}
}

/**
* Ajusta os arrays contendo as mascaras para utilizar o form default caso nao tenha sido informado.
*/
function adjustMasks(frm){
	for(var i=0; i<_maskedFields.length; i++){
		if (_maskedFields[i][2] == null){
			_maskedFields[i][2] = frm;
		}
		if (_maskedFields[i][3] == null){
			_maskedFields[i][3] = false;
		}
	}
}

/**
* Limpa os campos que possuem mascara
*/
function resetMaskedFields(fld){
	var regEx = new RegExp('['+numberChar+charChar+']', 'gi');

	if(fld == ''){
		for(var x = 0; x < _maskedFields.length; x++){
			obj = document.forms[_maskedFields[x][2]].elements[_maskedFields[x][0]];
			if (obj.value == ""){
				obj.value = _maskedFields[x][1].replace(regEx, blankChar);
			}
		}
	} else {
		obj = document.forms[_formName].elements[fld];
		x = fieldIsInArray(fld);
		if (x != -1){
			obj.value = _maskedFields[x][1].replace(regEx, blankChar);
		}
	}
}
/* FIM Inicializacao*/

/* Execucao */
/**
* Executa a mascara.
*/
function masking(ev){
	if(!ev) {
		ev = window.event; //IE
	}

	theField = (ev.srcElement)? ev.srcElement: ev.target;

	fieldName = theField.name;

	// verifica se o campo possui mascara...
	inputIndex = fieldIsInArray(fieldName);
	if (inputIndex == -1){
		return true;
	}

	// no IE as teclas backspace e del nao acionam o
	// evento keypress, já no gecko sim.
	// no IE o codigo da tecla pressionada vem sempre 
	// em event.keyCode
	// no gecko se for um simbolo(letras, numeros...) vem:
	// event.keyCode = 0 e event.charCode = <codigo da tecla>
	// se for tecla especial (bksp, del, setas...) vem:
	// event.keyCode = <codigo da tecla> e event.charCode = 0
	if (_browser == 'GK'){ // Gecko
		// primeiro saber se é tecla especial
		if (ev.charCode == 0){
			teclaPressionada = ev.keyCode;
		} else {
			teclaPressionada = ev.charCode;
		}
	} else { //IE
		teclaPressionada = ev.keyCode;
	}

	// as teclas normais no IE tambem acionam o evento keydown
	// entao para evitar a chamada do evento em duplicata
	// quando o evento for keydown e nao forem as teclas
	// backspace ou del cancelar o evento.
	if (_browser == 'IE' && ev.type == 'keydown'){
		if (teclaPressionada != VK_BKSP && teclaPressionada != VK_DEL){
			ev.returnValue = true;
			return;
		} else {
			ev.returnValue = false;
		}
	}

	// se nao forem as teclas backspace(8) ou del(46)
	// processa a tecla digitada, 
	if (teclaPressionada != VK_BKSP && teclaPressionada != VK_DEL){
		keyPressed = String.fromCharCode(teclaPressionada);
	} else {
		keyPressed = blankChar;
	}
	
	// no Gecko as teclas de setas e backspace tambem acionam o
	// evento keypress, nesse caso retornar true...
	switch (teclaPressionada){
		case [VK_F1.VK_F12]:
		case VK_INS  :
		case VK_HOME :
		case VK_END  :
		case VK_PGUP :
		case VK_PGDN :
		case VK_LEFT :
		case VK_UP   :
		case VK_RIGHT:
		case VK_DOWN :
		case VK_TAB  :
		case VK_ENTER:
			return true;
		break;
	default:
		if(_browser == 'IE'){ // IE
			ev.keyCode = 0;

		} else { // Gecko
			ev.preventDefault();
		}
	}

	// busca a posicao do cursor aonde deve ser inserida a tecla.
	pos = getCaretPos(theField);
	sel = getSelectedText(theField);

	if (teclaPressionada == VK_BKSP && sel.length <= 1){  // se foi pressionado backspace voltar a posicao um elemento para tras...
		if (pos > 0){
			pos--;
		}
	}

	add = testKey(keyPressed, pos, inputIndex, sel);

	addStr = add[0];
	addSz  = add[1];

	theField.value = theField.value.substring(0, pos)+addStr+theField.value.substring(pos+addStr.length);

	if (teclaPressionada == VK_BKSP || teclaPressionada == VK_DEL){
		moveCaretTo(theField, pos);
	} else {
		moveCaretTo(theField, pos+addSz);
	}

	return false;
}

/**
* Verifica se a tecla pressionada e valida para aquela posicao.
*/
function testKey(key, pos, field, sel){
	startPos  = pos;                     // posicao inicial do cursor
	selSz     = sel.length;              // tamanho do texto selecionado
	theMask   = _maskedFields[field][1]; // Busca a mascara
	maskSz    = theMask.length;          // tamanho da mascara
	returnKey = '';                      // valor retornado
	moved     = 0;                       // quantidade de carcteres que o cursor deve avancar

	// ER's para validar os caracteres digitados
	regEx = new Array();
	regEx[numberChar] = new RegExp('[0-9'+blankChar+']'   , 'gi');

	if(_maskedFields[field][3]){
		regEx[charChar] = new RegExp('[a-zA-Z '+blankChar+']', 'gi');
	} else {
		regEx[charChar] = new RegExp('[a-zA-Z'+blankChar+']', 'gi');
	}	

	maskChar  = theMask.charAt(pos);     // caractere da mascara na posicao digitada.
	while(!isMaskChar(maskChar) && pos < maskSz){
		returnKey += maskChar;
		maskChar   = theMask.charAt(++pos);
	}

	if(pos < maskSz && regEx[maskChar].test(key)){
		returnKey += key;
	}

	// conta quantos caracteres o cursor deve se mover,
	// sem levar em conta os caracteres extras de formatacao que serao adicionados.
	moved = returnKey.length;

	if ((moved < selSz)){
		for (var i = moved; i < selSz; i++){
			if (isMaskChar(theMask.charAt(startPos+i))){
				returnKey += blankChar;
			} else {
				returnKey += theMask.charAt(startPos+i);
			}
		}
	}

	return new Array(returnKey, moved);
}
/* FIM Execucao */

/* Finalizacao*/
/**
* Destroi as mascaras dos campos e disabilita os keypress
*/
function destroyMask() {
	document.forms[_formName].onkeydown  = null;
	document.forms[_formName].onkeypress = null;

	for(var x = 0; x < _maskedFields.length; x++){
		obj = document.forms[_maskedFields[x][2]].elements[_maskedFields[x][0]];
		obj.value = "";
	}
}
/* FIM Finalizacao*/

/* Funcoes de apoio */
/**
* Verifica se o campo possui uma mascara.
*/
function fieldIsInArray(fld){
	var retVal = -1;

	for (var y=0; y < _maskedFields.length; y++) {
		if (_maskedFields[y][0] == fld) {
			retVal = y;
			break;
		}
	}
	return retVal
}

/**
* Retorna a posicao do cursor.
*/
function getCaretPos(elem){
	if (_browser == 'GK'){
		// Gecko
		caretPos = elem.selectionStart;

	} else if (_browser == 'IE'){
		// IE
		range = document.selection.createRange().duplicate();
		caretPos = (-1)*(range.move('character', -1000));
	}
	return caretPos;
}

/**
* Retorna o texto atualmente selecionado.
*/
function getSelectedText(elem){
	if (_browser == 'GK'){
		// Gecko
		selSize = elem.selectionEnd - elem.selectionStart;
		// se nao tiver nenhum texto selecionado, seleciona o proximo caractere.
		if (selSize == 0){
			selSize = 1;
		}
		selText = elem.value.substr(elem.selectionStart, selSize);

	} else if (_browser == 'IE'){
		// IE
		selSize = document.selection.createRange().duplicate();
		// se nao tiver nenhum texto selecionado, seleciona o proximo caractere.
		if (selSize == 0){
			selSize = 1;
		}
		selText = selSize.text;
	}
	return selText;
}

/**
* Verifica se o caracter e fixo na mascara.
*/
function isMaskChar(charac){
	return (charac == numberChar || charac == charChar || charac == blankChar);
}

/**
* Move o cursor para a proxima posicao a ser digitada.
*/
function moveCaretTo(field, pos){
  if (_browser == 'GK') {
    field.focus();
    field.setSelectionRange(pos, pos);

  } else if (_browser == 'IE') {
    var range = field.createTextRange();

    range.collapse(true);
    range.moveEnd('character', pos);
    range.moveStart('character', pos);
    range.select();
  }
}

/**
* Detecta qual o browser utilizado
*/
function detectBrowser(){
	var agente = navigator.userAgent.toLowerCase();

	isOpr = (agente.indexOf('opera'   ) != -1);
	isNN  = (agente.indexOf('netscape') != -1);
	isFF  = (agente.indexOf('firefox' ) != -1);
	isMoz = (agente.indexOf('gecko'   ) != -1 && !isNN && !isFF);
	isIE  = (agente.indexOf('msie'    ) != -1 && !isOpr);

	if(isOpr)                      { 
		return 'OP'; // Opera
	} else if(isNN || isFF|| isMoz){ 
		return 'GK'; // browsers com 'motor' Gecko
	} else if(isIE)                { 
		return 'IE'; // Internet Explorer
	} else                         { 
		return 'OU'; // Outros
	}
}
/* FIM Funcoes de apoio */

function SomenteNumero(e)
{
    var tecla=(window.event)?event.keyCode:e.which;
    if((tecla > 47 && tecla < 58)) 
        return true;
    else
    {
    if (tecla != 8) 
        return false;
    else 
        return true;
    }
}
