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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;

import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import org.apache.deltaspike.core.api.scope.ConversationGroup;
import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;

import de.ivu.elect.business.gebietsbaum.boundary.GebietSelectChangeEvent;
import de.ivu.elect.business.gebietsbaum.entity.EntityMitGebietVeraenderbar;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.EntityMitGruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.person.boundary.SearchParametersMitPersonendatenNamen;
import de.ivu.elect.business.person.entity.PersonStatus;
import de.ivu.elect.business.person.entity.PersonendatenConstants;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.business.wahlvorschlagsperson.control.WahlvorschlagsPersonTypResolver;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPersonConstants;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPersonTyp;
import de.ivu.elect.jee.presentation.dynamicform.AbstractEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.presentation.gruppe.form.GruppeSearchProperty;


import static java.util.Arrays.asList;

@GroupedConversationScoped
@ConversationGroup(AbstractWahlvorschlagsPersonSearchParameters.class)
public class WahlvorschlagsPersonSearchParameters extends AbstractWahlvorschlagsPersonSearchParameters
    implements
    SearchParametersMitPersonendatenNamen,
    EntityMitGruppe<PolitischeGruppe>,
    EntityMitGebietVeraenderbar {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahlvorschlagsPersonTypResolver wahlvorschlagsPersonTypResolver;

  private WahlvorschlagsPersonTyp wahlvorschlagsPersonTyp;

  private Wahlvorschlag wahlvorschlag;

  private Kandidatur kandidatur;

  private Gebiet gebiet;

  private PolitischeGruppe politischeGruppe;

  private String familienname;

  private String vorname;

  private PersonStatus personStatus;

  public WahlvorschlagsPersonSearchParameters() {
    super();
  }

  public Collection<WahlvorschlagsPersonTyp> getWahlvorschlagsPersonTypen() {
    return wahlvorschlagsPersonTypResolver.getWahlvorschlagsPersonTypen();
  }

  public Property getWahlvorschlagsPersonTypProperty() {
    return new WahlvorschlagsPersonTypProperty();
  }

  public boolean hasWahlvorschlagsPersonTyp() {
    return getWahlvorschlagsPersonTyp() != null;
  }

  public WahlvorschlagsPersonTyp getWahlvorschlagsPersonTyp() {
    return wahlvorschlagsPersonTyp;
  }

  public void setWahlvorschlagsPersonTyp(WahlvorschlagsPersonTyp wahlvorschlagsPersonTyp) {
    this.wahlvorschlagsPersonTyp = wahlvorschlagsPersonTyp;
  }

  public boolean hasWahlvorschlag() {
    return getWahlvorschlag() != null;
  }

  public Wahlvorschlag getWahlvorschlag() {
    return wahlvorschlag;
  }

  public void setWahlvorschlag(Wahlvorschlag wahlvorschlag) {
    this.wahlvorschlag = wahlvorschlag;
  }

  public boolean hasKandidatur() {
    return getKandidatur() != null;
  }

  public Kandidatur getKandidatur() {
    return kandidatur;
  }

  public void setKandidatur(Kandidatur kandidatur) {
    this.kandidatur = kandidatur;
  }

  public boolean hasGebiet() {
    return getGebiet() != null;
  }

  @Override
  public Gebiet getGebiet() {
    return gebiet;
  }

  @Override
  public void setGebiet(Gebiet gebiet) {
    this.gebiet = gebiet;
  }

  @Override
  public void onGebietSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) GebietSelectChangeEvent event) {
    super.onGebietSelectChangeEvent(event);

    setGebiet(event.getNeueEntity());
  }

  @Override
  public PolitischeGruppe getGruppe() {
    return politischeGruppe;
  }

  @Override
  public void setGruppe(PolitischeGruppe politischeGruppe) {
    this.politischeGruppe = politischeGruppe;
  }

  public Property getPolitischeGruppeProperty(List<PolitischeGruppe> values) {
    return new GruppeSearchProperty<>(this, values, true);
  }

  @Override
  public FamiliennameProperty getFamiliennameProperty() {
    return new FamiliennameProperty();
  }

  @Override
  public String getFamilienname() {
    return familienname;
  }

  @Override
  public void setFamilienname(String familienname) {
    this.familienname = familienname;
  }

  @Override
  public VornameProperty getVornameProperty() {
    return new VornameProperty();
  }

  @Override
  public String getVorname() {
    return vorname;
  }

  @Override
  public void setVorname(String vorname) {
    this.vorname = vorname;
  }

  public PersonStatusProperty getPersonStatusProperty() {
    return new PersonStatusProperty();
  }

  public boolean hasPersonStatus() {
    return getPersonStatus() != null;
  }

  public PersonStatus getPersonStatus() {
    return personStatus;
  }

  public void setPersonStatus(PersonStatus personStatus) {
    this.personStatus = personStatus;
  }

  public class FamiliennameProperty extends AbstractStringProperty {

    public FamiliennameProperty() {
      super();
    }

    @Override
    public String getValue() {
      return getFamilienname();
    }

    @Override
    public void setValue(String value) {
      setFamilienname(value);
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonendatenConstants.FAMILIENNAME_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonendatenConstants.MESSAGE_KEY_FAMILIENNAME_EINZAHL);
    }

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

  public class VornameProperty extends AbstractStringProperty {

    public VornameProperty() {
      super();
    }

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

    @Override
    public String getDefaultLabel() {
      return getMessage(SearchParametersMitPersonendatenNamen.MESSAGE_KEY_VORNAME_EINZAHL);
    }

    @Override
    public String getValue() {
      return getVorname();
    }

    @Override
    public void setValue(String value) {
      setVorname(value);
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonendatenConstants.VORNAME_MAX_LENGTH;
    }
  }

  public class PersonStatusProperty extends AbstractEnumProperty<PersonStatus> {

    public PersonStatusProperty() {
      super();
    }

    @Override
    public boolean hasNoSelectionItem() {
      return true;
    }

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

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonendatenConstants.MESSAGE_KEY_PERSON_STATUS_EINZAHL);
    }

    @Override
    public PersonStatus getValue() {
      return getPersonStatus();
    }

    @Override
    public void setValue(PersonStatus value) {
      setPersonStatus(value);
    }

    @Override
    public List<PersonStatus> getValues() {
      List<PersonStatus> result = asList(PersonStatus.values());

      Collections.sort(result);

      return result;
    }

    @Override
    public Class<PersonStatus> getEnumClass() {
      return PersonStatus.class;
    }
  }

  public class WahlvorschlagsPersonTypProperty extends AbstractEnumProperty<WahlvorschlagsPersonTyp> {

    public WahlvorschlagsPersonTypProperty() {
      super();
    }

    @Override
    public boolean hasNoSelectionItem() {
      return true;
    }

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

    @Override
    public String getDefaultLabel() {
      return getMessage(WahlvorschlagsPersonConstants.MESSAGE_KEY_WAHLVORSCHLAGS_PERSON_TYP_EINZAHL);
    }

    @Override
    public WahlvorschlagsPersonTyp getValue() {
      return getWahlvorschlagsPersonTyp();
    }

    @Override
    public void setValue(WahlvorschlagsPersonTyp value) {
      setWahlvorschlagsPersonTyp(value);
    }

    @Override
    public List<WahlvorschlagsPersonTyp> getValues() {
      List<WahlvorschlagsPersonTyp> result = new ArrayList<>(getWahlvorschlagsPersonTypen());

      Collections.sort(result);

      return result;
    }

    @Override
    public Class<WahlvorschlagsPersonTyp> getEnumClass() {
      return WahlvorschlagsPersonTyp.class;
    }
  }
}
