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

import java.util.Map;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.hochrechnung.control.GebietDatenAnteileToGanzeZahlenConverter;

public class GebietDatenMitStimmenAnzahlen implements GebietDaten<Long> {
  private final GebietDaten<Long> gebietDaten;

  public GebietDatenMitStimmenAnzahlen(GebietDaten<Double> gebietDatenAlsAnteile, AnzahlStimmenProWaehlerNachStimmenartBestimmer anzahlStimmenProWaehlerBestimmer) {
    GebietDatenAnteileToGanzeZahlenConverter gebietDatenAnteileToGanzeZahlenConverter = new GebietDatenAnteileToGanzeZahlenConverter();

    Gebiet gebiet = gebietDatenAlsAnteile.getGebiet();
    WahlteilnehmerAnzahl anzahlWahlberechtigteImGebiet = gebietDatenAlsAnteile.getAnzahlWahlberechtigteImGebiet();
    WahlteilnehmerAnzahl anzahlWaehlerImGebiet = gebietDatenAlsAnteile.getAnzahlWaehlerImGebiet();

    Map<Stimmenart, Long> anzahlAbgegebeneStimmen = gebietDatenAnteileToGanzeZahlenConverter.getAnzahlAbgegebeneStimmen(gebietDatenAlsAnteile, anzahlStimmenProWaehlerBestimmer);

    Map<Stimmenart, Long> gueltige = gebietDatenAnteileToGanzeZahlenConverter.berechneGueltigeAnzahlen(gebietDatenAlsAnteile.getGueltige(), anzahlAbgegebeneStimmen);
    Map<Stimmenart, Long> ungueltige = gebietDatenAnteileToGanzeZahlenConverter.berechneUngueltigeStimmenVonRestlichenWaehler(gueltige, anzahlAbgegebeneStimmen);
    boolean isErgebnisVorhanden = gebietDatenAlsAnteile.isErgebnisVorhanden();
    GebietDatenWahlbeteiligung wahlbeteiligung = gebietDatenAlsAnteile.getWahlbeteiligung();
    Map<PolitischeGruppe, ParteiStimmen<Long>> parteiStimmen = gebietDatenAnteileToGanzeZahlenConverter
        .berechneParteiStimmenAnzahlen(gebietDatenAlsAnteile.getParteiStimmen(), gueltige);

    Map<Gruppe, ReferendumFrage<Long>> referendumFragen = gebietDatenAnteileToGanzeZahlenConverter.berechneReferendumFragenStimmenAnzahlen(gebietDatenAlsAnteile.getReferendumFragen(), anzahlAbgegebeneStimmen);

    gebietDaten = createGebietDaten(gebiet, anzahlWahlberechtigteImGebiet, anzahlWaehlerImGebiet, gueltige, ungueltige, isErgebnisVorhanden, wahlbeteiligung, parteiStimmen, referendumFragen);
  }

  private GebietDaten<Long> createGebietDaten(Gebiet gebiet, WahlteilnehmerAnzahl anzahlWahlberechtigteImGebiet, WahlteilnehmerAnzahl anzahlWaehlerImGebiet, Map<Stimmenart, Long> gueltige, Map<Stimmenart, Long> ungueltige, boolean isErgebnisVorhanden, GebietDatenWahlbeteiligung wahlbeteiligung, Map<PolitischeGruppe, ParteiStimmen<Long>> parteiStimmen, Map<Gruppe, ReferendumFrage<Long>> referendumFragen) {
    return new GebietDaten<Long>() {
      @Override
      public Gebiet getGebiet() {
        return gebiet;
      }

      @Override
      public WahlteilnehmerAnzahl getAnzahlWahlberechtigteImGebiet() {
        return anzahlWahlberechtigteImGebiet;
      }

      @Override
      public WahlteilnehmerAnzahl getAnzahlWaehlerImGebiet() {
        return anzahlWaehlerImGebiet;
      }

      @Override
      public Map<Stimmenart, Long> getGueltige() {
        return gueltige;
      }

      @Override
      public Map<Stimmenart, Long> getUngueltige() {
        return ungueltige;
      }

      @Override
      public boolean isErgebnisVorhanden() {
        return isErgebnisVorhanden;
      }

      @Override
      public GebietDatenWahlbeteiligung getWahlbeteiligung() {
        return wahlbeteiligung;
      }

      @Override
      public Map<PolitischeGruppe, ParteiStimmen<Long>> getParteiStimmen() {
        return parteiStimmen;
      }

      @Override
      public Map<Gruppe, ReferendumFrage<Long>> getReferendumFragen() {
        return referendumFragen;
      }
    };
  }

  @Override
  public Gebiet getGebiet() {
    return gebietDaten.getGebiet();
  }

  @Override
  public WahlteilnehmerAnzahl getAnzahlWahlberechtigteImGebiet() {
    return gebietDaten.getAnzahlWahlberechtigteImGebiet();
  }

  @Override
  public WahlteilnehmerAnzahl getAnzahlWaehlerImGebiet() {
    return gebietDaten.getAnzahlWaehlerImGebiet();
  }

  @Override
  public Map<Stimmenart, Long> getGueltige() {
    return gebietDaten.getGueltige();
  }

  @Override
  public Map<Stimmenart, Long> getUngueltige() {
    return gebietDaten.getUngueltige();
  }

  @Override
  public boolean isErgebnisVorhanden() {
    return gebietDaten.isErgebnisVorhanden();
  }

  @Override
  public GebietDatenWahlbeteiligung getWahlbeteiligung() {
    return gebietDaten.getWahlbeteiligung();
  }

  @Override
  public Map<PolitischeGruppe, ParteiStimmen<Long>> getParteiStimmen() {
    return gebietDaten.getParteiStimmen();
  }

  @Override
  public Map<Gruppe, ReferendumFrage<Long>> getReferendumFragen() {
    return gebietDaten.getReferendumFragen();
  }
}
