/***************************************************************************************************
* Exemplo de utilização:
* ---------------------
*
*	function isFormOk(source, arguments) 
*	{
*		var objValida = new Validacao();
*		
*		objValida.MarcarCampos	= true;
*		objValida.Obrigatorios	= true;
*		objValida.Requeridos	= false;
*		objValida.Separador		= "<BR>";
*		objValida.Validar( document.forms[0] );
*
*		arguments.IsValid	= objValida.IsValid;
*		source.errormessage = objValida.Mensagem;
*	}
***************************************************************************************************/
function Validacao()
{
	this.MarcarCampos	= true;
	this.Mensagem		= "";
	this.Separador		= "";
	this.IsValid		= true;
	this.cssClassOk		= "";
	this.cssClassError	= "";
	this.CamposMarcados = new Array();
	
	Validacao.prototype.Validar.base = this;
}

Validacao.prototype.returnCodeToMessage = function( returnCode, field )
{
	var ret = "";
	var fieldName = field.getAttribute("descricao");
	var max		  = field.getAttribute("max");
	var min		  = field.getAttribute("min");
	var tpo		  = field.getAttribute("tipo");
	
	switch( returnCode )
	{
		case eReturnCode.naoInformado:
			ret = "- Campo [" + fieldName + "] nao informado !";
			break;
			
		case eReturnCode.conteudoInvalido:
			ret = "- Campo [" + fieldName + "] invalido !";
			break;
			
		case eReturnCode.valorMinInvalido:
			if( tpo == eFieldType.string )
				ret = "- Campo [" + fieldName + "] deve apresentar no minimo [" + min + "] caracteres!";
			else
				ret = "- Campo [" + fieldName + "] invalido! Valor inferior ao minimo permitido [" + min + "]!";
			break;
			
		case eReturnCode.valorMaxInvalido:
			if( tpo == eFieldType.string )
				ret = "- Campo [" + fieldName + "] deve apresentar no maximo [" + max + "] caracteres!";
			else
				ret = "- Campo [" + fieldName + "] invalido! Valor superior ao maximo permitido [" + max + "]!";
			break;
	}

	return ret;
}

Validacao.prototype.Validar = function( RootElement )
{
	var ret = "";

	if( RootElement == null || RootElement == "undefined" )
		return;
	
	for(var i=0; i < RootElement.childNodes.length; i++)
	{
		var objeto = RootElement.childNodes[i];
		if( (objeto.tagName == "INPUT" && objeto.type != "button" && objeto.type != "image" ) || objeto.tagName == "SELECT" || objeto.tagName == "TEXTAREA" )
		{
			intAux = this.isFieldOk( objeto );
			if(eReturnCode.Ok != intAux ) 
			{
				this.IsValid = false;
				this.CamposMarcados[ this.CamposMarcados.length ] = objeto;

				ret += ((this.Mensagem != "")?this.Separador:"") + this.returnCodeToMessage( intAux, objeto );

				if( this.MarcarCampos )
				{
					if( objeto.className == this.cssClassOk )
						objeto.className = this.cssClassError;
				}
			}
			else
			{
				if( this.MarcarCampos )
				{
					if( objeto.className == this.cssClassError )
						objeto.className = this.cssClassOk;
				}
			}
		}
		else
		{
			if( objeto.childNodes.length > 0 )
				this.Validar(objeto);
		}
	}
	
	this.Mensagem+= ret;

	if( this.IsValid == false && this.CamposMarcados.length > 0 )
		this.setFieldFocus( this.CamposMarcados[0] );
}

Validacao.prototype.setFieldFocus = function( pField ) 
{
	if(pField) 
	{
		try
		{
			pField.focus();
			if(pField.type == "text") 
				pField.select();
		}
		catch( err )
		{
			try
			{
				var idDestino = pField.getAttribute("destino");
				var boDestino = eval( idDestino );

				this.setFieldFocus( boDestino );
			} 
			catch( err )
			{
			}
		}
	}
}

