
package de.ivu.elect.business.sitzberechnung.control.niemeyer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import de.ivu.elect.business.sitzberechnung.control.util.Fraction;
import de.ivu.elect.business.sitzberechnung.control.verteilung.AbstractVerteilungsErgebnis;
import de.ivu.elect.business.sitzberechnung.control.verteilung.Teilnehmer;

/**
 * Das Ergebnis einer Sitzverteilung nach Hare-Niemeyer. Man erhält es nach Verteilung der abgerundeten Sitze und der
 * Restsitze von einer {@link HareNiemeyerVerteilung}. Durch eine evtl. spätere Verteilung nach Los (oder anderen
 * Kriterien) werden nachträglich noch Sitze vergeben und damit dieses Objekt modifiziert. Es enthält für jeden
 * Teilnehmer an der Verteilung ein {@link HareNiemeyerTeilnehmerErgebnis}, das ebenfalls noch durch spätere Verteilung
 * nach Los (oder anderen Kriterien) modifiziert werden kann.
 * 
 *
 */
public class HareNiemeyerErgebnis extends AbstractVerteilungsErgebnis<HareNiemeyerTeilnehmerErgebnis> {

  /**
   * @return Ergebnis der Verteilung, wenn keine richtige Verteilung stattgefunden hat
   */
  public static HareNiemeyerErgebnis ohneVerteilung(long anzahlSitze, List< ? extends Teilnehmer> dieTeilnehmer) {
    List<HareNiemeyerTeilnehmerErgebnis> teilnehmerErgebnisse = new ArrayList<>();
    for (Teilnehmer teilnehmer : dieTeilnehmer) {
      teilnehmerErgebnisse.add(HareNiemeyerTeilnehmerErgebnis.ohneVerteilung(teilnehmer));
    }

    return new HareNiemeyerErgebnis(anzahlSitze, teilnehmerErgebnisse);
  }

  /**
   * Ergebnis der HareNiemeyerErgebnis ohne dass ein Losverfahren nötig war
   */
  public HareNiemeyerErgebnis(long anzahlSitze, List<HareNiemeyerTeilnehmerErgebnis> teilnehmerErgebnisse) {
    this(anzahlSitze, teilnehmerErgebnisse, Collections.<HareNiemeyerTeilnehmerErgebnis> emptyList(), 0);
  }

  public HareNiemeyerErgebnis(long anzahlSitze, List<HareNiemeyerTeilnehmerErgebnis> teilnehmerErgebnisse,
      List<HareNiemeyerTeilnehmerErgebnis> teilnehmerAmLosverfahren, long anzahlSitzeZuVerlosen) {
    super(anzahlSitze, teilnehmerErgebnisse, teilnehmerAmLosverfahren, anzahlSitzeZuVerlosen);
  }

  /**
   * @return der Rest, mit dem der letzte Restsitz zugeteilt wurde. null, wenn kein Restsitz zugeteilt wurde.
   */
  public Fraction getLetzterRest() {
    Fraction min = null;
    for (HareNiemeyerTeilnehmerErgebnis teilnehmerErgebnis : getTeilnehmerErgebnisse()) {
      if (teilnehmerErgebnis.getRestsitze() > 0) {
        Fraction rest = teilnehmerErgebnis.getRest();
        if (min == null || min.compareTo(rest) > 0) {
          min = rest;
        }
      }
    }

    return min;
  }

}
