/* Bem - Decompiled by JODE
 * Visit http://jode.sourceforge.net/
 */
package serpro.ppgd.irpf.bens;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import serpro.ppgd.irpf.DeclaracaoIRPF;
import serpro.ppgd.irpf.IdentificadorDeclaracao;
import serpro.ppgd.irpf.tabelas.CadastroTabelasIRPF;
import serpro.ppgd.negocio.Alfa;
import serpro.ppgd.negocio.CEP;
import serpro.ppgd.negocio.Codigo;
import serpro.ppgd.negocio.ConstantesGlobais;
import serpro.ppgd.negocio.CPF;
import serpro.ppgd.negocio.Data;
import serpro.ppgd.negocio.Informacao;
import serpro.ppgd.negocio.Inteiro;
import serpro.ppgd.negocio.NI;
import serpro.ppgd.negocio.ObjetoNegocio;
import serpro.ppgd.negocio.Pendencia;
import serpro.ppgd.negocio.RetornoValidacao;
import serpro.ppgd.negocio.ValidadorDefault;
import serpro.ppgd.negocio.Valor;
import serpro.ppgd.negocio.validadoresBasicos.ValidadorNaoNulo;
import serpro.ppgd.negocio.validadoresBasicos.ValidadorNI;

public class Bem extends ObjetoNegocio
{
  public static final String NOME_CAMPO_VALOR_ANTERIOR = "Situa\u00e7\u00e3o em 31/12/" + ConstantesGlobais.EXERCICIO_ANTERIOR;
  public static final String NOME_CAMPO_VALOR_ATUAL = "Situa\u00e7\u00e3o em 31/12/" + ConstantesGlobais.EXERCICIO;
  private Inteiro AChava = new Inteiro (this, "Chave/índice (calculada)");
  private Codigo codGrupo = new Codigo (this, "Grupo", CadastroTabelasIRPF.recuperarGrupoBens ());
  private Codigo codigo = new Codigo (this, "C\u00f3digo", CadastroTabelasIRPF.recuperarTipoBens ());
  private Codigo pais = new Codigo (this, "Localiza\u00e7\u00e3o(Pa\u00eds)", CadastroTabelasIRPF.recuperarPaises ());
  private Alfa discriminacao = new Alfa (this, "Discrimina\u00e7\u00e3o", 510);
  private Valor valorExercicioAnterior = new Valor (this, NOME_CAMPO_VALOR_ANTERIOR);
  private Valor valorExercicioAtual = new Valor (this, NOME_CAMPO_VALOR_ATUAL);
  private Alfa logradouro = new Alfa (this, "Logradouro", 40);
  private Alfa numero = new Alfa (this, "Número", 6);
  private Alfa complemento = new Alfa (this, "Número", 40);
  private Alfa bairro = new Alfa (this, "Bairro", 40);
  private Codigo uf = new Codigo (this, "UF", CadastroTabelasIRPF.recuperarUFs (1));
  private Codigo municipio = new Codigo (this, "Munic\u00edpio", new Vector ());
  private Alfa nomeMunicipio = new Alfa (this, "Município", 40);
  private Alfa cidade = new Alfa (this, "Cidade", 40);
  private CEP cep = new CEP (this, "CEP");
  private Alfa registrado = new Alfa (this, "Registrado", 1);
  private Alfa matricula = new Alfa (this, "Matrícula", 40);
  private Valor areaTotal = new Valor (this, "Área Total");
  private Alfa unidade = new Alfa (this, "Unidade da Área", 1);
  private Alfa nomeCartorio = new Alfa (this, "Nome do Cartório", 60);
  // FIXME: participacoesInventario = new ColecaoItemPercentualParticipacaoInventario (this);
  private Data dataAquisicao = new Data (this, "Data de aquisição");
  private Alfa IPTU = new Alfa (this, "Número do IPTU", 30);
  private Alfa Renavan = new Alfa (this, "Número do RENAVAN", 30);
  private Alfa RegAviaCivil = new Alfa (this, "Número do Registro na Aviação Civil", 30);
  private Alfa RegCapPortos = new Alfa (this, "Número do Registro na Capitania de Portos", 30);
  private Codigo banco = new Codigo (this, "Banco", CadastroTabelasIRPF.recuperarBancos ());
  private Alfa agencia = new Alfa (this, "Número da Agência Bancária", 4);
  private Alfa conta = new Alfa (this, "Número da Conta Bancária", 20);
  private Alfa contaDV = new Alfa (this, "Dígito Verificador da Conta Bancária", 2);
  private NI CPFCNPJ = new NI (this, "CPF ou CNPJ do Beneficiário");
  private CPF CPFTitDep = new CPF (this, "CPF do Titular ou do Dependente ao qual o registro se refere");
  private Alfa CIB = new Alfa (this, "CIB do Imóvel Rural", 8);
  private Alfa CEI_CNO = new Alfa (this, "CEI/CNO da Construção", 12);
  /* FIXME: IN_BEM_INVENTARIAR  */
  static private final int grupo_requer_TD[] = {
    3, 4, 5, 6, 7
  };
  static private final int grupoComCodigo_requer_TD[] = {
    9905, 9906, 9907, 9999
  };
  public static final String BRASIL = "0";
  public static final String EXTERIOR = "1";
  