Validacao.prototype.isFieldOk = function( object )
{
    var retorno = "nada";
    
	if( object.disabled==true || object.readOnly==true ) 
		retorno = eReturnCode.Ok;
		
    var obrigatorio = object.getAttribute("obrigatorio")
    var tipo		= object.getAttribute("tipo")
    var min			= object.getAttribute("min")
    var max			= object.getAttribute("max")
	
    if(obrigatorio)
    { 
        if((obrigatorio.toString() == "true" || obrigatorio.toString() == "TRUE") && object.value == "" )
        {
	        retorno = eReturnCode.naoInformado;
	    }
    }

    //alert("1"+retorno);
    if (retorno.toString() == "nada")
    {
	    if( tipo ) 	
	    {
		    switch(tipo) 
		    {
			    case eFieldType.data:
				    retorno =  this.validaData( object.value, min, max );
				    break;

			    case eFieldType.dataHora:
				    retorno =  this.validaDataHora( object.value, min, max );
				    break;

			    case eFieldType.dataHoraMinSeg:
				    retorno =  this.validaDataHoraMinSeg( object.value, min, max );
				    break;
    				
			    case eFieldType.mesAno:
				    retorno =  this.validaMesAno( object.value, min, max );
				    break;
			    case eFieldType.horaMinSeg:
				    retorno =  this.validaHora( object.value, min, max );
				    break;

			    case eFieldType.horaMin:
				    retorno =  this.validaHora( object.value + ":00", min, max );
				    break;

			    case eFieldType.numerico:
				    retorno =  this.isDecimalOk(object);
				    break;

			    case eFieldType.inteiro:
				    retorno =  this.isIntOk(object);
				    break;

			    case eFieldType.cartao:
				    retorno =  this.isCardNumberOk(object);
				    break;

			    case eFieldType.cep:
			        var temValor = ( object.value != "" );
			        if ( temValor )
				        temValor = this.isCepOk(object);
				    retorno =  temValor;
				    break;

			    case eFieldType.cnpj:
				    retorno =  this.isCnpjOk(object);
				    break;

			    case eFieldType.cpf:
				    retorno =  this.isCpfOk(object);
				    break;

			    case eFieldType.eMail:
				    retorno =  this.isEmailOk(object);
				    break;

			    case eFieldType.regExpr:
				    retorno =  this.isRegExprOk(object);
				    break;

    //			case eFieldType.RE:
    //				return this.isREOk(object);
    //				break;

			    case eFieldType.string:
				    retorno =  this.isStringOk( object );
				    break;

			    default:
				    retorno =  eReturnCode.Ok;
				    break;
		    }
	    } 
	    else 
	    {
            retorno =  eReturnCode.Ok;
            //alert("2"+retorno);
	    }
	}
	//alert("3"+retorno);
	return retorno;
}

Validacao.prototype.isStringOk = function( obj )
{
	var min = obj.getAttribute("min");
	var max = obj.getAttribute("max");
	
	if( obj.value != "" )
	{
		if( min != null )
		{
			if( obj.value.length < min )
				return eReturnCode.valorMinInvalido;
		}
	
		if( max != null )
		{
			if( obj.value.length > max )
				return eReturnCode.valorMaxInvalido;
		}
	}
	return eReturnCode.Ok;
}

