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

import serpro.ppgd.irpf.DeclaracaoIRPF;
import serpro.ppgd.negocio.Colecao;
import serpro.ppgd.negocio.NI;
import serpro.ppgd.negocio.ObjetoNegocio;
import serpro.ppgd.negocio.Valor;

public class Pagamentos extends Colecao
{
  public static final String VALOR_PAGO_ALTO = "50.000,00";
  private transient DeclaracaoIRPF objDecl;
  private Valor totalDeducoesInstrucao;
  private Valor totalContribuicaoFAPI;
  private Valor totalDespesasMedicas;
  private Valor totalPensao;
  private Valor totalPensaoCartoral;
  private Valor totalDeducaoIncentivo;
  
  public Pagamentos (DeclaracaoIRPF objDecl)
  {
    super (serpro.ppgd.irpf.pagamentos.Pagamento.class.getName ());
    totalDeducoesInstrucao = new Valor (this, "");
    totalContribuicaoFAPI = new Valor (this, "");
    totalDespesasMedicas = new Valor (this, "");
    totalPensao = new Valor (this, "");
    totalPensaoCartoral = new Valor (this, "");
    totalDeducaoIncentivo = new Valor (this, "");
    this.objDecl = objDecl;
    setFicha ("Pagamentos e Doa\u00e7\u00f5es Efetuados");
  }
  
  public void objetoInserido (Object o)
  {
    ((ObjetoNegocio) o).setFicha (getFicha ());
  }
  
  public ObjetoNegocio instanciaNovoObjeto ()
  {
    return new Pagamento (objDecl);
  }
  
  public Valor getTotalDeducoesInstrucao ()
  {
    return totalDeducoesInstrucao;
  }
  
  public Valor getTotalContribuicaoFAPI ()
  {
    return totalContribuicaoFAPI;
  }
  
  public Valor getTotalDespesasMedicas ()
  {
    return totalDespesasMedicas;
  }
  
  public Valor getTotalPensao ()
  {
    return totalPensao;
  }
  
  public Valor getTotalPensaoCartoral ()
  {
    return totalPensaoCartoral;
  }
  
  public Valor getTotalDeducaoIncentivo ()
  {
    return totalDeducaoIncentivo;
  }
  
  public String recuperarCpfMaiorPensaoAlimenticia ()
  {
    Iterator it = recuperarLista ().iterator ();
    String cpfMaior = "";
    Valor maiorValor = null;
    while (it.hasNext ())
      {
	Pagamento pgto = (Pagamento) it.next ();
	if (pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_PENSAOALIMENTICIA_BR)
	    || pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_PENSAOALIMENTICIA_EX))
	  {
	    if (maiorValor == null)
	      {
		maiorValor = pgto.getValorPago ();
		cpfMaior = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	    else if (pgto.getValorPago ().comparacao (">", maiorValor))
	      {
		maiorValor = pgto.getValorPago ();
		cpfMaior = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	  }
      }
    return cpfMaior;
  }
  
  private class Beneficiario
  {
    public Valor total;
    public String ni;
    private boolean shared = true;
    public Beneficiario (Valor total, NI ni)
    {
      this.total = total;
      this.ni = ni.asString ();
    }
    public Beneficiario (Pagamento pgto)
    {
      this.total = new Valor ();
      this.total.append ('+', pgto.getValorPago ());
      this.total.append ('-', pgto.getParcelaNaoDedutivel ());
      this.ni = pgto.getNiBeneficiario ().asString ();
    }
    public void soma (Beneficiario outro)
    {
      if (shared)
	{
	  Valor v = new Valor ();
	  v.append ('+', total);
	  total = v;
	  shared = false;
	}
      total.append ('+', outro.total);
    }
  };

  private class FiltroDePagamento
  {
    /* Especialize este método para filtrar pagamentos.  Retorne null
       para os que não devem ser considerados.  Para os demais,
       construa um Beneficiario com a chave que deve ser usada para
       agrupar pagamentos, e com o valor que deve ser considerado.  */
    Beneficiario seleciona (Pagamento pgto)
    {
      return new Beneficiario (pgto);
    }
  }

  /* Para cada Pagamento para qual o filtro devolter um Beneficiario
     não-nulo, preenche pgtos[] com os NIs correspondentes aos maiores
     pagamentos agrupados por NI.  O filtro pode criar o Beneficiario
     com uma chave que não seja necessariamente o NI do Pagamento, e
     com um valor diferente daquele do Pagamento.  */
  private String[] OrdenarPagamentos (int n, FiltroDePagamento filtro)
  {
    Hashtable agrupado = new Hashtable ();
    Iterator it = recuperarLista ().iterator ();
    while (it.hasNext ())
      {
	Pagamento pgto = (Pagamento) it.next ();
	Beneficiario nbene = filtro.seleciona (pgto);
	if (nbene != null)
	  {
	    Beneficiario bene = (Beneficiario) agrupado.get (nbene.ni);
	    if (bene == null)
	      {
		bene = nbene;
		agrupado.put (bene.ni, bene);
	      }
	    else
	      bene.soma (nbene);
	  }
      }

    String[] pgtos = new String[n];
    it = agrupado.values ().iterator ();
    while (it.hasNext ())
      {
	Beneficiario bene = (Beneficiario) it.next ();
	for (int i = 0; i < n; i++)
	  if (pgtos[i] == null
	      || bene.total.comparacao (">", ((Beneficiario) agrupado.get
					      (pgtos[i])).total))
	    {
	      String ni = bene.ni;
	      for (; i < n; i++)
		{
		  String save = pgtos[i];
		  pgtos[i] = ni;
		  ni = save;
		}
	      break;
	    }
      }

    return pgtos;
  }

