//====================================================
//Valida 1.0
//====================================================
//tipo
//1 - e-mail
//2 - numerico
//3 - nao nulo
//4 - fone
//5 - CEP
//6 - data
//7 - CPF
//8 - CNPJ
//9 - Cartao De Credito *
//====================================================
//Corpo exemplo para cartão de credito
/*
<table width="30%" border="0" cellpadding="2" cellspacing="0" id="tbcartao">
              <tr>
                <td width="45%"><font color="#FF6600" size="1" face="Verdana, Arial, Helvetica, sans-serif"><strong>Tipo:</strong></font></td>
                <td width="55%" align="right"><select name="tipo_cartao" class="form" id="tipo_cartao">
                    <option value="0" selected>Selecione</option>
                    <option value="1">Master Card</option>
                    <option value="2">Visa</option>
                    <option value="3">Amex</option>
                    <option value="4">Diners</option>
                </select></td>
              </tr>
              <tr>
                <td><font color="#FF6600" size="1" face="Verdana, Arial, Helvetica, sans-serif"><strong>N&uacute;mero:</strong></font></td>
                <td align="right"><input name="numero" type="text" class="form" id="numero" size="16" maxlength="16"></td>
              </tr>
              <tr>
                <td><font color="#FF6600" size="1" face="Verdana, Arial, Helvetica, sans-serif"><strong>Validade</strong></font></td>
                <td align="right"><input name="validade_mes" type="text" class="form" id="mes2" size="2" maxlength="2">
      /
        <input name="validade_ano" type="text" class="form" id="ano2" size="2" maxlength="2"></td>
              </tr>
              <tr>
                <td><font color="#FF6600" size="1" face="Verdana, Arial, Helvetica, sans-serif"><strong>C&oacute;digo de valida&ccedil;&atilde;o:</strong></font></td>
                <td align="right"><font color="#FF6600" size="1" face="Verdana, Arial, Helvetica, sans-serif"><strong>
                  <input name="cod_validacao" type="text" id="validador2" size="4" maxlength="4" class="form">
                </strong></font></td>
              </tr>
            </table>
*/
//campot
//1 - text
//2 - select-one
//3 - select-multiple**
//4 - radio
//5 - checkbox**
// Observeções
// * Para validar corretamente os tipos de cartão de credito é preciso configurar 
// - os campos do cartão usando.
// configCartao( tipo_cartao , numero , validade_ano , validade_mes , cod_validacao ),
// - adicionar os tipos de cartão 
// addTipoCartao(tipo)
// = tipos =
// 1 - Visa
// 2 - MasterCard
// 3 - Diners
// 4 - Amex (American Express)
// para a validação de cartoes o 0 (zero) no combo com os tipos é adotado como um valor nulo tipo 'Selecione'
// ** estes campos usam o seu tipo para determinar o tipo de validacao
// x < 0 - pelo menos x : permiteque o usuário escolha 0
// x >= 1000 - exatamente x
// x = 0 - pelo menos 1 
// 0 > x < 1000 - no maximo x

var htcValidationType = 'standard';
function htcValida(aviso){
	
	var motivo;
	
	this.aviso = aviso;
	this.labelErro = '';
	this.campos = new Array();
	this.tipo = new Array();
	this.campot = new Array();
	this.mens = new Array();
	this.cartao = new Array();
	this.cleanOnValid = new Array();
	this.addCampo = addCampo;
	this.isMail = isMail;
	this.isNumeric = isNumeric;
	this.isNotNull = isNotNull;
	this.isFone = isFone;
	this.isCEP = isCEP;
	this.isDate = isDate;
	this.isCPF = isCPF;
	this.isCNPJ = isCNPJ;
	this.isCrediCard = isCrediCard;
	this.addTipoCartao = addTipoCartao;
	this.configCartao = configCartao;
	this.tipo_cartao = '';
	this.numero = '';
	this.validade_ano = '';
	this.validade_mes = '';
	this.cod_validacao = '';
	this.isValid = validaTudo;
	this.trim = trim;
	this.tipoC = tipoCampo;
	
}