Validacao.prototype.validaData = function( data, min, max ) 
{
	var reDate = /^(\d{2})\/(\d{2})\/(\d{4})?$/;
	var ret    = eReturnCode.Ok;
	//var reDate = eval("/^(\d{2})/(\d{2})/(\d{4})?$/");
	
	if( data == "" )
	{
		return ret;
	}	
	var matchArray = data.match(reDate);
	if (matchArray == null )  
	{
		ret = eReturnCode.conteudoInvalido;
	}
	else
	{
		dia = parseFloat(matchArray[1]);
		mes = parseFloat(matchArray[2]);
		ano = parseFloat(matchArray[3]);

		if( dia < 0 || dia > 31 )
		{
			return eReturnCode.conteudoInvalido;
		}
		if( mes < 0 || mes > 12 )
		{
			return eReturnCode.conteudoInvalido;
		}
		if( mes == 2 )
		{
			if( this.LeapYear(ano) == false && dia > 28 )
			{
				return eReturnCode.conteudoInvalido;
			}
		}	

		if( mes != 1 && mes != 3 && mes != 5 && mes != 7 && mes != 8 && mes != 10 && mes != 12 && dia == 31)
		{
		/*
			alert( 'X=' + parseFloat('08')  );
			alert( '0=' + matchArray[0] );
			alert( '1=' + matchArray[1] );
			alert( '2=' + matchArray[2] );
			alert( '3=' + matchArray[3] );
			alert( '4=' + dia );
			alert( '5=' + mes );
			alert( '6=' + ano );
		*/
			return eReturnCode.conteudoInvalido;
		}	
		var fData = this.dateToFloat( data );
		if( min != null )
		{
			 var fMin = this.dateToFloat( min );
			 if( fData < fMin )
				return eReturnCode.valorMinInvalido;
		}
		
		if( max != null )
		{
			var fMax = this.dateToFloat( max );
			 if( fData > fMax )
				return eReturnCode.valorMaxInvalido;
		}

		if( ano < 1753 )//Menor Valor de Data no SQL = 01/01/1753
			return eReturnCode.conteudoInvalido;
	}

	return ret;
}


Validacao.prototype.validaDataHoraMinSeg = function( dataHora, min, max ) 
{
	var ret    = eReturnCode.Ok;
	var reDate = /^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2}):(\d{2})?$/;

	var matchArray = dataHora.match(reDate);
	if (matchArray == null && dataHora != "" ) 
	{
		ret = eReturnCode.conteudoInvalido;
	}
	else if( dataHora != "" )
	{
		var cData	= dataHora.substr(0, 10);
		var cDtMin	= (min != null)?min.substr(0,10):null;
		var cDtMax	= (max != null)?max.substr(0,10):null;

		var cHora	= dataHora.substr(11, 8);
		var cHrMin	= (min != null)?min.substr(11,8):null;
		var cHrMax	= (max != null)?max.substr(11,8):null;

		var dtOk = this.validaData( cData, cDtMin, cDtMax );
		var hrOk = this.validaHora( cHora, cHrMin, cHrMax);

		if( dtOk == eReturnCode.Ok )
			ret = hrOk;
		else
			ret = dtOk;
	}
	else if( dataHora == "" )
		ret = eReturnCode.Ok;
		
	return ret;
}

Validacao.prototype.validaDataHora = function( dataHora, min, max ) 
{
	var reDate = /^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})?$/;
	var matchArray = dataHora.match(reDate);
	var ret    = eReturnCode.Ok;

	if (matchArray == null && dataHora != "" ) 
	{
		ret = eReturnCode.conteudoInvalido;
	}
	else if( dataHora != "" )
	{
		var cData	= dataHora.substr(0, 10);
		var cDtMin	= (min != null)?min.substr(0,10):null;
		var cDtMax	= (max != null)?max.substr(0,10):null;

		var cHora	= dataHora.substr(11, 5) + ":00";
		var cHrMin	= (min != null)?min.substr(11,5) + ":00":null;
		var cHrMax	= (max != null)?max.substr(11,5) + ":00":null;

		var dtOk =  this.validaData( cData, cDtMin, cDtMax );
		var hrOk = this.validaHora( cHora, cHrMin, cHrMax);
		
		if( dtOk == eReturnCode.Ok )
			ret = hrOk;
		else
			ret = dtOk;
	}
	else
		ret = eReturnCode.Ok;
	
	return ret;
}

Validacao.prototype.validaMesAno = function( mesAno, min, max ) 
{
	//alert( mesAno )
	if( mesAno == "" )
		return eReturnCode.Ok;

	var cData	= "01/" + mesAno;
	var cMin	= (min == null)?null:"01/" + min;
	var cMax	= (max == null)?null:"01/" + max;

	return this.validaData( cData, cMin, cMax );
}

