
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 politischen Gruppen trifft. Die Größe der Auswahl ist vorgegeben (meist 1).
 * <p/>
 * Die Reihenfolge spielt dabei weder bei den politischen Gruppen zur Auswahl noch bei den gelosten politischen Gruppen 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 PolitischeGruppenAuswaehlenErgebnisKonfliktCustomData extends AbstractPolitischeGruppenErgebnisKonfliktCustomData {

  private static final long serialVersionUID = 9142478962621850461L;

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

  /**
   * Sortiere die politischen Gruppen nach dem PK und nimm die ersten davon
   */
  @Override
  public void loeseKonfliktAutomatisch() {
    setGelostePolitischeGruppenPKs(waehleDieErstenAus(getAnzahlZuLosen(), getBeteiligtePolitischeGruppenPKs()));
  }

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

  @Override
  public void loeseKonfliktAutomatischZyklisch(int indexDerLoesung) {
    setGelostePolitischeGruppenPKs(waehleZyklischAus(indexDerLoesung, getAnzahlZuLosen(), getBeteiligtePolitischeGruppenPKs()));
  }

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

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

  @Override
  public String createLoesungBeschreibung(ErgebnisKonfliktCustomDataFormatter ergebnisKonfliktCustomDataFormatter, Collection<Wahlvorschlag> ignore1, Collection<Kandidatur> ignore2,
      Collection<Listenverbindung> ignore3, Collection<PolitischeGruppe> politischeGruppen, Collection<Wahldurchfuehrungsgebiet> ignore4) {
    return createLoesungBeschreibung(ergebnisKonfliktCustomDataFormatter, politischeGruppen, getGelostePolitischeGruppenPKs());
  }
}
