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

import java.util.Comparator;

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

/**
 * Das Ergebnis der Verteilung nach Hare-Niemeyer für einen der Teilnehmer. Dieses beinhaltet die Anzahl Sitze aus
 * Abrundung, Restsitzverteilung und (ggf. auf die Hare-Niemeyer-Verteilung folgend) Losverfahren. Es ist Teil eines
 * {@link HareNiemeyerErgebnis}es. Einzige spätere Modifikation (nach der eigentlichen Verteilung) kann durch Verteilung
 * bei Restegleichheit (meist per Los) mit der Methode {@link #entscheideLosverfahren(long)} erfolgen.
 */
public class HareNiemeyerTeilnehmerErgebnis extends TeilnehmerErgebnis {

  public static Comparator<HareNiemeyerTeilnehmerErgebnis> SORT_BY_REST = new Comparator<HareNiemeyerTeilnehmerErgebnis>() {

    @Override
    public int compare(HareNiemeyerTeilnehmerErgebnis x, HareNiemeyerTeilnehmerErgebnis y) {
      // Größter Rest zuerst
      return y.getRest().compareTo(x.getRest());
    }
  };

  private final Fraction rest;

  /**
   * @return Ergebnis eines Teilnehmers, wenn keine richtige Verteilung stattgefunden hat
   */
  static HareNiemeyerTeilnehmerErgebnis ohneVerteilung(Teilnehmer teilnehmer) {
    return new HareNiemeyerTeilnehmerErgebnis(teilnehmer);
  }

  HareNiemeyerTeilnehmerErgebnis(Teilnehmer teilnehmer, Fraction divisor) {
    super(teilnehmer, divisor);
    this.rest = quote.subtract(sitzeAusAbrundung);
  }

  private HareNiemeyerTeilnehmerErgebnis(Teilnehmer teilnehmer) {
    super(teilnehmer);
    this.rest = Fraction.ZERO;
  }

  /**
   * @return den nicht-ganzzahligen Anteil von {@link #getQuote()}
   */
  public Fraction getRest() {
    return rest;
  }

  public long getSitzeMaximal() {
    if (isEntschieden) {
      return getSitze();
    } else {
      // Könnte noch einen Sitz per Los gewinnen
      return getSitze() + 1;
    }
  }

  public long getSitzeMinimal() {
    return getSitze();
  }

  @Override
  protected void vergibRestsitz() {
    // Diese Methode gibt es nur, um zu verhindern, dass sie in der Oberklasse public sein muss.  
    super.vergibRestsitz();
  }

  @Override
  protected void seiTeilnehmerAmLosverfahren() {
    // Diese Methode gibt es nur, um zu verhindern, dass sie in der Oberklasse public sein muss.  
    super.seiTeilnehmerAmLosverfahren();
  }
}
