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

import java.math.BigInteger;
import java.util.Collection;

import com.google.common.math.BigIntegerMath;

import de.ivu.elect.business.ergebniskonflikt.control.util.SublistList;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.wahlvorschlag.entity.Listenverbindung;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

/**
 * CustomData für einen ErgebnisKonflikt, bei dem der Losentscheid eine Auswahl aus einer gegebenen Menge von Gebieten trifft. Die Größe der Auswahl ist vorgegeben (meist 1).
 * <p/>
 * Die Reihenfolge spielt dabei weder bei den Gebieten zur Auswahl noch bei den gelosten Gebieten eine zwingende Rolle. Trotzdem wird mit Hilfe von LinkedHashMaps versucht, die Reihenfolge des
 * Einfügens beizubehalten, um ein deterministisches Verhalten zu ermöglichen.
 */
public class GebieteAuswaehlenErgebnisKonfliktCustomData extends AbstractGebieteErgebnisKonfliktCustomData {

  private static final long serialVersionUID = 9142478962621850461L;

  @Override
  public String getClassName() {
    return GebieteAuswaehlenErgebnisKonfliktCustomData.class.getName();
  }

  /**
   * Sortiere die Gebiete nach dem PK und nimm die ersten davon
   */
  @Override
  public void loeseKonfliktAutomatisch() {
    setGelosteGebietPKs(waehleDieErstenAus(getAnzahlZuLosen(), getBeteiligteGebietPKs()));
  }

  @Override
  public void loeseKonfliktAutomatisch(int indexDerLoesung) {
    setGelosteGebietPKs(new SublistList<>(asSortedList(getBeteiligteGebietPKs()), (int) getAnzahlZuLosen()).get(indexDerLoesung));
  }

  @Override
  public void loeseKonfliktAutomatischZyklisch(int indexDerLoesung) {
    setGelosteGebietPKs(waehleZyklischAus(indexDerLoesung, getAnzahlZuLosen(), getBeteiligteGebietPKs()));
  }

  @Override
  public BigInteger getAnzahlLoesungen() {
    return BigIntegerMath.binomial(getAnzahlZyklischerLoesungen(), (int) getAnzahlZuLosen());
  }

  @Override
  public int getAnzahlZyklischerLoesungen() {
    return getBeteiligteGebietPKs().size();
  }

  @Override
  public String createLoesungBeschreibung(ErgebnisKonfliktCustomDataFormatter ergebnisKonfliktCustomDataFormatter, Collection<Wahlvorschlag> wahlvorschlaege, Collection<Kandidatur> kandidaturen,
      Collection<Listenverbindung> listenverbindungen, Collection<PolitischeGruppe> politischeGruppen, Collection<Wahldurchfuehrungsgebiet> gebiete) {
    return createLoesungBeschreibung(ergebnisKonfliktCustomDataFormatter, gebiete, getGelosteGebietPKs());
  }
}
