
package de.ivu.elect.business.stimmeingabe.control;

import javax.annotation.Nullable;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;

import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeGruppeStimmenErfassenModelBuilder;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeKopfzahlErfassenModelBuilder;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeListenkandidaturStimmenErfassenModelBuilder;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeReferendumOptionStimmenErfassenModelBuilder;
import de.ivu.elect.business.wahl.entity.Wahl;

public class StimmeingabeErfassenModelBuilderResolver {

  /*
  NOTE, dass es sauberer wäre, mit dem StimmeingabeErfassenDescriptionResolver die StimmeingabeErfassenDescription zur Wahl zu finden,
  und dort nach dem ModelBuilder zu fragen
  */

  @Inject
  private transient Instance<StimmeingabeGruppeStimmenErfassenModelBuilder> stimmeingabeGruppeStimmenErfassenModelBuilders;

  @Inject
  private transient Instance<StimmeingabeKopfzahlErfassenModelBuilder> stimmeingabeKopfzahlErfassenModelBuilders;

  @Inject
  private transient Instance<StimmeingabeListenkandidaturStimmenErfassenModelBuilder> stimmeingabeListenkandidaturStimmenErfassenModelBuilders;

  @Inject
  private transient Instance<StimmeingabeReferendumOptionStimmenErfassenModelBuilder> stimmeingabeReferendumOptionStimmenErfassenModelBuilders;

  public boolean isStimmeingabeErfassenModelBuilderAvailable(Wahl wahl) {
    // HINT: Kopfzahlen müssen immer erfasst werden...
    return isModelBuilderAvailable(wahl, stimmeingabeKopfzahlErfassenModelBuilders);
  }

  @Nullable
  public StimmeingabeListenkandidaturStimmenErfassenModelBuilder getStimmeingabeListenkandidaturStimmenErfassenModelBuilder(
      Wahl wahl) {
    return selectModelBuilder(wahl, stimmeingabeListenkandidaturStimmenErfassenModelBuilders);
  }

  @Nullable
  public StimmeingabeKopfzahlErfassenModelBuilder getStimmeingabeKopfzahlErfassenModelBuilder(Wahl wahl) {
    return selectModelBuilder(wahl, stimmeingabeKopfzahlErfassenModelBuilders);
  }

  @Nullable
  public StimmeingabeGruppeStimmenErfassenModelBuilder getStimmeingabeGruppeStimmenErfassenModelBuilder(Wahl wahl) {
    return selectModelBuilder(wahl, stimmeingabeGruppeStimmenErfassenModelBuilders);
  }

  public boolean hasStimmeingabeGruppeStimmenErfassenModelBuilder(Wahl wahl) {
    return isModelBuilderAvailable(wahl, stimmeingabeGruppeStimmenErfassenModelBuilders);
  }

  @Nullable
  public StimmeingabeReferendumOptionStimmenErfassenModelBuilder getStimmeingabeReferendumOptionStimmenErfassenModelBuilder(
      Wahl wahl) {
    return selectModelBuilder(wahl, stimmeingabeReferendumOptionStimmenErfassenModelBuilders);
  }

  public boolean hasStimmeingabeReferendumOptionStimmenErfassenModelBuilder(Wahl wahl) {
    return isModelBuilderAvailable(wahl, stimmeingabeReferendumOptionStimmenErfassenModelBuilders);
  }

  private boolean isModelBuilderAvailable(Wahl wahl, Iterable< ? extends StimmeingabeErfassenModelBuilder> modelBuilders) {
    return selectModelBuilder(wahl, modelBuilders) != null;
  }

  @Nullable
  private <T extends StimmeingabeErfassenModelBuilder> T selectModelBuilder(Wahl wahl, Iterable<T> modelBuilders) {
    for (T modelBuilder : modelBuilders) {
      if (modelBuilder.isApplicable(wahl)) {
        return modelBuilder;
      }
    }

    return null;
  }

}