Validacao.prototype.validaHora = function( timeStr, min, max ) 
{

	var timePat = /^(\d{2}):(\d{2}):(\d{2})?$/;
	var matchArray = timeStr.match(timePat);

	if (matchArray == null && timeStr != "" ) 
	{
		return eReturnCode.conteudoInvalido;
	}
	else
	{
		hour	= this.StringToInt( matchArray[1] );
		minute	= this.StringToInt( matchArray[2] );
		second	= this.StringToInt( matchArray[3] );
		
		if (hour < 0  || hour > 23)
			return eReturnCode.conteudoInvalido;

		if (minute < 0 || minute > 59)
			return eReturnCode.conteudoInvalido;

		if (second < 0  || second > 59)
			return eReturnCode.conteudoInvalido;

		var Vlr = this.Replace(timeStr, ":");

		if( min != null && min != "" )
		{
			var vMin = this.Replace(min, ":");
			if( Vlr < vMin )
				return eReturnCode.valorMinInvalido;
		}

		if( max != null && max != "" )
		{
			var vMax = this.Replace(max, ":");
			if( Vlr > vMax )
				return eReturnCode.valorMaxInvalido;
		}
	}
	return eReturnCode.Ok;
}

Validacao.prototype.LeapYear = function(intYear) 
{

	if (intYear % 100 == 0) {
		if (intYear % 400 == 0) { return true; }
	}
	else {
		if ((intYear % 4) == 0) { return true; }
	}
	
	return false;
}

Validacao.prototype.dateToFloat = function(Date) 
{

	var arrAux = Date.split("/");
	var strAux = arrAux[2] + arrAux[1] + arrAux[0];
	
	return parseFloat( strAux );
}

Validacao.prototype.isEmailOk = function( obj )
{
	var emailStr	= obj.value;
	if( emailStr == "" )
		return eReturnCode.Ok;
		
	var emailPat	= eval("/^(.+)@(.+)$/");
	var specialChars= "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
	var validChars	= "\[^\\s" + specialChars + "\]";
	var firstChars	= validChars;
	var quotedUser	= "(\"[^\"]*\")";
	var ipDomainPat	= eval("/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/");
	var atom		= "(" + firstChars + validChars + "*" + ")";
	var word		= "(" + atom + "|" + quotedUser + ")";
	var userPat		= new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat	= new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray	= emailStr.match(emailPat);

	if (matchArray==null) 
		return eReturnCode.conteudoInvalido;

	var user=matchArray[1];
	var domain=matchArray[2];

	if (user.match(userPat)==null)
		return eReturnCode.conteudoInvalido;

	var IPArray=domain.match(ipDomainPat);
	if (IPArray!=null)
	{
		for (var i=1;i<=4;i++)
			if (IPArray[i]>255)
				return eReturnCode.conteudoInvalido;

		return eReturnCode.Ok;
	}

	var domainArray=domain.match(domainPat);
	if (domainArray==null)
		return eReturnCode.conteudoInvalido;

	var atomPat=new RegExp(atom,"g");
	var domArr=domain.match(atomPat);
	var len=domArr.length;
	if (domArr[domArr.length-1].length<2 || domArr[domArr.length-1].length>3)
		return eReturnCode.conteudoInvalido;

	if (domArr[domArr.length-1].length==2 && len<3)
		return eReturnCode.conteudoInvalido;

	if (domArr[domArr.length-1].length==3 && len<2)
		return eReturnCode.conteudoInvalido;
	
	return eReturnCode.Ok;

	var domainArray=domain.match(domainPat);
	if (domainArray==null)
		return eReturnCode.conteudoInvalido;


	var atomPat=new RegExp(atom,"g");
	var domArr=domain.match(atomPat);
	var len=domArr.length;
	if (domArr[domArr.length-1].length<2 || domArr[domArr.length-1].length>3)
		return eReturnCode.conteudoInvalido;

	if (domArr[domArr.length-1].length==2 && len<3)
		return eReturnCode.conteudoInvalido;
	
	if (domArr[domArr.length-1].length==3 && len<2)
		return eReturnCode.conteudoInvalido;

	return eReturnCode.Ok;
} 