  /* Mapeia códigos usados até 2021 para
     (grupo * 100 + código) de 2022.  */
  public static int mapeiaCodigo21para22 (int codigo21)
  {
    switch (codigo21)
    {
    case  1: return 1 * 100 + 1; /* Prédio residencial */
    case  2: return 1 * 100 + 2; /* Prédio comercial */
    case  3: return 1 * 100 + 3; /* Galpão */
    case 11: return 1 * 100 + 11; /* Apartamento */
    case 12: return 1 * 100 + 12; /* Casa */
    case 13: return 1 * 100 + 13; /* Terreno */
    case 14: return 1 * 100 + 14; /* Imóvel rural */
    case 15: return 1 * 100 + 15; /* Sala ou conjunto */
    case 16: return 1 * 100 + 16; /* Construção */
    case 17: return 1 * 100 + 17; /* Benfeitorias */
    case 18: return 1 * 100 + 18; /* Loja */
    case 19: return 1 * 100 + 99; /* Outros bens imóveis */
    case 21: return 2 * 100 + 1; /* Veículo automotor terrestre: caminhão, automóvel, moto etc */
    case 22: return 2 * 100 + 2; /* Aeronave */
    case 23: return 2 * 100 + 3; /* Embarcação */
    case 24: return 2 * 100 + 4; /* Bem relacionado com o exercício da atividade autônoma */
    case 25: return 2 * 100 + 5; /* Jóia, quadro, objeto de arte, de coleção, antiguidade etc */
    case 26: return 2 * 100 + 99; /* ??? Outros bens móveis */
    case 29: return 2 * 100 + 99; /* Outros bens móveis */
    case 31: return 3 * 100 + 1; /* Ações */
    case 32: return 3 * 100 + 2; /* Quotas ou quinhões de capital */
    case 39: return 3 * 100 + 99; /* Outras participações societárias */
    case 41: return 4 * 100 + 1; /* Depósito em conta poupança */
    case 45: return 4 * 100 + 2; /* Títulos públicos e privados sujeitos à tributação (Tesouro Direto, CDB, RDB e Outros) */
    case 46: return 4 * 100 + 5; /* Ouro, ativo financeiro */
    case 47: return 4 * 100 + 4; /* ??? Ativos negociados em bolsa no Brasil (BDRs, opções e outros - exceto ações e fundos) */
    case 49: return 4 * 100 + 99; /* Outras aplicações e investimentos */
    case 51: return 5 * 100 + 1; /* Empréstimos concedidos */
    case 52: return 5 * 100 + 2; /* Crédito decorrente de alienação */
    case 53: return 6 * 100 + 99; /* ??? Outros depósitos à vista */
    case 54: return 6 * 100 + 99; /* ??? Outros depósitos à vista */
    case 59: return 5 * 100 + 99; /* ??? Outros créditos */
    case 61: return 6 * 100 + 1; /* Depósito em conta corrente ou conta pagamento */
    case 62: return 6 * 100 + 1; /* ??? Depósito em conta corrente ou conta pagamento */
    case 63: return 6 * 100 + 10; /* Dinheiro em espécie - moeda nacional */
    case 64: return 6 * 100 + 11; /* Dinheiro em espécie - moeda estrangeira */
    case 69: return 6 * 100 + 99; /* ??? Outros depósitos à vista */
    case 71: return 7 * 100 + 1; /* Fundos de Investimentos sujeitos à tributação periódica (come-cotas) */
    case 72: return 7 * 100 + 1; /* ??? Fundos de Investimentos sujeitos à tributação periódica (come-cotas) */
    case 73: return 7 * 100 + 3; /* Fundos de Investimento Imobiliário (FII) */
    case 74: return 7 * 100 + 5; /* ??? Fundos de Investimento em Ações - Mercado de Acesso */
    case 79: return 7 * 100 + 99; /* Outros fundos */
    case 80: return 6 * 100 + 99; /* Outros depósitos à vista */
    case 91: return 99 * 100 + 1; /* Licença e concessão especiais */
    case 92: return 99 * 100 + 2; /* Título de clube e assemelhado */
    case 93: return 99 * 100 + 3; /* Direito de autor, de inventor e patente */
    case 94: return 99 * 100 + 4; /* Direito de lavra e assemelhado */
    case 95: return 99 * 100 + 5; /* Consórcio não contemplado */
    case 96: return 99 * 100 + 99; /* ??? Outros bens e direitos */
    case 99: return 99 * 100 + 99; /* Outros bens e direitos */
    default: return 99 * 100 + 99; /* ??? Outros bens e direitos */
    }
  }

