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

import java.io.Serializable;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;

import de.ivu.elect.business.wahl.entity.AbstractWahlParameterLoader;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;

@RequestScoped // ELECT-6404
public class ListenwahlStimmeingabeKonfiguration implements Serializable {

  private static final long serialVersionUID = 1L;

  private static final AbstractListenwahlStimmeingabeKonfiguration UNDEFINED = new AbstractListenwahlStimmeingabeKonfiguration() {

    private static final long serialVersionUID = 1L;

    @Override
    public boolean isApplicable(Wahl wahl) {
      return false;
    }
  };

  @Inject
  private transient Instance<CustomListenwahlStimmeingabeKonfiguration> customListenwahlStimmeingabeKonfiguration;

  public ListenwahlStimmeingabeKonfiguration() {
    super();
  }

  public boolean isApplicable(Wahl wahl) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isApplicable(wahl);
  }

  public boolean isErgebniseingangContainsStimmenKomplett(Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isErgebniseingangContainsStimmenKomplett(wahl, ergebnisart);
  }

  public boolean isErgebnismeldungEndgueltigKomplett(AbstractWahlParameterLoader wahlParameterLoader, Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isErgebnismeldungEndgueltigKomplett(wahlParameterLoader, wahl, ergebnisart);
  }

  public boolean isErgebnismeldungVorlaeufigKomplett(AbstractWahlParameterLoader wahlParameterLoader, Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isErgebnismeldungVorlaeufigKomplett(wahlParameterLoader, wahl, ergebnisart);
  }

  /**
   * A.k.a. "Stimmzettel für genau einen Wahlvorschlag unverändert"
   */
  public boolean isStimmzetteleingabeGruppeStimmenNurEinzelnerWahlvorschlagUnveraendertRelevant(AbstractWahlParameterLoader wahlParameterLoader, Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isStimmzetteleingabeGruppeStimmenNurEinzelnerWahlvorschlagUnveraendertRelevant(wahlParameterLoader, wahl, ergebnisart);
  }

  /**
   * A.k.a. "Stimmzettel für genau einen Wahlvorschlag mit Änderungen nur in diesem"
   */
  public boolean isStimmzetteleingabeGruppeStimmenNurEinzelnerWahlvorschlagVeraendertRelevant(AbstractWahlParameterLoader wahlParameterLoader, Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isStimmzetteleingabeGruppeStimmenNurEinzelnerWahlvorschlagVeraendertRelevant(wahlParameterLoader, wahl, ergebnisart);
  }

  /**
   * A.k.a. "Stimmzettel für genau einen Wahlvorschlag mit panaschierten Stimmen"
   */
  public boolean isStimmzetteleingabeGruppeStimmenNurEinzelnerWahlvorschlagPanaschiertRelevant(AbstractWahlParameterLoader wahlParameterLoader, Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isStimmzetteleingabeGruppeStimmenNurEinzelnerWahlvorschlagPanaschiertRelevant(wahlParameterLoader, wahl, ergebnisart);
  }

  /**
   * A.k.a. "Gültige kumulierte und panaschierte Stimmen insgesamt"
   */
  public boolean isStimmeingabeGruppeStimmenListenkandidaturenGesamtRelevant(AbstractWahlParameterLoader wahlParameterLoader, Wahl wahl, WahlartErgebnisart ergebnisart) {
    return getCustomListenwahlStimmeingabeKonfiguration(wahl).isStimmeingabeGruppeStimmenListenkandidaturenGesamtRelevant(wahlParameterLoader, wahl, ergebnisart);
  }

  private CustomListenwahlStimmeingabeKonfiguration getCustomListenwahlStimmeingabeKonfiguration(Wahl wahl) {
    for (CustomListenwahlStimmeingabeKonfiguration stimmeingabeKonfiguration : customListenwahlStimmeingabeKonfiguration) {
      if (stimmeingabeKonfiguration.isApplicable(wahl)) {
        return stimmeingabeKonfiguration;
      }
    }

    return UNDEFINED;
  }
}