Validacao.prototype.isCardNumberOk = function ( obj )
{
	var ccnumber = obj.value;
	var comMask	 = false;
	var aceitaMask = obj.getAttribute("aceitaMascara");
	if( aceitaMask )
		comMask	 = (aceitaMask.toString().toUpperCase() == "TRUE");
		
	if( ccnumber.indexOf('*') == -1 )
	{
		ccnumber = this.cleanCCNum( ccnumber );
		if( ccnumber != "" )
		{
			isEven = false;
			digits = "";
		
			for( var i=(ccnumber.length-1); i >= 0; i--) {
				
				c = ccnumber.substring(i, i+1);
				if( isEven ) 
					digits += "" + parseInt(c * 2);
				else
					digits += "" + parseInt(c);

				isEven = !isEven;
			}

			checkSum = 0;
			
			for( var i=0; i < digits.length; i++)
				checkSum+= parseInt( digits.substring(i, i+1) );

//Gambi Teste Bradesco
//return eReturnCode.Ok;

			if( checkSum%10 == 0 )
				return eReturnCode.Ok;
			else
				return eReturnCode.conteudoInvalido;
		}
		return eReturnCode.Ok;
	}
	else
	{
		if( comMask )
		{
			ccnumber = this.cleanCCNum( ccnumber );
			if( ccnumber != "" && ccnumber.length == 10 )
				return eReturnCode.Ok;
			else
				return eReturnCode.conteudoInvalido;
		}
		else 
			return eReturnCode.conteudoInvalido;
	}
 }

Validacao.prototype.cleanCCNum = function ( ccnumber ) {

	var ret="";

	for(var i=0; i < ccnumber.length; i++) {
		
		var c=ccnumber.substring(i, i+1);
			if(!isNaN(c))
				ret+=c; 
	}
	
	return ret;
}

Validacao.prototype.isCpfOk = function (obj) 
{
	exp = this.cleanCCNum( obj.value );
	
	if( exp == "" )
		return eReturnCode.Ok;
		
	var regExp = /\d{11}/;
	if (regExp.test(exp)) 
	{
		var varFirstChr = exp.charAt(0);	
		var vaCharCPF = false;
		for(var i=0;i<=10;i++){
			var c = exp.charAt(i);             
			if(c!=varFirstChr)
				vaCharCPF = true;
		}

		if(!vaCharCPF)
			return eReturnCode.conteudoInvalido;

		var soma=0;	

		for(i=0;i<9; i++)
			soma += (10-i) * ( eval(exp.charAt(i)) );

		digito_verificador = 11-(soma % 11);

		if((soma % 11) < 2)
			digito_verificador = 0;	

		if (eval(exp.charAt(9)) != digito_verificador)
			return eReturnCode.conteudoInvalido;

		soma=0;	

		for(i=0;i<9; i++)
			soma += (11-i)*(eval(exp.charAt(i)));

		soma += 2*(eval(exp.charAt(9)));

		digito_verificador = 11-(soma % 11);

		if((soma % 11)<2) 
			digito_verificador = 0;

		if(eval(exp.charAt(10)) != digito_verificador)
			return eReturnCode.conteudoInvalido;

		return eReturnCode.Ok;

	} else {
		return eReturnCode.conteudoInvalido;
	}
}


