/************************/
/* Autor: Felipe Jaekel */
/********************************************************/
/* Classe para realizar validações de entrada de dados  */
/********************************************************/

var valida =
{
	//Atributo para armazenar expressões regulares
	regex: '',

	//Atributo para armazenar mensagens de erro
	erro: '',

	/*********************************************************************
	 Protótipo: valida.telefone(campo)
	 Função...: verifica se o telefone digitado é válido
	 Entrada..: identidade do campo que contém a string a ser validada
	 Saída....: true|false
	**********************************************************************/
	telefone: function(campo)
	{
		this.regex = /^\d{2} \d{3,4}-\d{4}$/;

		return field(campo).value.match(this.regex);
	},

	//Para tornar a função abrangente, ela retorna apenas true|false. Para exibição de uma mensagem foi criado este atributo
	formatoTelefone: 'Telefone deve ser escrito no seguinte formato: \n\n' +
	 					  'DDD(dois dígitos) + ' +
	 					  'um espaço em branco + ' +
	 					  'três ou quatro dígitos + ' +
	 					  'um hífen(-) + ' +
	 					  'quatro dígitos \n\n' +
	 					  'Exemplo: 31 3399-2500',

	/*********************************************************************
	 Protótipo: valida.isPHPerror(str) OBSOLETA(mantida para compatibilidade), usar valida.isJSON()
	 Função...: verifica, ao usar o tookit dojo, se foi ouve algum erro ou warning do PHP
	 Entrada..: string a ser validada
	 Saída....: true|false
	**********************************************************************/	
	isPHPerror: function(str)
	{
		//Verifica se é uma mensagem de erro de debug ou do PHP e não é uma mensagem de erro SQL produzida por DB::execSQL(), que é utilizada em instruções insert, update e delete
		return (str.match(/(error)|(warning)/i) && !str.match(/(insert)|(update)|(delete)/i));
	},

	/*********************************************************************
	 Protótipo: valida.isJSON(str)
	 Função...: verifica, ao usar o tookit dojo, se o conteúdo retornado é uma string JSON
	 Entrada..: string a ser validada
	 Saída....: true|false
	**********************************************************************/	
	isJSON: function(str)
	{
		//Exemplo de JSON: {"__className": "dojoIO", "msgSucesso" : "", "msgConfirma" : "", "retorno" : "", "msgErro" : ["Método inválido"]}
		return (str.match(/^\{.*\}$/));
	},	

	/*********************************************************************
	 Protótipo: valida.digit(campo, tipo), valida.alpha(campo), valida.alNum(campo), multipleEmail(campo)
	 Função...: bloqueiam a digitação de caracteres inválidos
	 	->Referência dos eventos usados associados as funções
			onkeyup:
	  		  -captura qualquer tecla digitada. Como o evento é assionado quando a tecla é solta
	  		  -captura também quando a tecla é pressionada e segurada
	  		onchange:
	  		  -complementa o evento acima, capturando CTRL + V, texto colado com o mouse, etc
	 Entrada..: identidade do campo que contém a string a ser validada. A função digit é condicionada de acordo com o argumento tipo
	 Saída....: removem o caracter inválido no instante em que é digitado
	**********************************************************************/		
	//Apenas números
	digit: function(campo, tipo)
	{
		switch(tipo)
		{
			case 'float':
			{
				this.regex = /[^0-9,.]/g;
				break;
			}			
			case 'data':
			{
				this.regex = /[^0-9\/]/g;
				break;
			}
			case 'cep':
			{
				this.regex = /[^0-9\-]/g;
				break;
			}
			case 'cpf':
			{
				this.regex = /[^0-9\.\-]/g;
				break;
			}
			case 'cnpj':
			{
				this.regex = /[^0-9\.\-\/]/g;
				break;
			}
			case 'telefone':
			{
				this.regex = /[^0-9 \-]/g;
				break;
			}
			default:
			{
				this.regex = /[^0-9]/g;
			}
		}

		//Esse teste evita replaces desnecessários e faz com que seja possível usar a tecla seta para trás no IE
		if(campo.value.match(this.regex))
		{
			campo.value = campo.value.replace(this.regex, '');
		}
	},
	//-----------------------------------------------------------------------------
	//Apenas letras e espaços
	alpha: function(campo)
	{
		this.regex = /[^a-z àáâãçéêíóôõúü]/gi;

		if(campo.value.match(this.regex))
		{
			campo.value = campo.value.replace(this.regex, '');
		}
	},
	//-----------------------------------------------------------------------------
	//Apenas letras, números e espaços
	alNum: function(campo)
	{
		this.regex = /[^a-z àáâãçéêíóôõúü0-9]/gi;

		if(campo.value.match(this.regex))
		{
			campo.value = campo.value.replace(this.regex, '');
		}
	},
	//-----------------------------------------------------------------------------
	//Múltiplos emails
	multipleEmail: function(campo)
	{
		this.regex = /[^a-z 0-9@_\.;]/gi;

		if(campo.value.match(this.regex))
		{
			campo.value = campo.value.replace(this.regex, '');
		}
	},	

	/*********************************************************************
	 Protótipo: valida.cookies()
	 Função...: verifica se os cookies estão ativados no navegador do cliente
	 Entrada..: 
	 Saída....: true|false
	**********************************************************************/
	cookies: function()
	{
		var cookieEnabled = (navigator.cookieEnabled);

		if(typeof(navigator.cookieEnabled) == 'undefined' && !cookieEnabled)
		{
			document.cookie = 'testcookie';
			cookieEnabled 	 = (document.cookie.indexOf('testcookie') != -1);
		}

		return cookieEnabled;
	},

	/*********************************************************************
	 Protótipo: valida.empty()
	 Função...: verifica se o valor de um campo ou string esta vazio
	 Entrada..: identidade do campo que contém a string a ser validada | string a ser validada, flag para determinar se é string ou identidade
	 Saída....: true|false
	**********************************************************************/
	empty: function(campo, isNormalStr)
	{
		//Se o argumento passado for a identidade de um campo
		if(!isNormalStr)
		{
			switch(field(campo).type)
			{
				case 'text':
				case 'file':
				case 'hidden':
				case 'textarea':
				case 'password':
				{
					return this.isEmptyStr(field(campo).value);
				}
				case 'select-one':
				case 'select-multiple':
				{
					if(field(campo).selectedIndex == 0 && field(campo).options[field(campo).options.selectedIndex].value == '')
					{
						return (field(campo).selectedIndex == 0);
					}
					else
					{
						return (field(campo).selectedIndex == -1);
					}
				}
				case 'checkbox':
				case 'radio':
				{
					return !field(campo).checked;
				}
				case 'button':
				case 'submit':
				case 'reset':
				{
					//Botões não são editáveis, portanto nada a ser feito
					return false;
				}
				default:
				{
					return true;
				}
			}
		}
		else
		{
			//Se o argumento passado for uma string normal
			return (this.isEmptyStr(campo));
		}
	},
	//-----------------------------------------------------------------------------
	//Função auxiliar de empty
	isEmptyStr: function(str)
	{
		switch(trim(str))
		{
			case '':
			case 0:
			case '0':
			case null:
			case undefined: //assim como null, não é uma string
			case false:
			{
				return true;
			}
			default:
			{
				return false;
			}
		}
	},

	/*********************************************************************
	 Protótipo: valida.data(campo, nomeCampo)
	 Função...: verifica se uma data é válida
	 Entrada..: identidade do campo que contém a string a ser validada(previamente formatada com formata.data() para que substr() funcione corretamente), nome do campo testado para aparecer na mensagem de erro [, ano inicial [, ano final]]
	 Saída....: mensagem de erro
	**********************************************************************/
	data: function(campo, nomeCampo, anoIni, anoFim)
	{
   	anoIni = !anoIni ? 1900 : anoIni;
   	anoFim = !anoFim ? 2100 : anoFim;

		var dia = field(campo).value.substr(0, 2);
		var mes = field(campo).value.substr(3, 2);
		var ano = field(campo).value.substr(6, 4);

		if(!field(campo).value.match(/^\d{2}\/\d{2}\/\d{4}$/))
		{
			//Gera a mensagem de erro apenas se o nome do campo foi informado
			if(nomeCampo)
			{
				this.dataInvalida = '- Data de ' + nomeCampo + ' deve ser digitada no formato dd/mm/aaaa';
			}
			return false;
		}
		else
		{
			if((ano < anoIni) || (ano > anoFim) || (mes < 1) || (mes > 12) || (dia < 1) ||
			((mes == 2) && (dia > 28 + (!(ano % 4)) - (!(ano % 100)) + (!(ano % 400)))) ||
			(dia > 30 + ((mes > 7) ^ (mes & 1))))
			{
				if(nomeCampo)
				{
					this.dataInvalida = '- Data de ' + nomeCampo + ' incorreta';
				}
				return false;
			}
			else
			{
				var data 	  = new Date(ano, mes - 1, dia);
				var dataAtual = new Date();

				if(data.getTime() > dataAtual.getTime())
				{
					if(nomeCampo)
					{
						this.dataInvalida = '- Data de ' + nomeCampo + ' é maior que a data atual';
					}
					return false;
				}
			}
		}
		return true;
	},

	//Atributo auxiliar
	dataInvalida: '',

	/*********************************************************************
	 Protótipo: valida.comparaData(campo1, campo2)
	 Função...: verifica se a primeira data é maior do que a segunda
	 Entrada..: identidade dos campos que contém as strings a serem validadas(previamente formatados com formata.data() para que substr() funcione corretamente)
	 Saída....: true|false
	**********************************************************************/
	comparaData: function(campo1, campo2, isNormalStr)
	{
		if(!isNormalStr)
		{	
			campo1 = field(campo1).value;
			campo2 = field(campo2).value;
		}

		//Converte o mês para número e subtrai 1 porque a faixa de mês do JS é 0-11
		var data1 = new Date(campo1.substr(6, 4), parseInt(campo1.substr(3, 2)) - 1, campo1.substr(0, 2));
		var data2 = new Date(campo2.substr(6, 4), parseInt(campo2.substr(3, 2)) - 1, campo2.substr(0, 2));

		return (data1.getTime() > data2.getTime());
	},

	/*********************************************************************
	 Protótipo: valida.email(campo, isNormalStr)
	 Função...: verifica se o email é válido
	 Entrada..: identidade do campo que contém a string a ser validada | string a ser validada, flag para determinar se é string ou identidade
	 Saída....: true|false
	**********************************************************************/
	email: function(campo, isNormalStr)
	{
		this.regex = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;

		return !isNormalStr ? field(campo).value.match(this.regex) : trim(campo).match(this.regex);
	},

	//-----------------------------------------------------------------------------
	//CPF
	CPF: function()
	{
		var cpf	 = field('edtCPF').value.replace(/\D/g, '');
		var valor = true;

		this.erro = '';

		//Testa se o CPF é 11111111111 ou 22222222222 ...
		if(cpf.match(/^[1-9]{11}$/))
		{
			this.erro = '- CPF inválido';
		}
		else
		{
			var a = Array();
			var b = 0;
			var c = 11;
			for(i = 0; i < 11; i++)
			{
				a[i] = cpf.charAt(i);
				if(i < 9)
				{
					b += (a[i] * --c);
				}
			}
			if((x = b % 11) < 2)
			{
				a[9] = 0;
			}
			else
			{
				a[9] = 11 - x;
			}
			b = 0;
			c = 11;
			for(y = 0; y < 10; y++)
			{
				b += (a[y] * c--);
			}
			if((x = b % 11) < 2)
			{
				a[10] = 0;
			}
			else
			{
				a[10] = 11 - x;
			}
			if((cpf.charAt(9) != a[9]) || (cpf.charAt(10) != a[10]))
			{
				this.erro = '- Digito verificador do CPF com problema';
			}
		}
		return this.erro;
	},

	//-----------------------------------------------------------------------------
	//CNPJ
	CNPJ: function(campo)
	{
		var CNPJ	= field('edtCNPJ').value.replace(/\D/g, '');

		this.erro = '';

		var a = [];
		var b = 0;
		var c = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
		for(i = 0; i < 12; i++)
		{
			a[i] = CNPJ.charAt(i);
			b += a[i] * c[i + 1];
		}
		if((x = b % 11) < 2)
		{
			a[12] = 0;
		}
		else
		{
			a[12] = 11 - x;
		}
		b = 0;
		for(y = 0; y < 13; y++)
		{
			b += (a[y] * c[y]);
		}
		if((x = b % 11) < 2)
		{
			a[13] = 0;
		}
		else
		{
			a[13] = 11 - x;
		}
		if((CNPJ.charAt(12) != a[12]) || (CNPJ.charAt(13) != a[13]))
		{
			this.erro = '- Digito verificador do CNPJ com problema';
		}
		return this.erro;
	}
};