/* CalculosPagamentos - Decompiled by JODE
 * Visit http://jode.sourceforge.net/
 */
package serpro.ppgd.irpf.calculos;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import serpro.ppgd.irpf.DeclaracaoIRPF;
import serpro.ppgd.irpf.pagamentos.Pagamento;
import serpro.ppgd.irpf.pagamentos.Pagamentos;
import serpro.ppgd.negocio.Observador;
import serpro.ppgd.negocio.Valor;

public class CalculosPagamentos extends Observador
{
  private DeclaracaoIRPF declaracaoIRPF = null;
  
  public CalculosPagamentos (DeclaracaoIRPF dec)
  {
    declaracaoIRPF = dec;
  }
  
  public void notifica (Object observado, String nomePropriedade, Object valorAntigo, Object valorNovo)
  {
    if (nomePropriedade != null)
      {
	if (nomePropriedade.equals ("ObjetoInserido"))
	  {
	    ((Pagamento) valorNovo).getCodigo ().addObservador (this);
	    ((Pagamento) valorNovo).getValorPago ().addObservador (this);
	    ((Pagamento) valorNovo).getParcelaNaoDedutivel ().addObservador (this);
	  }
	else if (nomePropriedade.equals ("ObjetoRemovido"))
	  {
	    ((Pagamento) valorNovo).getValorPago ().removeObservador (this);
	    ((Pagamento) valorNovo).getParcelaNaoDedutivel ().removeObservador (this);
	    ((Pagamento) valorNovo).getCodigo ().removeObservador (this);
	  }
      }
    calculaTotalDeducoesInstrucao ();
    calculaTotalContribuicaoFAPI ();
    calculaTotalDespesasMedicas ();
    CalculosDeducoesIncentivos.calculaDeducaoIncentivo (declaracaoIRPF);
    calculaTotalPensao ();
  }
  
