
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;
import de.ivu.elect.jee.faces.Messages;

/**
 * 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(Collection<Wahlvorschlag> wahlvorschlaege,
                                          Collection<Kandidatur> kandidaturen, Collection<Listenverbindung> listenverbindungen,
                                          Collection<PolitischeGruppe> politischeGruppen, Collection<Wahldurchfuehrungsgebiet> gebiete, Messages messages) {
    return createLoesungBeschreibung(gebiete, getGelosteGebietPKs());
  }

}