  /* Combina codGrupo * 100 + codigo.  */
  public int codigoComGrupo ()
  {
    return codGrupo.asInteger () * 100 + codigo.asInteger ();
  }

  public Bem (final DeclaracaoIRPF objDecl)
  {
    final IdentificadorDeclaracao identificadorDeclaracao
      = objDecl.getIdentificadorDeclaracao ();
    getCodGrupo ().setColunaFiltro (1);
    getCodigo ().setColunaFiltro (1);
    getPais ().setColunaFiltro (1);
    getCodGrupo ().addValidador (new ValidadorNaoNulo ((byte) 3, tab.msg ("bem_codigo")));
    getCodigo ().addValidador (new ValidadorNaoNulo ((byte) 3, tab.msg ("bem_codigo")));
    getDiscriminacao ().addValidador (new ValidadorNaoNulo ((byte) 3, tab.msg ("bem_discriminacao")));
    getPais ().addValidador (new ValidadorNaoNulo ((byte) 3, tab.msg ("bem_pais_branco")));
    getCPFCNPJ ().addValidador (new ValidadorNI ((byte) 3));
    /* Os campos banco, agência e conta só são solicitados para
       códigos 41 e 61.  Vários outros campos são específicos para
       certos códigos de bens.  FIXME: validar?  */
    getCPFTitDep ().addValidador (new ValidadorDefault ((byte) 3)
    {
      private boolean requerTD (int val)
      {
	{
	  final int grupo = val / 100;
	  final int[] lst = grupo_requer_TD;
	  int inf = 0, sup = lst.length - 1;
	  while (inf <= sup)
	    {
	      int mid = (inf + sup) / 2;
	      int tst = lst[mid];
	      if (tst == grupo)
		return true;
	      if (tst < grupo)
		inf = mid + 1;
	      else
		sup = mid - 1;
	    }
	}
	final int[] lst = grupoComCodigo_requer_TD;
	int inf = 0, sup = lst.length - 1;
	while (inf <= sup)
	  {
	    int mid = (inf + sup) / 2;
	    int tst = lst[mid];
	    if (tst == val)
	      return true;
	    if (tst < val)
	      inf = mid + 1;
	    else
	      sup = mid - 1;
	  }
	return false;
      }

      public RetornoValidacao validarImplementado ()
      {
	CPF td = getCPFTitDep ();
	boolean esperado = requerTD (codigoComGrupo ());
	if (td.asString ().trim ().length () > 0)
	  {
	    if (!esperado)
	      return new RetornoValidacao (tab.msg ("bem_dispensa_td"),
					   (byte) 3);
	    if (identificadorDeclaracao.getCpf ().asString ().equals
		(td.asString ()))
	      return null;
	    if (objDecl.getDependentes ().getDependenteByCPF (td)
		== null)
	      return new RetornoValidacao (tab.msg ("bem_dependente_sem_ficha"),
					   (byte) 3);
	  }
	else if (esperado)
	  return new RetornoValidacao (tab.msg ("bem_requer_td"), (byte) 3);
	return null;
      }
    });
  }
  