  private void calculaTotalPensao ()
  {
    declaracaoIRPF.getPagamentos ().getTotalPensao ().setConteudo (totalizarPagamentos (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.PAGAMENTO_PENSAOALIMENTICIA_BR, Pagamento.PAGAMENTO_PENSAOALIMENTICIA_EX }, true, true));
  }
  
  private void calculaTotalPensaoCartoral ()
  {
    declaracaoIRPF.getPagamentos ().getTotalPensaoCartoral ().setConteudo (totalizarPagamentos (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.PAGAMENTO_PENSAODIVORCIO_BR, Pagamento.PAGAMENTO_PENSAODIVORCIO_EX }, true, true));
  }
  
  private void calculaTotalDeducoesInstrucao ()
  {
    Valor valTotalDespesasInstrucao = new Valor ();
    Valor despesasInstrucaoPropria = new Valor ();
    despesasInstrucaoPropria.setConteudo (totalizarPagamentos (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.TIPO_TITULAR, Pagamento.TIPO_TITULAR }, new String[] { Pagamento.PAGAMENTO_INSTRUCAO_BR, Pagamento.PAGAMENTO_INSTRUCAO_EX }, true));
    if (despesasInstrucaoPropria.comparacao (">", Pagamento.LIMITE_DESPESAS_INSTRUCAO))
      despesasInstrucaoPropria.setConteudo (Pagamento.LIMITE_DESPESAS_INSTRUCAO);
    Valor despesasInstrucaoDep = new Valor ();
    despesasInstrucaoDep.setConteudo (totalizarPagamentosPorBeneficiarioComLimite (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.TIPO_DEPENDENTE, Pagamento.TIPO_DEPENDENTE }, new String[] { Pagamento.PAGAMENTO_INSTRUCAO_BR, Pagamento.PAGAMENTO_INSTRUCAO_EX }));
    Valor despesasInstrucaoAlimentando = new Valor ();
    despesasInstrucaoAlimentando.setConteudo (totalizarPagamentosPorBeneficiarioComLimite (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.TIPO_ALIMENTANDO, Pagamento.TIPO_ALIMENTANDO }, new String[] { Pagamento.PAGAMENTO_INSTRUCAO_BR, Pagamento.PAGAMENTO_INSTRUCAO_EX }));
    valTotalDespesasInstrucao.append ('+', despesasInstrucaoPropria);
    valTotalDespesasInstrucao.append ('+', despesasInstrucaoDep);
    valTotalDespesasInstrucao.append ('+', despesasInstrucaoAlimentando);
    declaracaoIRPF.getPagamentos ().getTotalDeducoesInstrucao ().setConteudo (valTotalDespesasInstrucao);
  }
  
  private void calculaTotalContribuicaoFAPI ()
  {
    Valor contribPrevPrivadaFAPI = new Valor ();
    contribPrevPrivadaFAPI.setConteudo (totalizarPagamentos (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.PAGAMENTO_PREVIPRIVADA, Pagamento.PAGAMENTO_FAPI }, false, true));
    if (contribPrevPrivadaFAPI.comparacao (">", declaracaoIRPF.getResumo ().getRendimentosTributaveisDeducoes ().getTotalRendimentos ().operacao ('*', Pagamento.PERC_LIMITE_DEDUCAO_CONTRIBUICAO_PREV_PRIV_FAPI)))
      contribPrevPrivadaFAPI.setConteudo (declaracaoIRPF.getResumo ().getRendimentosTributaveisDeducoes ().getTotalRendimentos ().operacao ('*', Pagamento.PERC_LIMITE_DEDUCAO_CONTRIBUICAO_PREV_PRIV_FAPI));
    declaracaoIRPF.getPagamentos ().getTotalContribuicaoFAPI ().setConteudo (contribPrevPrivadaFAPI);
  }
  
  private void calculaTotalDespesasMedicas ()
  {
    Valor totalDespMedicas = totalizarPagamentos (declaracaoIRPF.getPagamentos (), new String[] { Pagamento.PAGAMENTO_FONOAUDIOLOGO_BR, Pagamento.PAGAMENTO_FONOAUDIOLOGO_EX, Pagamento.PAGAMENTO_MEDICO_BR, Pagamento.PAGAMENTO_MEDICO_EX, Pagamento.PAGAMENTO_DENTISTA_BR, Pagamento.PAGAMENTO_DENTISTA_EX, Pagamento.PAGAMENTO_PSICOLOGO_BR, Pagamento.PAGAMENTO_PSICOLOGO_EX, Pagamento.PAGAMENTO_FISIOTERAPEUTA_BR, Pagamento.PAGAMENTO_FISIOTERAPEUTA_EX, Pagamento.PAGAMENTO_TERAPEUTA_OCUPACIONAL_BR, Pagamento.PAGAMENTO_TERAPEUTA_OCUPACIONAL_EX, Pagamento.PAGAMENTO_HOSPITAL_BR, Pagamento.PAGAMENTO_HOSPITAL_EX, Pagamento.PAGAMENTO_PLANOSAUDE_BR }, true, false);
    declaracaoIRPF.getPagamentos ().getTotalDespesasMedicas ().setConteudo (totalDespMedicas);
  }
  
  public static Valor totalizarPagamentosGlosado (Pagamentos pagamentos, String[] codigo, boolean abateParcelaNaoDedutivel)
  {
    Valor result = totalizarPagamentos (pagamentos, codigo, abateParcelaNaoDedutivel, true);
    if (result.comparacao ("<", "0,00"))
      result.clear ();
    return result;
  }
  
  public static Valor totalizarPagamentos (Pagamentos pagamentos, String[] tipo, String[] codigo, boolean abateParcelaNaoDedutivel)
  {
    Valor total = new Valor ();
    List objColecao = pagamentos.recuperarLista ();
    for (int i = 0; i <= pagamentos.recuperarLista ().size () - 1; i++)
      {
	Pagamento obj = (Pagamento) objColecao.get (i);
	for (int j = 0; j < codigo.length; j++)
	  {
	      if (obj.getTipo ().toString ().equals (tipo[j]) && obj.getCodigo ().toString ().equals (codigo[j]) && obj.getValorPago ().comparacao (">=", obj.getParcelaNaoDedutivel ()))
	      {
		total.append ('+', obj.getValorPago ());
		if (abateParcelaNaoDedutivel)
		  total.append ('-', obj.getParcelaNaoDedutivel ());
	      }
	  }
      }
    return total;
  }
  
  public static Valor totalizarPagamentos (Pagamentos pagamentos, String[] codigo, boolean abateParcelaNaoDedutivel, boolean omite_alimentando)
  {
    Valor total = new Valor ();
    List objColecao = pagamentos.recuperarLista ();
    for (int i = 0; i <= pagamentos.recuperarLista ().size () - 1; i++)
      {
	Pagamento obj = (Pagamento) objColecao.get (i);
	for (int j = 0; j < codigo.length; j++)
	  {
	      if (obj.getCodigo ().toString ().equals (codigo[j]) && obj.getValorPago ().comparacao (">=", obj.getParcelaNaoDedutivel ()) && (! obj.getTipo ().toString ().equals (Pagamento.TIPO_ALIMENTANDO) || ! omite_alimentando))
	      {
		total.append ('+', obj.getValorPago ());
		if (abateParcelaNaoDedutivel)
		  total.append ('-', obj.getParcelaNaoDedutivel ());
	      }
	  }
      }
    return total;
  }
  
  public static Valor totalizarPagamentos (Pagamentos pagamentos)
  {
    Valor total = new Valor ();
    List objColecao = pagamentos.recuperarLista ();
    for (int i = 0; i <= pagamentos.recuperarLista ().size () - 1; i++)
      {
	Pagamento obj = (Pagamento) objColecao.get (i);
	total.append ('+', obj.getValorPago ());
      }
    return total;
  }
  
  public static Valor totalizarPagamentosPorBeneficiarioComLimite (Pagamentos pagamentos, String[] tipo, String[] codigo)
  {
    Valor retorno = new Valor ();
    java.util.Map mapBeneficiarios = new Hashtable ();
    List objColecao = pagamentos.recuperarLista ();
    class Beneficiario
    {
      public String nome = null;
      public Valor total = new Valor ();
      
      public Beneficiario (String pNome)
      {
	nome = pNome;
      }
    };
    for (int i = 0; i <= pagamentos.recuperarLista ().size () - 1; i++)
      {
	Pagamento obj = (Pagamento) objColecao.get (i);
	for (int j = 0; j < codigo.length; j++)
	  {
	    if (obj.getTipo ().toString (). equals (tipo[j]) && obj.getCodigo ().toString ().equals (codigo[j]))
	      {
		Beneficiario beneficiario = null;
		if (! mapBeneficiarios.containsKey (obj.getDependenteOuAlimentando ().asString ()))
		  {
		    beneficiario = new Beneficiario (obj.getDependenteOuAlimentando ().asString ());
		    mapBeneficiarios.put (beneficiario.nome, beneficiario);
		  }
		else
		  beneficiario = (Beneficiario) mapBeneficiarios.get (obj.getDependenteOuAlimentando ().asString ());
		if (obj.getValorPago ().comparacao (">=", obj.getParcelaNaoDedutivel ()))
		  {
		    beneficiario.total.append ('+', obj.getValorPago ());
		    beneficiario.total.append ('-', obj.getParcelaNaoDedutivel ());
		  }
	      }
	  }
      }
    Iterator it = mapBeneficiarios.values ().iterator ();
    while (it.hasNext ())
      {
	Beneficiario b = (Beneficiario) it.next ();
	if (b.total.comparacao (">", Pagamento.LIMITE_DESPESAS_INSTRUCAO))
	  b.total.setConteudo (Pagamento.LIMITE_DESPESAS_INSTRUCAO);
	retorno.append ('+', b.total);
      }
    return retorno;
  }
}
