
package de.ivu.elect.business.stimmzettel.boundary;

import static de.ivu.elect.jee.entity.EntityUtil.castTo;

import java.util.Collection;
import java.util.function.Supplier;

import javax.enterprise.inject.Specializes;
import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.sitzberechnung.control.Sitzberechnungsalgorithmus;
import de.ivu.elect.business.sitzberechnung.control.SitzberechnungsalgorithmusFinder;
import de.ivu.elect.business.wahl.entity.CommonWahlart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;

@Specializes
public class WasAnzahlStimmenProWaehlerBestimmer extends AnzahlStimmenProWaehlerBestimmer {

  @Inject
  private transient SitzberechnungsalgorithmusFinder sitzberechnungsalgorithmusFinder;

  public WasAnzahlStimmenProWaehlerBestimmer() {
    super();
  }

  @Override // ELECT-13860, erste, naive Implementierung...
  public boolean isSitzverteilungPerMehrheitswahl(Gebiet gebiet, Supplier<Collection< ? extends Wahlvorschlag>> wahlvorschlaegeFct) {
    if (gebiet != null) {
      Wahl wahl = gebiet.getWahl();

      if (wahl != null) {
        if (CommonWahlart.BUERGERMEISTERWAHL.equalsWahlart(wahl)) {
          return true;
        }

        if (wahl.isWahlMitListengebieten()) {
          // Momentan gilt: Listenwahl -> WasAnzahlStimmenProWaehlerBestimmer#isWaehlerBenannteWahlvorschlaegeErfassbar -> Sitzberechnungsalgorithmus#isWaehlerBenannteWahlvorschlaegeErfassbar -> AbstractListenwahlMehrheitswahlPruefer#isMehrheitswahl...
          return isWaehlerBenannteWahlvorschlaegeErfassbar(gebiet, wahlvorschlaegeFct);
        } else if (wahl.isWahlMitDirektkandidatengebieten()) {
          return true;
        }
      }
    }

    return false;
  }

  @Override
  public boolean isWaehlerBenannteWahlvorschlaegeErfassbar(Gebiet gebiet, Supplier<Collection< ? extends Wahlvorschlag>> wahlvorschlaegeFct) {
    if (gebiet != null && gebiet.isInstanceOf(Wahldurchfuehrungsgebiet.class)) {
      Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet = castTo(gebiet, Wahldurchfuehrungsgebiet.class);

      return getSitzberechnungsalgorithmus(wahldurchfuehrungsgebiet).isWaehlerBenannteWahlvorschlaegeErfassbar(wahldurchfuehrungsgebiet, wahlvorschlaegeFct.get());
    }

    return false;
  }

  private Sitzberechnungsalgorithmus< ? > getSitzberechnungsalgorithmus(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    return sitzberechnungsalgorithmusFinder.getSitzberechnungsalgorithmus(wahldurchfuehrungsgebiet.getWahldurchfuehrung());
  }
}
