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

import de.ivu.elect.business.hochrechnung.entity.AnzahlStimmenProWaehlerNachStimmenartBestimmer;
import de.ivu.elect.business.hochrechnung.entity.GebietDaten;
import de.ivu.elect.business.hochrechnung.entity.StimmenhochrechnerGebietAusgabedaten;

public enum ArtBetrachteterStimmen {
  ANZAHLEN {
    @Override
    public Long getWahlbeteiligungOderWaehlerAnzahl(GebietDaten gebietDaten) {
      return getAnzahlWaehler(gebietDaten);
    }

    @Override
    public GebietDaten<Long> getGebietDatenVorperiode(StimmenhochrechnerGebietAusgabedaten ausgabedaten) {
      return ausgabedaten.getVorperiodeAnzahlen();
    }

    @Override
    public GebietDaten<Long> getGebietDatenAktuell(StimmenhochrechnerGebietAusgabedaten ausgabedaten) {
      return ausgabedaten.getAktuellAnzahlen();
    }

    @Override
    public GebietDaten<Long> getGebietDatenHochgerechnet(StimmenhochrechnerGebietAusgabedaten ausgabedaten, AnzahlStimmenProWaehlerNachStimmenartBestimmer anzahlStimmenProWaehlerNachStimmenartBestimmer) {
      return ausgabedaten.getHochgerechnetAlsAnzahlen(anzahlStimmenProWaehlerNachStimmenartBestimmer);
    }
  },

  ANTEILE {
    @Override
    public Double getWahlbeteiligungOderWaehlerAnzahl(GebietDaten gebietDaten) {
      return gebietDaten.getWahlbeteiligung().getGesamt();
    }

    @Override
    public GebietDaten<Double> getGebietDatenVorperiode(StimmenhochrechnerGebietAusgabedaten ausgabedaten) {
      return ausgabedaten.getVorperiodeAnteile();
    }

    @Override
    public GebietDaten<Double> getGebietDatenAktuell(StimmenhochrechnerGebietAusgabedaten ausgabedaten) {
      return ausgabedaten.getAktuellAnteile();
    }

    @Override
    public GebietDaten<Double> getGebietDatenHochgerechnet(StimmenhochrechnerGebietAusgabedaten ausgabedaten, AnzahlStimmenProWaehlerNachStimmenartBestimmer anzahlStimmenProWaehlerNachStimmenartBestimmer) {
      return ausgabedaten.getHochgerechnetAnteile();
    }
  };

  Long getAnzahlWaehler(GebietDaten gebietDaten) {
    if (gebietDaten == null) {
      return null;
    }
    Long wahlberechtigete = gebietDaten.getAnzahlWahlberechtigteImGebiet().getGesamt();
    Double wahlbeteiligung = gebietDaten.getWahlbeteiligung().getGesamt();
    if (wahlbeteiligung == null || wahlberechtigete == null) {
      return null;
    }
    return Math.round(wahlbeteiligung * wahlberechtigete);
  }

  public abstract <N extends Number> N getWahlbeteiligungOderWaehlerAnzahl(GebietDaten gebietDaten);
  public abstract <N extends Number> GebietDaten<N> getGebietDatenVorperiode(StimmenhochrechnerGebietAusgabedaten ausgabedaten);
  public abstract <N extends Number> GebietDaten<N> getGebietDatenAktuell(StimmenhochrechnerGebietAusgabedaten ausgabedaten);
  public abstract <N extends Number> GebietDaten<N> getGebietDatenHochgerechnet(StimmenhochrechnerGebietAusgabedaten ausgabedaten, AnzahlStimmenProWaehlerNachStimmenartBestimmer anzahlStimmenProWaehlerNachStimmenartBestimmer);

  public String getMessageKeyFuerWahlbeteiligungOderWaehlerAktuell() {
    return "stimmeingabe.auffaelligkeit.visualisiert.wahlbeteiligung." + toString().toLowerCase() + ".label";
  }

  public String getMessageKeyFuerStimmenVorperiode() {
    return "stimmeingabe.auffaelligkeit.visualisiert.stimmen." + toString().toLowerCase() + ".vorperiode";
  }

  public String getMessageKeyFuerStimmenAktuell() {
    return "stimmeingabe.auffaelligkeit.visualisiert.stimmen." + toString().toLowerCase() + ".aktuell";
  }

  public String getMessageKeyFuerStimmenHochgerechnet() {
    return "stimmeingabe.auffaelligkeit.visualisiert.stimmen." + toString().toLowerCase() + ".hochgerechnet";
  }
}
    
