
package de.ivu.elect.business.ergebnis.entity;

import java.io.Serializable;
import java.math.BigDecimal;

import javax.annotation.Nullable;

import de.ivu.elect.business.gebietsbaum.entity.GebietPK;
import de.ivu.elect.business.gebietsbaum.entity.GebietUK;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.jee.entity.AbstractNoPersistentEntity;
import de.ivu.elect.presentation.system.PercentUtil;

/**
 *  on 23.10.2015.
 */
public class ParteienwechselSearchResult extends AbstractNoPersistentEntity<GebietPK, GebietUK> implements KumulierteStimmen, Serializable {

  private static final long serialVersionUID = 1L;

  private final Long laufendeNummer;

  private final Wahldurchfuehrungsgebiet wahlkreis;

  private final PolitischeGruppe aktuellerGewinner;

  private final PolitischeGruppe vorperiodeGewinner;

  private final Long anzahlStimmenGueltigAktuell;

  private final Long anzahlStimmenGueltigVorperiode;

  private final Long anzahlStimmenAktuellerGewinnerAktuell;

  private final Long anzahlStimmenAktuellerGewinnerVorperiode;

  private final Long anzahlStimmenVorperiodeGewinnerAktuell;

  private final Long anzahlStimmenVorperiodeGewinnerVorperiode;

  public ParteienwechselSearchResult(Long laufendeNummer, ParteienwechselSearchResult result) {
    this(laufendeNummer, result.getWahlkreis(), result.getAktuellerGewinner(), result.getVorperiodeGewinner(),
        result.getAnzahlStimmenGueltigAktuell(), result.getAnzahlStimmenGueltigVorperiode(),
        result.getAnzahlStimmenAktuellerGewinnerAktuell(), result.getAnzahlStimmenAktuellerGewinnerVorperiode(),
        result.getAnzahlStimmenVorperiodeGewinnerAktuell(), result.getAnzahlStimmenVorperiodeGewinnerVorperiode());
  }

  public ParteienwechselSearchResult(Wahldurchfuehrungsgebiet wahlkreis, PolitischeGruppe aktuellerGewinner,
      PolitischeGruppe vorperiodeGewinner, Long anzahlStimmenGueltigAktuell, Long anzahlStimmenGueltigVorperiode,
      Long anzahlStimmenAktuellerGewinnerAktuell, Long anzahlStimmenAktuellerGewinnerVorperiode,
      Long anzahlStimmenVorperiodeGewinnerAktuell, Long anzahlStimmenVorperiodeGewinnerVorperiode) {
    this(null, wahlkreis, aktuellerGewinner, vorperiodeGewinner, anzahlStimmenGueltigAktuell, anzahlStimmenGueltigVorperiode,
        anzahlStimmenAktuellerGewinnerAktuell, anzahlStimmenAktuellerGewinnerVorperiode, anzahlStimmenVorperiodeGewinnerAktuell,
        anzahlStimmenVorperiodeGewinnerVorperiode);
  }

  public ParteienwechselSearchResult(Long laufendeNummer, Wahldurchfuehrungsgebiet wahlkreis, PolitischeGruppe aktuellerGewinner,
      PolitischeGruppe vorperiodeGewinner, Long anzahlStimmenGueltigAktuell, Long anzahlStimmenGueltigVorperiode,
      Long anzahlStimmenAktuellerGewinnerAktuell, Long anzahlStimmenAktuellerGewinnerVorperiode,
      Long anzahlStimmenVorperiodeGewinnerAktuell, Long anzahlStimmenVorperiodeGewinnerVorperiode) {
    super();

    this.laufendeNummer = laufendeNummer;
    this.wahlkreis = wahlkreis;
    this.aktuellerGewinner = aktuellerGewinner;
    this.vorperiodeGewinner = vorperiodeGewinner;
    this.anzahlStimmenGueltigAktuell = anzahlStimmenGueltigAktuell;
    this.anzahlStimmenGueltigVorperiode = anzahlStimmenGueltigVorperiode;
    this.anzahlStimmenAktuellerGewinnerAktuell = anzahlStimmenAktuellerGewinnerAktuell;
    this.anzahlStimmenAktuellerGewinnerVorperiode = anzahlStimmenAktuellerGewinnerVorperiode;
    this.anzahlStimmenVorperiodeGewinnerAktuell = anzahlStimmenVorperiodeGewinnerAktuell;
    this.anzahlStimmenVorperiodeGewinnerVorperiode = anzahlStimmenVorperiodeGewinnerVorperiode;
  }

