<?PHP
/*
 * DIREITOS AUTORAIS RESERVADOS (C) 2007 UFRJ
 * 
 * ESTE PROGRAMA É SOFTWARE LIVRE; VOCÊ PODE REDISTRIBUÍ-LO E/OU MODIFICÁ-LO SOB OS
 * TERMOS DA LICENÇA PÚBLICA GERAL GNU CONFORME PUBLICADA PELA FREE SOFTWARE FOUNDATION;
 * TANTO A VERSÃO 2 DA LICENÇA, COMO (A SEU CRITÉRIO) QUALQUER VERSÃO POSTERIOR.

 * ESTE PROGRAMA É DISTRIBUÍDO NA EXPECTATIVA DE QUE SEJA ÚTIL, PORÉM, SEM NENHUMA GARANTIA;
 * NEM MESMO A GARANTIA IMPLÍCITA DE COMERCIABILIDADE OU ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA.
 * CONSULTE A LICENÇA PÚBLICA GERAL DO GNU PARA MAIS DETALHES.
 * 
 * VOCÊ DEVE TER RECEBIDO UMA CÓPIA DA LICENÇA PÚBLICA GERAL DO GNU JUNTO COM ESTE PROGRAMA; 
 * SE NÃO, ACESSE <<HTTP://WWW.GNU.ORG/LICENSES/LICENSES.PT-BR.HTML>>
 */

<?

require_once 'documento.php';

function valida_cnh($codigo)/*{{{*/
{
	if(!ctype_digit($codigo))
		return false;

	if(strlen($codigo) > 11)
		return false;

	$codigo = str_pad($codigo, 11, '0', STR_PAD_LEFT);

	// Eh mais rápido testar se o codigo eh composto de
	// digitos iguais assim...
	$igual = true;
	for($j=1; $j<11; ++$j)
	{
		if($codigo[$j] != $codigo[$j-1])
		{
			$igual = false;
			break;
		}
	}
	if($igual)
		return false;

	$soma = 0;
	for($i=0; $i<9; ++$i)
		$soma += $codigo[$i]*(9-$i);
	$dv1 = $soma % 11;
	$incr_dig2 = $dv1 == 10 ? -2 : 0;
	if($dv1 >= 10)
		$dv1 = 0;

	if($dv1 != $codigo[9])
		return false;

	$soma = 0;
	for($i=0; $i<9; ++$i)
		$soma += $codigo[$i]*($i+1);
	$dv2 = $soma % 11;

	if($dv2 + $incr_dig2 < 0)
		$dv2 += 11 + $incr_dig2;
	else
		$dv2 += $incr_dig2;

	if($dv2 >= 10)
		$dv2 = 0;

	return $dv2 == $codigo[10];
}/*}}}*/
function valida_pgu($codigo)/*{{{*/
{
	if(!ctype_digit($codigo))
		return false;

	if(strlen($codigo) > 9)
		return false;

	$codigo = str_pad($codigo, 9, '0', STR_PAD_LEFT);

	// Eh mais rápido testar se o codigo eh composto de
	// digitos iguais assim...
	$igual = true;
	for($j=1; $j<9; ++$j)
	{
		if($codigo[$j] != $codigo[$j-1])
		{
			$igual = false;
			break;
		}
	}
	if($igual)
		return false;

	$soma = 0;
	for($i=0; $i<8; ++$i)
		$soma += $codigo[$i]*(2+$i);

	$dv = $soma % 11;
	if($dv > 9)
		$dv = 0;

	return $dv == $codigo[8];
}/*}}}*/

function valida_habilitacao_motorista($codigo)/*{{{*/
{
	return valida_cnh($codigo) || valida_pgu($codigo);
}/*}}}*/


class CNH extends Documento
{
	function setTableDefinition()
	{
		$this->setTableName('saude.cnh');
		$this->hasColumn('numero','string', 11, 
			array('fixed','unique','notnull','notblank'));

		$this->hasColumn('idpessoa', 'integer', NULL, array('notnull'));

		Documento::setTableDefinition();
	}

	function validate()
	{
		Documento::validate();

		$erros = array();

		if(!$this->numero)
			$erros[] = 'O número de registro da carteira de motorista deve ser informado';
		else 
		{
			$len = strlen($this->numero);
			if($len != 11 && // cnh
			   $len != 9) // pgu, habilitação antiga
			{
				$erros[] = 'O número de registro da carteira de motorista deve ter 11 (nova) ou 9 (antiga) dígitos';
			}
			else if(!valida_habilitacao_motorista($this->numero))

				$erros[] = 'O número de registro da carteira de motorista é inválido: '.$this->numero;
		}

		if($erros)
			throw new Exception(implode("\n",$erros));
	}

	function setUp()
	{
		Documento::setUp();

		$this->hasOne('Pessoa as pessoa',
			array('local'=>'idpessoa',
			      'foreign'=>'id'));

		$this->index('unique_pessoa_cnh',
			array('fields'=>array('idpessoa'),
			      'type'=>'unique'));

	}
};

?>
