package de.ivu.elect.business.hochrechnung.entity;

import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.commons.math3.random.RandomGenerator;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;

public class ZufaelligeAnzahlWahlberechtigteNormalverteilungKonfiguration {
  // Diese Konstante Zahlen orientieren sich an de.ivu.elect.business.stimmeingabe.control.fiktive.WahlberechtigteUndWaehlerStimmeingabenAusFiktivwertenSetzer

  private static final long WAHLBERECHTIGTE_GESAMT_URNENWAHL_MEAN = 900;
  private static final long WAHLBERECHTIGTE_GESAMT_URNENWAHL_STANDARD_DEVIATION = 200;
  private static final long WAHLBERECHTIGTE_GESAMT_URNENWAHL_MIN_PREVENTIG_ZEROS = 100;


  private static final double WAHLBERECHTIGTE_MIT_WAHLSCHEIN_URNENWAHL_ANTEIL_MEAN = 0.35;
  private static final double WAHLBERECHTIGTE_MIT_WAHLSCHEIN_URNENWAHL_ANTEIL_STANDARD_DEVIATION = 0.1;
  private static final double WAHLBERECHTIGTE_MIT_WAHLSCHEIN_URNENWAHL_MIN_PREVENTIG_ZEROS = 0.05;

  private static final double WAHLBERECHTIGTE_NICHT_IM_WAEHLEVERZEICHNIS_URNENWAHL_ANTEIL_MEAN = 0;
  private static final double WAHLBERECHTIGTE_NICHT_IM_WAEHLEVERZEICHNIS_URNENWAHL_ANTEIL_STANDARD_DEVIATION = 0.005;

  private final NormalDistribution normalDistributionFuerWahlberechtigteGesamtUrnenwahl;
  private final NormalDistribution normalDistributionFuerWahlberechtigteMitWahlscheinUrnenwahlAnteil;
  private final NormalDistribution normalDistributionFuerWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteil;

  public ZufaelligeAnzahlWahlberechtigteNormalverteilungKonfiguration(RandomGenerator randomGenerator) {
    this.normalDistributionFuerWahlberechtigteGesamtUrnenwahl = new NormalDistribution(randomGenerator, getWahlberechtigteGesamtUrnenwahlMean(), getWahlberechtigteGesamtUrnenwahlStandardDeviation());
    this.normalDistributionFuerWahlberechtigteMitWahlscheinUrnenwahlAnteil =  new NormalDistribution(randomGenerator, getWahlberechtigteMitWahlscheinUrnenwahlAnteilMean(), getWahlberechtigteMitWahlscheinUrnenwahlAnteilStandardDeviation());
    this.normalDistributionFuerWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteil =  new NormalDistribution(randomGenerator, getWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteilMean(), getWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteilStandardDeviation());
  }

  private long getWahlberechtigteGesamtUrnenwahlMean() {
    return WAHLBERECHTIGTE_GESAMT_URNENWAHL_MEAN;
  }

  private long getWahlberechtigteGesamtUrnenwahlStandardDeviation() {
    return WAHLBERECHTIGTE_GESAMT_URNENWAHL_STANDARD_DEVIATION;
  }

  public long getWahlberechtigteGesamtUrnenwahlMinPreventigZeros() {
    return WAHLBERECHTIGTE_GESAMT_URNENWAHL_MIN_PREVENTIG_ZEROS;
  }

  private double getWahlberechtigteMitWahlscheinUrnenwahlAnteilMean() {
    return WAHLBERECHTIGTE_MIT_WAHLSCHEIN_URNENWAHL_ANTEIL_MEAN;
  }

  private double getWahlberechtigteMitWahlscheinUrnenwahlAnteilStandardDeviation() {
    return WAHLBERECHTIGTE_MIT_WAHLSCHEIN_URNENWAHL_ANTEIL_STANDARD_DEVIATION;
  }

  public double getWahlberechtigteMitWahlscheinUrnenwahlMinPreventigZeros() {
    return WAHLBERECHTIGTE_MIT_WAHLSCHEIN_URNENWAHL_MIN_PREVENTIG_ZEROS;
  }

  private double getWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteilMean() {
    return WAHLBERECHTIGTE_NICHT_IM_WAEHLEVERZEICHNIS_URNENWAHL_ANTEIL_MEAN;
  }

  private double getWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteilStandardDeviation() {
    return WAHLBERECHTIGTE_NICHT_IM_WAEHLEVERZEICHNIS_URNENWAHL_ANTEIL_STANDARD_DEVIATION;
  }

  public NormalDistribution getNormalDistributionFuerWahlberechtigteAmUrnenwahlgebiet(Stimmenart stimmenart) {
    switch (stimmenart) {
      case GESAMT:
        return normalDistributionFuerWahlberechtigteGesamtUrnenwahl;
      case MIT_WAHLSCHEIN:
        return normalDistributionFuerWahlberechtigteMitWahlscheinUrnenwahlAnteil;
      case NICHT_IM_WAEHLERVERZEICHNIS:
        return normalDistributionFuerWahlberechtigteNichtImWaehleverzeichnisUrnenwahlAnteil;
    }
    return null;
  }
}
