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

import java.util.ArrayList;
import java.util.Collection;

import org.apache.deltaspike.core.api.scope.ConversationGroup;
import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;

import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingabestufe;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.ErgebniseingangConstants;
import de.ivu.elect.business.stimmeingabe.entity.ErgebniseingangProperties;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingangsart;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingangsfehlerstatus;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.presentation.dynamicform.AbstractBooleanProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumSelectManyProperty;
import de.ivu.elect.jee.presentation.dynamicform.Property;

@GroupedConversationScoped
@ConversationGroup(AbstractErgebniseingangSearchParameters.class)
public class ErgebniseingangSearchParameters extends AbstractErgebniseingangSearchParameters {

  private static final long serialVersionUID = 1L;

  public static final boolean SHOW_SEPARATE_ITEMS = true;

  private Wahldurchfuehrung wahldurchfuehrung;

  private Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet;

  private Ergebniseingang ergebniseingang;

  private transient Property ergebniseingangsartProperty;

  private Collection<Ergebniseingabestufe> ergebniseingabestufen;

  private transient Property ergebniseingabestufenProperty;

  private Collection<Ergebniseingangsfehlerstatus> ergebniseingangsfehlerstatus;

  private transient Property ergebniseingangsfehlerstatusProperty;

  private boolean nurLetztenEingangProGebietAnzeigen;

  private transient Property nurLetztenEingangProGebietAnzeigenProperty;

  public ErgebniseingangSearchParameters() {
    super();

    this.ergebniseingabestufen = new ArrayList<>();
    this.ergebniseingangsfehlerstatus = new ArrayList<>();

    this.nurLetztenEingangProGebietAnzeigen = true;
  }

  public Wahldurchfuehrung getWahldurchfuehrung() {
    return wahldurchfuehrung;
  }

  public void setWahldurchfuehrung(Wahldurchfuehrung wahldurchfuehrung) {
    this.wahldurchfuehrung = wahldurchfuehrung;
  }

  public Wahldurchfuehrungsgebiet getWahldurchfuehrungsgebiet() {
    return wahldurchfuehrungsgebiet;
  }

  public void setWahldurchfuehrungsgebiet(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
    this.wahldurchfuehrungsgebiet = wahldurchfuehrungsgebiet;
  }

  public Ergebniseingangsart getErgebniseingangsart() {
    return getErgebniseingang().getErgebniseingangsart();
  }

  public void setErgebniseingangsart(Ergebniseingangsart ergebniseingangsart) {
    getErgebniseingang().setErgebniseingangsart(ergebniseingangsart);
  }

  public Property getErgebniseingangsartProperty() {
    if (ergebniseingangsartProperty == null) {
      ergebniseingangsartProperty = getErgebniseingangProperties().getErgebniseingangsartMitLeererAuswahlProperty();
      ergebniseingangsartProperty.setRequired(false);
    }

    return ergebniseingangsartProperty;
  }

  public Collection<Ergebniseingabestufe> getErgebniseingabestufen() {
    return ergebniseingabestufen;
  }

  public void setErgebniseingabestufen(Collection<Ergebniseingabestufe> ergebniseingabestufen) {
    this.ergebniseingabestufen = ergebniseingabestufen;
  }

  public Property getErgebniseingabestufenProperty(Collection<Ergebniseingabestufe> values) {
    if (ergebniseingabestufenProperty == null) {
      ergebniseingabestufenProperty = new LambdaEnumSelectManyProperty<>(LambdaEnumSelectManyProperty.CHECKBOX_MENU, getMessage(ErgebniseingangConstants.MESSAGE_KEY_ERGEBNISEINGABESTUFE_EINZAHL),
          false, this::setErgebniseingabestufen, this::getErgebniseingabestufen, Ergebniseingabestufe.class, new ArrayList<>(values), SHOW_SEPARATE_ITEMS);
    }

    return ergebniseingabestufenProperty;
  }

  public Collection<Ergebniseingangsfehlerstatus> getErgebniseingangsfehlerstatus() {
    return ergebniseingangsfehlerstatus;
  }

  public void setErgebniseingangsfehlerstatus(Collection<Ergebniseingangsfehlerstatus> ergebniseingangsfehlerstatus) {
    this.ergebniseingangsfehlerstatus = ergebniseingangsfehlerstatus;
  }

  public Property getErgebniseingangsfehlerstatusProperty(Collection<Ergebniseingangsfehlerstatus> values) {
    if (ergebniseingangsfehlerstatusProperty == null) {
      ergebniseingangsfehlerstatusProperty = new LambdaEnumSelectManyProperty<>(LambdaEnumSelectManyProperty.CHECKBOX_MENU,
          getMessage(ErgebniseingangConstants.MESSAGE_KEY_ERGEBNISEINGANGSFEHLERSTATUS_EINZAHL), false, this::setErgebniseingangsfehlerstatus, this::getErgebniseingangsfehlerstatus,
          Ergebniseingangsfehlerstatus.class, new ArrayList<>(values), SHOW_SEPARATE_ITEMS);
    }

    return ergebniseingangsfehlerstatusProperty;
  }

  public boolean isNurLetztenEingangProGebietAnzeigen() {
    return nurLetztenEingangProGebietAnzeigen;
  }

  public void setNurLetztenEingangProGebietAnzeigen(boolean nurLetztenEingangProGebietAnzeigen) {
    this.nurLetztenEingangProGebietAnzeigen = nurLetztenEingangProGebietAnzeigen;
  }

  public Property getNurLetztenEingangProGebietAnzeigenProperty() {
    if (nurLetztenEingangProGebietAnzeigenProperty == null) {
      nurLetztenEingangProGebietAnzeigenProperty = new NurLetztenEingangProGebietAnzeigenProperty(this);
    }

    return nurLetztenEingangProGebietAnzeigenProperty;
  }

  private Ergebniseingang getErgebniseingang() {
    if (ergebniseingang == null) {
      ergebniseingang = new Ergebniseingang();
    }

    return ergebniseingang;
  }

  private ErgebniseingangProperties getErgebniseingangProperties() {
    return getErgebniseingang().getProperties();
  }

  @Override
  public void reset() {
    wahldurchfuehrung = null;
    wahldurchfuehrungsgebiet = null;

    ergebniseingang = null;

    ergebniseingabestufen = new ArrayList<>();
    ergebniseingangsfehlerstatus = new ArrayList<>();

    nurLetztenEingangProGebietAnzeigen = true;

    super.reset();
  }

  public static class NurLetztenEingangProGebietAnzeigenProperty extends AbstractBooleanProperty {

    private final ErgebniseingangSearchParameters ergebniseingangSearchParameters;

    public NurLetztenEingangProGebietAnzeigenProperty(ErgebniseingangSearchParameters ergebniseingangSearchParameters) {
      super();

      this.ergebniseingangSearchParameters = ergebniseingangSearchParameters;
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }

    @Override
    public Boolean getValue() {
      return ergebniseingangSearchParameters.isNurLetztenEingangProGebietAnzeigen();
    }

    @Override
    public void setValue(Boolean value) {
      ergebniseingangSearchParameters.setNurLetztenEingangProGebietAnzeigen(value);
    }

    @Override
    public String getDefaultLabel() {
      return getMessage("ergebniseingang.nur.letzten.eingang.pro.gebiet.anzeigen");
    }
  }
}