function addCampo(obj,tipo,men,cam,clr){
	if(obj){
		this.campos[this.campos.length] = obj;
		this.tipo[this.tipo.length] 	= tipo;	
		this.mens[this.mens.length] 	= men;
		this.campot[this.campot.length] = cam;
		if(clr)
			this.cleanOnValid.push(obj);
	}else{
		alert('Campo ' + men + ', não encontrado');
	}

}

function validaTudo(){
	var a,men;
	men = '';
	
	for(a=0;a<this.campos.length;a++){
		
		//variavel para algumas validações
		var tobj = this.campos[a];
		//alert(this.campos[a].value + '\n' + this.tipo[a] + '\n' + this.campot[a]);
		//alert(a);
		switch(this.campot[a]){
			case 1: //Texto
			switch(this.tipo[a]){
				case 1://1 - e-mail
					(isMail(this.campos[a]))?true:men = men + this.mens[a];
					(isMail(this.campos[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 2://2 - numerico
					(!isNaN(this.campos[a].value) && trim(this.campos[a]).length > 0)?true:men = men + this.mens[a];
					(!isNaN(this.campos[a].value) && trim(this.campos[a]).length > 0)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 3://3 - nao nulo
					(isNotNull(this.campos[a]))?true:men = men + this.mens[a];
					(isNotNull(this.campos[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 4://4 - fone
					(isFone(this.campos[a]))?true:men = men + this.mens[a];
					(isFone(this.campos[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 5://5 - CEP
					(isCEP(this.campos[a]))?true:men = men + this.mens[a];
					(isCEP(this.campos[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 6://6 - Date
					(isDate(this.campos[a],1))?true:men = men + this.mens[a];
					(isDate(this.campos[a],1))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 7://7 - CPF
					(isCPF(this.campos[a]))?true:men = men + this.mens[a];
					(isCPF(this.campos[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 8://8 - CNPJ
					(isCNPJ(this.campos[a]))?true:men = men + this.mens[a];
					(isCNPJ(this.campos[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
				case 9://9 - Cartao de Credito
					(isCrediCard(this.tipo_cartao,this.numero,this.validade_ano,this.validade_mes,this.cod_validacao))?true:men = men + this.mens[a] + ' ( ' + motivo + ' ) ';
					(isCrediCard(this.tipo_cartao,this.numero,this.validade_ano,this.validade_mes,this.cod_validacao))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
					break;
			}
			break;

			case 2:
				try{
					(parseInt(this.campos[a].options[this.campos[a].selectedIndex].value) != 0)?true:men = men + this.mens[a];
					(parseInt(this.campos[a].options[this.campos[a].selectedIndex].value) != 0)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}catch(e){
					men = men + this.mens[a];
				}
				break;
			
			case 3:
				var slok = 0;
				for(b=0;b<tobj.length;b++){
					if(tobj.options[b].selected)
						slok++;
				}

				if(this.tipo[a] == 0){ // a vontado - pelo menos 1
					(slok >= 1)?true:men = men + this.mens[a];
					(slok >= 1)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}else if(this.tipo[a] < 0){ //no minimo - pelo menos n
					(slok >= Math.abs(this.tipo[a]))?true:men = men + this.mens[a] + ' (escolha pelo menos ' + Math.abs(this.tipo[a]) + ')';
					(slok >= Math.abs(this.tipo[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}else if(this.tipo[a] >= 1000){//exatamente
					(slok == (this.tipo[a] / 1000))?true:men = men + this.mens[a] + ' (escolha somente ' + (this.tipo[a] / 1000) + ')';
					(slok == (this.tipo[a] / 1000))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}else{ //maximo
					(slok <= this.tipo[a] && slok > 0)?true:men = men + this.mens[a] + ' (escolha no máximo ' + this.tipo[a] + ' e no minimo 1)';
					(slok <= this.tipo[a] && slok > 0)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}
				break;
			
			case 4:
				var rdok = 0;
				for(b=0;b<tobj.length;b++){
					if(tobj[b].checked)
						rdok++;
				}
				(rdok == 1)?true:men = men + this.mens[a];
				(rdok == 1)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				break;
			
			case 5:
				var chok = 0;
				for(b=0;b<tobj.length;b++){
					if(tobj[b].checked)
						chok++;
				}
				if(this.tipo[a] == 0){ // a vontado - pelo menos 1
					(chok >= 1)?true:men = men + this.mens[a];
					(chok >= 1)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}else if(this.tipo[a] < 0){ //no minimo - pelo menos n
					(chok >= Math.abs(this.tipo[a]))?true:men = men + this.mens[a] + ' (escolha pelo menos ' + Math.abs(this.tipo[a]) + ')';
					(chok >= Math.abs(this.tipo[a]))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}else if(this.tipo[a] >= 1000){//exatamente
					(chok == (this.tipo[a] / 1000))?true:men = men + this.mens[a] + ' (escolha somente ' + (this.tipo[a] / 1000) + ')';
					(chok == (this.tipo[a] / 1000))?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}else{ //maximo
					(chok <= this.tipo[a] && chok > 0)?true:men = men + this.mens[a] + ' (escolha no máximo '+ this.tipo[a] +' e no minimo 1)';
					(chok <= this.tipo[a] && chok > 0)?erroCampo(this.campos[a],false):erroCampo(this.campos[a],true);
				}
				break;			
		}
		
	}
	
	if(men == ''){
		for(var j = 0;j < this.cleanOnValid.length;j++)
			this.cleanOnValid[j].value = clearSpecial(this.cleanOnValid[j].value);
			
		return true;
	}else{
		try{
			if(htcValidationType == 'form'){
				eval(this.labelErro).innerHTML = this.aviso;
			}else{
				alert(this.aviso + men);
			}
		}catch(e){
			status = e.description;
		}
		return false;
	}
	
}

function erroCampo(campo,erro){
	try{
		if(htcValidationType == 'form'){
			node = campo.parentNode;
			flag = true;
			while(flag){
				if(node.tagName == 'TD'){
					if(node.id != 'no'){
						node = node.previousSibling;
						flag = false;
					}else{
						node = node.previousSibling;
					}
				}else{
					node = node.parentNode;
				}
			}

			if(erro)
				node.className = 'afErro';
			else
				node.className = 'afLabel';	
		}
	}catch(e){
		status = 'Validacao - ' + e.description;
	}
}

function isNotNull(obj){
	if(trim(obj).length > 0)
		return true;
	else
		return false;
}


function isMail(obj){
	
	tipoCampo(obj);
	
	if(trim(obj).length > 0){
		
		var validam = 0;
		(obj.value.indexOf(".") <= 0)?validam = 1:true;
		(obj.value.indexOf(".") == (obj.value.length - 1))?validam = 1:true;
		(obj.value.indexOf("@") <= 0)?validam = 1:true;
		(obj.value.indexOf("@") == (obj.value.length - 1))?validam = 1:true;
		(obj.value.indexOf(".",obj.value.indexOf("@")) < obj.value.indexOf("@"))?validam = 1:true;
		(obj.value.indexOf(".",obj.value.indexOf("@")) == (obj.value.length - 1))?validam = 1:true;
		(obj.value.indexOf("@.") > 0)?validam = 1:true;
		(obj.value.indexOf(".@") > 0)?validam = 1:true;
		(obj.value.indexOf(" ") > 0)?validam = 1:true;
		//alert((validam == 1));
		if(validam == 1)
			return false;
		else
			return true;
	}
	else{
		return false;
	}
}

function isCEP(obj){
	var txt = clearSpecial(obj.value);
	if(txt.length >= 8 && txt.length <= 9)
		return !isNaN(txt);
	else
		return false;
}

function isFone(obj){
	var txt = clearSpecial(obj.value);
	if(txt.length >= 7 && txt.length <= 12)
		return !isNaN(txt);
	else
		return false;
}

function isNumeric(obj,t){
	
	if ( obj.value != '' ) {
		var i;
		var dif = 0;
		for (i = 0; i < obj.value.length; i++){
			var c = obj.value.charAt(i);
			switch(t){
				case 0:
					if (!((c >= '0') && (c <= '9'))){
						dif = 1;
					}
					break;
				case 1: //Data
					if (!((c >= '0') && (c <= '9') || (c == '/')) ){
						dif = 1;
					}
					break;
				case 2: // CEP - Fone
					if (!((c >= '0') && (c <= '9') || (c == '-')) ){
						dif = 1;
					}
					break;
			}
		
		}
		if (dif == 1){
			return false;
		}
		else{
			return true;
		}
	}
	return false;
}

//*******************************************
//Valida data
//parametros : 
// valor : string
// tipo : 1 - dd/mm/aaaa ; 2 - dd/mm/aa
//retorno : true/false
//descricao : Valida as datas mesmo para anos 
//bixestos
//*******************************************

function isDate(obj,tipo){


	//limite de caracteres
	if(tipo == 1){
		maxc = 10;
	}
	else{
		maxc = 8;
	}

	if(obj.value.length < maxc || obj.value.length > maxc){
		return false;
	}
	else{

		var b1 = obj.value.substring(2,3);
		var b2 = obj.value.substring(5,6);
		var dia = obj.value.substring(0,2);
		var mes = obj.value.substring(3,5);
		var erro = 0;

		if(dia <= 0){
			return false;
		}

		if(tipo == 1)
			var ano = obj.value.substring(6,10);
		else
			var ano = obj.value.substring(6,8);		

		if(!isNumericString(dia,0)){
			return false;
		}
		if(!isNumericString(mes,0)){
			return false;
		}		
		if(!isNumericString(ano,0)){
			return false;
		}

		//ano bixesto para limite dos dias em fevereiro
		if((ano%4) == 0 && (ano%100) != 0 || (ano%400) == 0)
			lfev = 29;
		else
			lfev = 28;

		//alert(parseInt(mes) + ' ' + mes);

		switch(mes){
			case '01':
			case '03':
			case '05':
			case '07':
			case '08':
			case '10':
			case '12': //31 dias
				(parseInt(dia) > 31)?erro = 1:erro = 0;
				break;
			case '04':
			case '06':
			case '09':
			case '11': //30 dias
				(parseInt(dia) > 30)?erro = 1:erro = 0;
				break;
			case '02': // fevereiro
				(parseInt(dia) > lfev)?erro = 1:erro = 0;
				break;
			default :
				erro = 1;
				break;
		}

		if(erro == 1)
			return false;
		
		return true;		
	}
}

//*******************************************
//Trim
//parametros : 
// valor : string
//retorno : string
//descricao : Remove os espaços antes e depois
//de uma string
//*******************************************

function trim(obj){
	
		var ts = '';
		var p = 0;
		var ultima = 0;
	
		for (i = 0; i < obj.value.length; i++){
			var c = obj.value.charAt(i);

			if(c == ' '){
				if(p==1){
					ts = ts + c;
				}
			}
			else{
				ts = ts + c;
				ultima = i;
				p = 1;
			}
			//alert(c);
		}	
		
		//se o ultimo for espaco
		if(c == ' '){
			ts = ts.substring(0,(ultima-1));
		}
				
		return ts;
}

//Verifica qual o tipo de campo para saber como valida-lo
function tipoCampo(obj){
	//alert(obj.type);
	switch(obj.type){
		case 'text':
			return 1
			break;
		case 'select-one':
			return 2
			break;
		case 'select-multiple':
			return 3
			break;
		case 'radio':
			return 4
			break;
		case 'checkbox':
			return 5
			break;
	}
}

function isNumericString(obj,t){
	
	if ( obj != '' ) {
		var i;
		var dif = 0;
		for (i = 0; i < obj.length; i++){
			var c = obj.charAt(i);
			switch(t){
				case 0:
					if (!((c >= '0') && (c <= '9'))){
						dif = 1;
					}
					break;
				case 1: //Data
					if (!((c >= '0') && (c <= '9') || (c == '/')) ){
						dif = 1;
					}
					break;
				case 2: // CEP - Fone
					if (!((c >= '0') && (c <= '9') || (c == '-')) ){
						dif = 1;
					}
					break;
			}
		
		}
		if (dif == 1){
			return false;
		}
		else{
			return true;
		}
	}
	return false;
}

function isCPF(s){
	var i;
	var txt = clearSpecial(s.value);
	var c = txt.substr(0,9);
	var dv = txt.substr(9,2);
	var d1 = 0;
		for (i = 0; i < 9; i++){
			d1 += c.charAt(i)*(10-i);
		}
		if (d1 == 0) return false;
		d1 = 11 - (d1 % 11);
		if (d1 > 9) d1 = 0;
		if (dv.charAt(0) != d1){
			return false;
		}
		d1 *= 2;
		for (i = 0; i < 9; i++){
			d1 += c.charAt(i)*(11-i);
		}
		d1 = 11 - (d1 % 11);
		if (d1 > 9) d1 = 0;
		if (dv.charAt(1) != d1){
			return false;
		}
		return true;
}

function clearSpecial(str){
	var txt = '';
	for(var i = 0;i < str.length;i++){
		var c = str.charAt(i);
		if( (c >= '0') && (c <= '9') ){
			txt = txt + '' + c;
		}
	}
	return txt;
}

function isCNPJ(s){
	var i;
	var txt = clearSpecial(s.value);
	if (txt.length > 14) {
		if (txt.substr(0,1) == 0){
			var c = txt.substr(1,12);
			var dv = txt.substr(13,2);
		}
		else{
			var c = txt.substr(0,12);
			var dv = txt.substr(12,2);
		}
	}
	else{
		var c = txt.substr(0,12);
		var dv = txt.substr(12,2);
	}
	var d1 = 0;
	if (txt.length < 14) {
		return false;
	}
		for (i = 0; i < 12; i++){
			d1 += c.charAt(11-i)*(2+(i % 8));
		}
		if (d1 == 0) return false;
		d1 = 11 - (d1 % 11);
		if (d1 > 9) d1 = 0;
		if (dv.charAt(0) != d1){
			return false;
		}
		d1 *= 2;
		for (i = 0; i < 12; i++){
			d1 += c.charAt(11-i)*(2+((i+1) % 8));
		}
		d1 = 11 - (d1 % 11);
		if (d1 > 9) d1 = 0;
		if (dv.charAt(1) != d1){
			return false;
		}
		return true;
}

function isCrediCard(tipo_cartao,numero,validade_ano,validade_mes,cod_validacao){

	var motivo = '';
	//alert(numero.value);
	if(isNumeric(numero,0)){
		motivo = 'numero não preenchido';
		return false;
	}
	
	var allnumber = '',card1,card2,card3,card4;

	card1 = numero.value.substring(0,4);
	card2 = numero.value.substring(4,8);
	card3 = numero.value.substring(8,12);
	card4 = numero.value.substring(12,numero.value.length);			

	//alert('c1 - ' + card1 + 
	//'\nc2 - ' + card2 + 
	//'\nc3 - ' + card3 + 
	//'\nc4 - ' + card4);
	
	allnumber = card1 + '' +  card2 + '' +  card3 + '' +  card4;

	//valida o tipo do cartão
	//(tipo.selectedIndex == 0)?motivo = 'selecione um tipo de cartão':false;

	if(tipo_cartao.selectedIndex == 0){
		//motivo = 'selecione um tipo de cartão';
		return false;
	}

	if(trim(numero) == ''){
		//motivo = 'numero do cartão';
		return false;
	}	

	if( trim(validade_ano) == '' || trim(validade_mes) == '' ){
		motivo = 'validade incorreta';
		return false;
	}
	
	if( trim(cod_validacao) == ''){
		motivo = 'cod. de validação';
		return false;
	}	
	
	//alert(conta(allnumber));
	//valida a validade do cartão
	var hoje = new Date();
	//alert( hoje.getYear() + '\n' + parseInt(ano.value) );
	anofull = 2000 + parseInt(validade_ano.value);
	//alert('' + anofull + '\n' + parseInt(mes.value)  + '\n' + hoje.getMonth());
	if( hoje.getMonth() > (parseInt(validade_mes.value)-1) && hoje.getFullYear() >= anofull ){
		motivo = 'cartão expirrou';
		return false;
	}
	//alert(hoje.getMonth() + '\n' + mes.value);
	
	if(motivo == ''){

		switch(tipo_cartao.selectedIndex){
			case 1:		//Master card
				if(allnumber.length == 16){
					ini = parseInt(card1)/100;
					(parseInt(ini) >= 51 && parseInt(ini) <= 55)?true:motivo = 'desacordo com a operadora';
				}
				else{
					motivo = 'desacordo com a operadora';		
				}
				break;
			case 2:		//Visa
				if(allnumber.length >= 13 && allnumber.length <= 16){
					ini = parseInt(card1)/1000;
					(parseInt(ini) == 4)?true:motivo = 'desacordo com a operadora';
				}
				else{
					motivo = 'desacordo com a operadora';				
				}				
				break;
			case 3:		//Amex
				if(allnumber.length == 15){
					ini = parseInt(card1)/100;
					(parseInt(ini) == 34 || parseInt(ini) == 37)?true:motivo = 'desacordo com a operadora';
				}
				else{
					motivo = 'desacordo com a operadora';
									
				}				
				break;
			case 4:		//Diners
				if(allnumber.length == 14){
					ini = parseInt(card1)/10;
					ini2 = parseInt(card1)/100;	
					//alert(ini + '\n' + ini2);
					( (parseInt(ini) >= 300 && parseInt(ini) <= 308) || parseInt(ini2) == 38 || parseInt(ini2) == 36 )?true:motivo = 'desacordo com a operadora';
				}
				else{
					motivo = 'desacordo com a operadora';
					return false;				
				}								
				break;				
		}
		
	}
	
	if(motivo == '')
		(isMod10(allnumber))?true:motivo='numero invalido';
	else
		return false;
	
	if(motivo != '')
		return false;
		

	return true;
}

function configCartao(tipo_cartao,numero,validade_ano,validade_mes,cod_validacao,motivo){
	this.tipo_cartao 	= tipo_cartao;
	this.numero 		= numero;
	this.validade_ano 	= validade_ano;
	this.validade_mes 	= validade_mes;
	this.cod_validacao 	= cod_validacao;
}

function addTipoCartao(tipo){

	var ccok = 0;
	for(a = 0;a<this.cartao.length;a++){
		if(this.cartao[a] == tipo){
			ccok = 1;
		}
	}
	if(ccok == 0)
		this.cartao[this.cartao.length] = obj;
		return false;
	
}

function isMod10(valor) { // LUHN Formula for validation of credit card numbers.
 var ar = new Array( valor.length );
 var i = 0,sum = 0;

 for( i = 0; i < valor.length; ++i ) {
  ar[i] = parseInt(valor.charAt(i));
  }
 
 for( i = ar.length -2; i >= 0; i-=2 ) { // you have to start from the right, and work back.
  ar[i] *= 2;			// every second digit starting with the right most (check digit)
  if( ar[i] > 9 ) ar[i]-=9; 	// will be doubled, and summed with the skipped digits.
  }					// if the double digit is > 9, add those individual digits together 

 for( i = 0; i < ar.length; ++i ) {
  sum += ar[i];			// if the sum is divisible by 10 mod10 succeeds
  }
  
 return (((sum%10)==0)?true:false);	 
 
 
 alert('eita');
}