  public String[] recuperarNiMaioresPagamentosDedutiveis (int n)
  {
    String[] pgtos = OrdenarPagamentos (n, new FiltroDePagamento() {
	Beneficiario seleciona (Pagamento pgto) {
	  if (pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_INSTRUCAO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_INSTRUCAO_EX)
	      || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_FONOAUDIOLOGO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_MEDICO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_DENTISTA_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_PSICOLOGO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_FISIOTERAPEUTA_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_TERAPEUTA_OCUPACIONAL_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_HOSPITAL_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_PLANOSAUDE_BR)
	      || pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_PREVIPRIVADA) || pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_FAPI))
	    return super.seleciona (pgto);
	  return null;
	}
      });

    return pgtos;
  }

  public String recuperarCnpjMaiorPagamentoFunpresp ()
  {
    Iterator it = recuperarLista ().iterator ();
    String cpfMaior = "";
    Valor maiorValor = null;
    while (it.hasNext ())
      {
	Pagamento pgto = (Pagamento) it.next ();
	if (pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_FUNPRESP))
	  {
	    if (maiorValor == null)
	      {
		maiorValor = pgto.getValorPago ();
		cpfMaior = pgto.getNiBeneficiario ().asString ();
	      }
	    else if (pgto.getValorPago ().comparacao (">", maiorValor))
	      {
		maiorValor = pgto.getValorPago ();
		cpfMaior = pgto.getNiBeneficiario ().asString ();
	      }
	  }
      }
    return cpfMaior;
  }
  
  public String recuperarCNPJMaiorPrevComplementar ()
  {
    Iterator it = recuperarLista ().iterator ();
    String cnpjMaior = "";
    Valor maiorValor = null;
    while (it.hasNext ())
      {
	Pagamento pgto = (Pagamento) it.next ();
	if (pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_PREVIPRIVADA)
	    || pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_FAPI))
	  {
	    if (maiorValor == null)
	      {
		maiorValor = pgto.getValorPago ();
		cnpjMaior = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	    else if (pgto.getValorPago ().comparacao (">", maiorValor))
	      {
		maiorValor = pgto.getValorPago ();
		cnpjMaior = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	  }
      }
    return cnpjMaior;
  }
  
  public String recuperarCNPJSegundaMaiorPrevComplementar ()
  {
    Iterator it = recuperarLista ().iterator ();
    String cnpjMaior = "";
    Valor maiorValor = null;
    String cnpjSegundo = "";
    Valor segundoValor = null;
    while (it.hasNext ())
      {
	Pagamento pgto = (Pagamento) it.next ();
	if (pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_PREVIPRIVADA)
	    || pgto.getCodigo ().asString ().equals (Pagamento.PAGAMENTO_FAPI))
	  {
	    if (maiorValor == null)
	      {
		maiorValor = pgto.getValorPago ();
		cnpjMaior = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	    else if (pgto.getValorPago ().comparacao (">", maiorValor))
	      {
		segundoValor = maiorValor;
		cnpjSegundo = cnpjMaior;
		maiorValor = pgto.getValorPago ();
		cnpjMaior = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	    else if (segundoValor == null)
	      {
		segundoValor = pgto.getValorPago ();
		cnpjSegundo = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	    else if (pgto.getValorPago ().comparacao (">", segundoValor))
	      {
		segundoValor = pgto.getValorPago ();
		cnpjSegundo = pgto.getNiBeneficiario ().asString ().substring (0, 11);
	      }
	  }
      }
    return cnpjMaior;
  }
  
  public NI recuperarNIMaiorDespMedicas ()
  {
    Hashtable beneficiariosMedicas = new Hashtable ();
    List objColecao = recuperarLista ();
    class BeneficiarioMedico
    {
      public Valor total;
      public NI ni;
    };
    for (int i = 0; i < recuperarLista ().size (); i++)
      {
	Pagamento pgto = (Pagamento) objColecao.get (i);
	if (pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_FONOAUDIOLOGO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_MEDICO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_DENTISTA_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_PSICOLOGO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_FISIOTERAPEUTA_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_TERAPEUTA_OCUPACIONAL_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_HOSPITAL_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_PLANOSAUDE_BR))
	  {
	    Valor total = new Valor ();
	    if (pgto.getValorPago ().comparacao (">=", pgto.getParcelaNaoDedutivel ()))
	      {
		total.append ('+', pgto.getValorPago ());
		total.append ('-', pgto.getParcelaNaoDedutivel ());
	      }
	    // final String depalim = pgto.getDependenteOuAlimentando ().asString ();
	    final String key = pgto.getNiBeneficiario ().asString (); // + depalim;
	    BeneficiarioMedico medico = (BeneficiarioMedico) beneficiariosMedicas.get (key);
	    if (medico == null)
	      {
		medico = new BeneficiarioMedico ();
		medico.total = total;
		medico.ni = pgto.getNiBeneficiario ();
		beneficiariosMedicas.put (key, medico);
	      }
	    else
	      medico.total.append ('+', total);
	  }
      }
    Iterator it = beneficiariosMedicas.values ().iterator ();
    BeneficiarioMedico benefMaior = null;
    if (it.hasNext ())
      {
	benefMaior = (BeneficiarioMedico) it.next ();
	while (it.hasNext ())
	  {
	    BeneficiarioMedico aux = (BeneficiarioMedico) it.next ();
	    if (aux.total.comparacao (">", benefMaior.total))
	      benefMaior = aux;
	  }
      }
    if (benefMaior == null)
      return new NI (this, "");
    return benefMaior.ni;
  }
  
  public NI recuperarNISegundoMaiorDespMedicas ()
  {
    Hashtable beneficiariosMedicas = new Hashtable ();
    List objColecao = recuperarLista ();
    class BeneficiarioMedico
    {
      public Valor total;
      public NI ni;
    };
    for (int i = 0; i < recuperarLista ().size (); i++)
      {
	Pagamento pgto = (Pagamento) objColecao.get (i);
	if (pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_FONOAUDIOLOGO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_MEDICO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_DENTISTA_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_PSICOLOGO_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_FISIOTERAPEUTA_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_TERAPEUTA_OCUPACIONAL_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_HOSPITAL_BR) || pgto.getCodigo ().toString ().equals (Pagamento.PAGAMENTO_PLANOSAUDE_BR))
	  {
	    Valor total = new Valor ();
	    if (pgto.getValorPago ().comparacao (">=", pgto.getParcelaNaoDedutivel ()))
	      {
		total.append ('+', pgto.getValorPago ());
		total.append ('-', pgto.getParcelaNaoDedutivel ());
	      }
	    // final String depalim = pgto.getDependenteOuAlimentando ().asString ();
	    final String key = pgto.getNiBeneficiario ().asString (); // + depalim;
	    BeneficiarioMedico medico = (BeneficiarioMedico) beneficiariosMedicas.get (key);
	    if (medico == null)
	      {
		medico = new BeneficiarioMedico ();
		medico.total = total;
		medico.ni = pgto.getNiBeneficiario ();
		beneficiariosMedicas.put (key, medico);
	      }
	    else
	      medico.total.append ('+', total);
	  }
      }
    Iterator it = beneficiariosMedicas.values ().iterator ();
    BeneficiarioMedico benefMaior = null;
    BeneficiarioMedico segundoBenefMaior = null;
    if (it.hasNext ())
      {
	benefMaior = (BeneficiarioMedico) it.next ();
	while (it.hasNext ())
	  {
	    BeneficiarioMedico aux = (BeneficiarioMedico) it.next ();
	    if (aux.total.comparacao (">", benefMaior.total))
	      {
		segundoBenefMaior = benefMaior;
		benefMaior = aux;
	      }
	    else if (segundoBenefMaior == null || aux.total.comparacao (">", segundoBenefMaior.total))
	      segundoBenefMaior = aux;
	  }
      }
    if (segundoBenefMaior == null)
      return new NI (this, "");
    return segundoBenefMaior.ni;
  }
  
  public int obterTotalDependentesEnvolvidos ()
  {
    java.util.Set listaDependentes = new HashSet ();
    excluirRegistrosEmBranco ();
    Iterator itPagamentos = recuperarLista ().iterator ();
    while (itPagamentos.hasNext ())
      {
	Pagamento pagamento = (Pagamento) itPagamentos.next ();
	if (pagamento.ehDependenteBrasil () || pagamento.ehDependenteExterior ())
	  listaDependentes.add (pagamento.getDependenteOuAlimentando ().getConteudoFormatado ());
      }
    int tam = 0;
    if (! listaDependentes.isEmpty ())
      tam = listaDependentes.size ();
    return tam;
  }
  
  public int obterTotalAlimentandosEnvolvidos ()
  {
    java.util.Set listaDependentes = new HashSet ();
    excluirRegistrosEmBranco ();
    Iterator itPagamentos = recuperarLista ().iterator ();
    while (itPagamentos.hasNext ())
      {
	Pagamento pagamento = (Pagamento) itPagamentos.next ();
	if (pagamento.ehAlimentandoBrasil () || pagamento.ehAlimentandoExterior ())
	  listaDependentes.add (pagamento.getDependenteOuAlimentando ().getConteudoFormatado ());
      }
    int tam = 0;
    if (! listaDependentes.isEmpty ())
      tam = listaDependentes.size ();
    return tam;
  }
}