  @Override
  public Long getId() {
    return wahlkreis.getId();
  }

  @Override
  public GebietPK getPk() {
    return wahlkreis.getPk();
  }

  @Override
  public GebietUK getUk() {
    return wahlkreis.getUk();
  }

  public PolitischeGruppe getAktuellerGewinner() {
    return aktuellerGewinner;
  }

  public Long getAnzahlStimmenGueltigAktuell() {
    return anzahlStimmenGueltigAktuell;
  }

  public Long getAnzahlStimmenGueltigVorperiode() {
    return anzahlStimmenGueltigVorperiode;
  }

  public Long getAnzahlStimmenAktuellerGewinnerAktuell() {
    return anzahlStimmenAktuellerGewinnerAktuell;
  }

  public Long getAnzahlStimmenAktuellerGewinnerVorperiode() {
    return anzahlStimmenAktuellerGewinnerVorperiode;
  }

  public Long getAnzahlStimmenVorperiodeGewinnerAktuell() {
    return anzahlStimmenVorperiodeGewinnerAktuell;
  }

  public Long getAnzahlStimmenVorperiodeGewinnerVorperiode() {
    return anzahlStimmenVorperiodeGewinnerVorperiode;
  }

  public Long getLaufendeNummer() {
    return laufendeNummer;
  }

  public PolitischeGruppe getVorperiodeGewinner() {
    return vorperiodeGewinner;
  }

  public Wahldurchfuehrungsgebiet getWahlkreis() {
    return wahlkreis;
  }

  public boolean isWechsel() {
    return aktuellerGewinner == null && vorperiodeGewinner != null
        || aktuellerGewinner != null && !aktuellerGewinner.equals(vorperiodeGewinner);
  }

  public BigDecimal getStimmenanteilAktuellGewinnerAktuell() {
    return getStimmenanteil(getAnzahlStimmenGueltigAktuell(), getAnzahlStimmenAktuellerGewinnerAktuell());
  }

  private BigDecimal getStimmenanteilVorperiodeGewinnerAktuell() {
    return getStimmenanteil(getAnzahlStimmenGueltigVorperiode(), getAnzahlStimmenVorperiodeGewinnerAktuell());
  }

  public BigDecimal getStimmenanteilAktuellGewinnerVorperiode() {
    return getStimmenanteil(getAnzahlStimmenGueltigAktuell(), getAnzahlStimmenAktuellerGewinnerVorperiode());
  }

  private BigDecimal getStimmenanteilVorperiodeGewinnerVorperiode() {
    return getStimmenanteil(getAnzahlStimmenGueltigVorperiode(), getAnzahlStimmenVorperiodeGewinnerVorperiode());
  }

  @Nullable
  public BigDecimal getGewinnVerlustGewinnerAktuell() {
    if (getStimmenanteilAktuellGewinnerAktuell() == null || getStimmenanteilVorperiodeGewinnerAktuell() == null) {
      return null;
    }

    return getStimmenanteilAktuellGewinnerAktuell().subtract(getStimmenanteilVorperiodeGewinnerAktuell());
  }

  @Nullable
  public BigDecimal getGewinnVerlustGewinnerVorperiode() {
    if (getStimmenanteilAktuellGewinnerVorperiode() == null || getStimmenanteilVorperiodeGewinnerVorperiode() == null) {
      return null;
    }

    return getStimmenanteilAktuellGewinnerVorperiode().subtract(getStimmenanteilVorperiodeGewinnerVorperiode());
  }

  private BigDecimal getStimmenanteil(Long alle, Long anteil) {
    return PercentUtil.percent(alle, anteil);
  }
}