  public boolean isVazio ()
  {
    Iterator iterator = recuperarCamposInformacao ().iterator ();
    while (iterator.hasNext ())
      {
	Informacao informacao = (Informacao) iterator.next ();
	if (! informacao.isVazio () && ! informacao.getNomeCampo ().equals ("Localiza\u00e7\u00e3o(Pa\u00eds)"))
	  return false;
      }
    return true;
  }
  
  public Inteiro getChave ()
  {
    return AChava;
  }

  public Codigo getCodGrupo ()
  {
    return codGrupo;
  }
  
  public Codigo getCodigo ()
  {
    return codigo;
  }
  
  public Alfa getDiscriminacao ()
  {
    return discriminacao;
  }
  
  public Codigo getPais ()
  {
    return pais;
  }
  
  public Valor getValorExercicioAnterior ()
  {
    return valorExercicioAnterior;
  }
  
  public Valor getValorExercicioAtual ()
  {
    return valorExercicioAtual;
  }
  
  public Alfa getLogradouro ()
  {
    return logradouro;
  }

  public Alfa getNumero ()
  {
    return numero;
  }

  public Alfa getComplemento ()
  {
    return complemento;
  }

  public Alfa getBairro ()
  {
    return bairro;
  }

  public Codigo getUf ()
  {
    return uf;
  }

  public Codigo getMunicipio ()
  {
    return municipio;
  }

  public Alfa getNomeMunicipio ()
  {
    return nomeMunicipio;
  }

  public Alfa getCidade ()
  {
    return cidade;
  }

  public CEP getCep ()
  {
    return cep;
  }

  public Alfa getRegistrado ()
  {
    return registrado;
  }

  public Alfa getMatricula ()
  {
    return matricula;
  }

  public Valor getAreaTotal ()
  {
    return areaTotal;
  }

  public Alfa getUnidade ()
  {
    return unidade;
  }

  public Alfa getNomeCartorio ()
  {
    return nomeCartorio;
  }

  public Data getDataAquisicao ()
  {
    return dataAquisicao;
  }

  public Alfa getIPTU ()
  {
    return IPTU;
  }

  public Alfa getRenavan ()
  {
    return Renavan;
  }

  public Alfa getRegAviaCivil ()
  {
    return RegAviaCivil;
  }

  public Alfa getRegCapPortos ()
  {
    return RegCapPortos;
  }

  public Codigo getBanco ()
  {
    return banco;
  }

  public Alfa getAgencia ()
  {
    return agencia;
  }

  public Alfa getConta ()
  {
    return conta;
  }

  public Alfa getContaDV ()
  {
    return contaDV;
  }

  public NI getCPFCNPJ ()
  {
    return CPFCNPJ;
  }

  public CPF getCPFTitDep ()
  {
    return CPFTitDep;
  }

  public Alfa getCIB ()
  {
    return CIB;
  }

  public Alfa getCEI_CNO ()
  {
    return CEI_CNO;
  }

  protected List recuperarListaCamposPendencia ()
  {
    List retorno = super.recuperarListaCamposPendencia ();
    retorno.add (codGrupo);
    retorno.add (codigo);
    retorno.add (pais);
    retorno.add (discriminacao);
    retorno.add (valorExercicioAtual);
    retorno.add (valorExercicioAnterior);
    retorno.add (CPFCNPJ);
    retorno.add (CPFTitDep);
    return retorno;
  }
  
  public List verificarPendencias (int numeroItem)
  {
    List retorno = super.verificarPendencias (numeroItem);
    if (getValorExercicioAtual ().isVazio () && getValorExercicioAnterior ().isVazio ())
      {
	Pendencia p = new Pendencia ((byte) 2, getValorExercicioAnterior (), getValorExercicioAnterior ().getNomeCampo (), tab.msg ("bem_valor_nao_informado"), numeroItem);
	retorno.add (p);
      }
    return retorno;
  }
}