Validacao.prototype.isCnpjOk = function(psCNPJ) 
{

	var liPeso = 2;
	var liSoma = 0;
	var lsAux  = '';
	var liTemp = 0;
	var liDigito = 0;
	var lsCNPJ = '';

	lsCNPJ = this.cleanCCNum( psCNPJ.value );
	
	if( lsCNPJ == "" )
		return eReturnCode.Ok;
		
	var liPos  = 0;

	for (liPos = lsCNPJ.length - 1; liPos >= 0; liPos--)
		if (!isNaN(lsCNPJ.charAt(liPos)))
			lsAux = lsCNPJ.charAt(liPos) + lsAux;
			
	for (liPos = lsAux.length - 3; liPos >= 0; liPos--)
	{
		liSoma += parseInt(lsCNPJ.charAt(liPos)) * liPeso;
		liPeso  = (liPeso == 9)?2:(liPeso + 1);
	}
	
	liTemp   = (liSoma % 11);
	liDigito = (liTemp < 2)?0:(11 - liTemp);
	
	if (parseInt(lsCNPJ.charAt(lsCNPJ.length - 2)) != liDigito)
		return eReturnCode.conteudoInvalido;
	
	liPeso = 2;
	liSoma = 0;

	for (liPos = lsAux.length - 2; liPos >= 0; liPos--)
	{
		liSoma += parseInt(lsCNPJ.charAt(liPos)) * liPeso;
		liPeso  = (liPeso == 9)?2:(liPeso + 1);
	}
	
	liTemp   = (liSoma % 11);
	liDigito = (liTemp < 2)?0:(11 - liTemp);
	
	if (parseInt(lsCNPJ.charAt(lsCNPJ.length - 1)) != liDigito)
		return eReturnCode.conteudoInvalido;

	return eReturnCode.Ok;
}

Validacao.prototype.isDecimalOk = function( obj )
{
	var strDec = this.Replace( obj.value, ".", "" );
		strDec = this.Replace( strDec   , ",", "." );
	
	var min  = obj.getAttribute("min");
	var max  = obj.getAttribute("max");
	
	if( strDec != "" )
	{
		var fAux = parseFloat( strDec );
		
		if( isNaN( fAux ) )
			return eReturnCode.conteudoInvalido;
		else
		{
			if( min != null )
				if( fAux < this.StringToDecimal(min) )
					return eReturnCode.valorMinInvalido;

			if( max != null )
				if( fAux > this.StringToDecimal(max) )
					return eReturnCode.valorMaxInvalido;
		}
	}
	return eReturnCode.Ok;
}

Validacao.prototype.isIntOk = function( obj )
{
	var min  = obj.getAttribute("min");
	var max  = obj.getAttribute("max");
	var iAux = this.Replace( obj.value, ".", "" );

	if( isNaN(iAux) )
		return eReturnCode.conteudoInvalido;
	else
	{
		if( min != null )
			if( iAux < this.StringToInt(min) )
				return eReturnCode.valorMinInvalido;

		if( max != null )
			if( iAux > this.StringToInt(max) )
				return eReturnCode.valorMaxInvalido;
	}
	return eReturnCode.Ok;
}

Validacao.prototype.isCepOk = function( obj )
{
	var cep   = obj.value;
	var reCep = /^(\d{5})-(\d{3})?$/;
	var matchArray = cep.match(reCep);
	if (matchArray == null) 
		return eReturnCode.conteudoInvalido;
	else
		return eReturnCode.Ok;
}

Validacao.prototype.isREOk = function( obj )
{
	var re   = obj.value;
	
	if( re == "" )
		return eReturnCode.Ok;
	
	var reRE = /^(\d{6})-(\d{1})?$/;
	var matchArray = re.match(reRE);
	if (matchArray == null) 
		return eReturnCode.conteudoInvalido;
	else
		return eReturnCode.Ok;
}

Validacao.prototype.isRegExprOk = function( field )
{
	var vlField		= field.value;
	var reField		= field.getAttribute("regExpr");
	var matchArray	= vlField.match(reField);
	if (matchArray == null) 
		return eReturnCode.conteudoInvalido;
	else
		return eReturnCode.Ok;
}

Validacao.prototype.Replace = function( Text, oldText, newText )
{
	do{	
		Text = Text.toString().replace(oldText, newText);
	} while (Text.indexOf(oldText) > 0)
	
	return Text;
}
Validacao.prototype.StringToDecimal = function(pValue)
{
	var ret = this.Replace( pValue, ".", "" );
		ret = this.Replace( ret   , ",", ".");

	if( isNaN(parseFloat(ret)) )
		return 0;
	else
		return parseFloat(ret);
}

Validacao.prototype.StringToInt = function(pValue)
{
	var ret = this.Replace( pValue, ".", "" );
	if( isNaN(parseInt(ret)) )
		return 0;
	else
		return parseInt(ret);
}
