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

import static java.util.Arrays.asList;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import java.util.Date;
import java.util.List;

import javax.annotation.Nullable;

import de.ivu.elect.business.person.boundary.SearchParametersMitPersonendaten;
import de.ivu.elect.business.person.entity.Geschlecht;
import de.ivu.elect.business.personenregister.entity.FamiliennameProperty;
import de.ivu.elect.business.personenregister.entity.GeburtsdatumProperty;
import de.ivu.elect.business.personenregister.entity.GeschlechtProperty;
import de.ivu.elect.business.personenregister.entity.PersonenregisterEinwohnerstatus;
import de.ivu.elect.business.personenregister.entity.VornameProperty;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.presentation.dynamicform.Property;

// NOTE ELECT-7776, dass alle Properties explizit definiert sind, damit diese tatsächlich die Getter und Setter aufrufen und damit ggf. deren
// Spezialbehandlungen, cf. MesoByPersonendatenSearchParameters, durchführen!!!
public class PersonenregisterByPersonendatenSearchParameters extends AbstractPersonenregisterSearchParameters implements SearchParametersMitPersonendaten {

  private static final long serialVersionUID = 1L;

  public static final Geschlecht DEFAULT_GESCHLECHT = Geschlecht.UNBEKANNT;

  /**** !!!!!!!!!!!!! ***********/
  /* ELECT-11217 neue Suchparameter in getParameterValues aufnehmen!! ***/
  /**** !!!!!!!!!!!!! ***********/

  private String familienname;

  private transient Property familiennameProperty;

  private String vorname;

  private transient Property vornameProperty;

  private Date geburtsdatum;

  private transient Property geburtsdatumProperty;

  private Geschlecht geschlecht;

  private final List<Geschlecht> geschlechterSupported;

  private transient Property geschlechtProperty;

  public PersonenregisterByPersonendatenSearchParameters() {
    this(asList(Geschlecht.values()));
  }

  public PersonenregisterByPersonendatenSearchParameters(List<Geschlecht> geschlechterSupported) {
    this(null, DEFAULT_PERSONENREGISTER_EINWOHNERSTATUS, "", "", null, DEFAULT_GESCHLECHT, geschlechterSupported);
  }

  protected PersonenregisterByPersonendatenSearchParameters(@Nullable Wahltermin wahltermin, PersonenregisterEinwohnerstatus einwohnerstatus, String familienname, String vorname, Date geburtsdatum,
      Geschlecht geschlecht, List<Geschlecht> geschlechterSupported) {
    super(wahltermin, einwohnerstatus);

    // NOTE, dass die Setter explizit aufgerufen werden, um ggf. deren Spezialbehandlungen, cf. MesoByPersonendatenSearchParameters, durchzuführen!!!
    setFamilienname(familienname);
    setVorname(vorname);

    setGeburtsdatum(geburtsdatum);
    setGeschlecht(geschlecht);

    this.geschlechterSupported = geschlechterSupported;
  }

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

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

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

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

  @Override
  public Date getGeburtsdatum() {
    return geburtsdatum;
  }

  @Override
  public void setGeburtsdatum(Date geburtsdatum) {
    this.geburtsdatum = geburtsdatum;
  }

  @Override
  public Geschlecht getGeschlecht() {
    return geschlecht;
  }

  @Override
  public void setGeschlecht(Geschlecht geschlecht) {
    this.geschlecht = geschlecht;
  }

  public List<Geschlecht> getGeschlechterSupported() {
    return geschlechterSupported;
  }

  @Deprecated // Stattdessen getGeschlechtProperty(List<Geschlecht> geschlechterSupported) verwenden!
  @Override
  public Property getGeschlechtProperty() {
    return getGeschlechtProperty(getGeschlechterSupported());
  }

  public Property getGeschlechtProperty(List<Geschlecht> geschlechterSupported) {
    if (geschlechtProperty == null) {
      geschlechtProperty = createGeschlechtProperty(geschlechterSupported);
    }

    return geschlechtProperty;
  }

  protected Property createGeschlechtProperty(List<Geschlecht> geschlechterSupported) {
    return new GeschlechtProperty(this, geschlechterSupported);
  }

  @Override
  public Property getFamiliennameProperty() {
    if (familiennameProperty == null) {
      familiennameProperty = createFamiliennameProperty();
    }

    return familiennameProperty;
  }

  protected Property createFamiliennameProperty() {
    return new FamiliennameProperty(this);
  }

  @Override
  public Property getGeburtsdatumProperty() {
    if (geburtsdatumProperty == null) {
      geburtsdatumProperty = createGeburtsdatumProperty();
    }

    return geburtsdatumProperty;
  }

  protected Property createGeburtsdatumProperty() {
    return new GeburtsdatumProperty(this);
  }

  @Override
  public Property getVornameProperty() {
    if (vornameProperty == null) {
      vornameProperty = createVornameProperty();
    }

    return vornameProperty;
  }

  protected Property createVornameProperty() {
    return new VornameProperty(this);
  }

  @Override
  protected List<Object> getParameterValues() {
    return asList(familienname, vorname, geburtsdatum, geburtsdatum);
  }
}
