
package de.ivu.elect.was.sitzberechnung.boundary;

import java.text.NumberFormat;
import java.util.Locale;

import javax.annotation.Nullable;

import de.ivu.elect.business.verteilung.boundary.VerteilungContext;
import de.ivu.elect.business.verteilung.boundary.VerteilungQuotient;
import de.ivu.elect.sitzberechnung.math.Fraction;
import de.ivu.elect.sitzberechnung.math.FractionConverter;
import de.ivu.elect.sitzberechnung.verteilung.dhondt.DHondtQuotient;

public class ElectVerteilungQuotient implements VerteilungQuotient {

  private final Long zaehlerGanzzahlig;

  private final Long nennerGanzzahlig;

  private final Fraction nennerDezimal;

  private final boolean nennerDezimalExakt;

  private final Fraction quote;

  private final boolean sitzgewinn;

  private final boolean relevantInLosverfahren;

  private final boolean ausgewaehlt;

  public ElectVerteilungQuotient(FractionConverter fractionConverter, DHondtQuotient dHondtQuotient) {
    this(dHondtQuotient.getZaehler(), dHondtQuotient.getNenner(), null, false, dHondtQuotient.toFraction(fractionConverter), dHondtQuotient.isSitzgewinn(), dHondtQuotient.isTeilnehmerAmLosverfahren(),
        false);
  }

  public ElectVerteilungQuotient(Long zaehler, Fraction nenner, boolean nennerExakt, Fraction quote, boolean ausgewaehlt) {
    this(zaehler, null, nenner, nennerExakt, quote, false, false, ausgewaehlt);
  }

  public ElectVerteilungQuotient(Long zaehler, Fraction nenner, boolean nennerExakt, Fraction quote, boolean sitzgewinn, boolean relevantInLosverfahren) {
    this(zaehler, null, nenner, nennerExakt, quote, sitzgewinn, relevantInLosverfahren, false);
  }

  private ElectVerteilungQuotient(Long zaehler, @Nullable Long nennerGanzzahlig, @Nullable Fraction nennerDezimal, boolean nennerDezimalExakt, Fraction quote, boolean sitzgewinn,
      boolean relevantInLosverfahren, boolean ausgewaehlt) {
    super();

    this.zaehlerGanzzahlig = zaehler;

    this.nennerGanzzahlig = nennerGanzzahlig;
    this.nennerDezimal = nennerDezimal;
    this.nennerDezimalExakt = nennerDezimalExakt;

    this.quote = quote;

    this.sitzgewinn = sitzgewinn;

    this.relevantInLosverfahren = relevantInLosverfahren;

    this.ausgewaehlt = ausgewaehlt;
  }

  @Override
  public boolean isRelevantInSitzvergabe() {
    return isSitzgewinn() || isRelevantInLosverfahren();
  }

  @Override
  public boolean isSitzgewinn() {
    return sitzgewinn;
  }

  @Override
  public boolean isRelevantInLosverfahren() {
    return relevantInLosverfahren;
  }

  @Override
  public boolean isAusgewaehlt() {
    return ausgewaehlt;
  }

  @Override
  public String formatDezimal(VerteilungContext context) {
    return context.formatBruchDezimal(quote);
  }

  @Override
  public String formatGemein(VerteilungContext context) {
    Locale locale = context.getLocale();

    NumberFormat numberFormat = NumberFormat.getInstance(locale);

    String zaehlerFormatted = numberFormat.format(zaehlerGanzzahlig);
    String nennerFormatted = null;

    if (nennerGanzzahlig != null) {
      nennerFormatted = numberFormat.format(nennerGanzzahlig);
    } else {
      if (nennerDezimalExakt) { // ... dann dezimalen Nenner unkonvertiert (wie übergeben) ausgeben
        nennerFormatted = numberFormat.format(nennerDezimal);
      } else { // ... dezimalen Nenner konvertiert ausgeben
        nennerFormatted = context.formatBruchDezimal(nennerDezimal);
      }
    }

    return VerteilungContext.formatBruchGemein(zaehlerFormatted, nennerFormatted);
  }
}
