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

import static java.util.Arrays.asList;

import java.io.Serializable;
import java.util.List;

import de.ivu.elect.business.anschrift.entity.AnschriftArt;
import de.ivu.elect.jee.presentation.dynamicform.AbstractEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractIntegerProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;

public class PersonenregisterAnschriftProperties implements Serializable {

  private static final long serialVersionUID = 1L;

  private final PersonenregisterAnschrift personenregisterAnschrift;

  private transient AnschriftArtProperty anschriftArtProperty;

  private transient StrasseProperty strasseProperty;

  private transient HausnummerProperty hausnummerProperty;

  private transient HausnummerzusatzProperty hausnummerzusatzProperty;

  private transient WohnungsnummerProperty wohnungsnummerProperty;

  private transient OrtProperty ortProperty;

  private transient OrtsteilProperty ortsteilProperty;

  private transient PlzProperty plzProperty;

  private transient NameOrCodeStaatProperty staatProperty;

  private transient ZustellanweisungProperty zustellanweisungProperty;

  private transient StimmbezirkSchluesselProperty stimmbezirkSchluesselProperty;

  public PersonenregisterAnschriftProperties(PersonenregisterAnschrift personenregisterAnschrift) {
    super();

    this.personenregisterAnschrift = personenregisterAnschrift;
  }

  public AnschriftArtProperty getAnschriftArtProperty() {
    if (anschriftArtProperty == null) {
      anschriftArtProperty = new AnschriftArtProperty(personenregisterAnschrift);
    }

    return anschriftArtProperty;
  }

  public StrasseProperty getStrasseProperty() {
    if (strasseProperty == null) {
      strasseProperty = new StrasseProperty(personenregisterAnschrift);
    }

    return strasseProperty;
  }

  public HausnummerProperty getHausnummerProperty() {
    if (hausnummerProperty == null) {
      hausnummerProperty = new HausnummerProperty(personenregisterAnschrift);
    }

    return hausnummerProperty;
  }

  public HausnummerzusatzProperty getHausnummerzusatzProperty() {
    if (hausnummerzusatzProperty == null) {
      hausnummerzusatzProperty = new HausnummerzusatzProperty(personenregisterAnschrift);
    }

    return hausnummerzusatzProperty;
  }

  public WohnungsnummerProperty getWohnungsnummerProperty() {
    if (wohnungsnummerProperty == null) {
      wohnungsnummerProperty = new WohnungsnummerProperty(personenregisterAnschrift);
    }

    return wohnungsnummerProperty;
  }

  public PlzProperty getPlzProperty() {
    if (plzProperty == null) {
      plzProperty = new PlzProperty(personenregisterAnschrift);
    }

    return plzProperty;
  }

  public OrtProperty getOrtProperty() {
    if (ortProperty == null) {
      ortProperty = new OrtProperty(personenregisterAnschrift);
    }

    return ortProperty;
  }

  public OrtsteilProperty getOrtsteilProperty() {
    if (ortsteilProperty == null) {
      ortsteilProperty = new OrtsteilProperty(personenregisterAnschrift);
    }

    return ortsteilProperty;
  }

  public NameOrCodeStaatProperty getStaatProperty() {
    if (staatProperty == null) {
      staatProperty = new NameOrCodeStaatProperty(personenregisterAnschrift);
    }

    return staatProperty;
  }

  public ZustellanweisungProperty getZustellanweisungProperty() {
    if (zustellanweisungProperty == null) {
      zustellanweisungProperty = new ZustellanweisungProperty(personenregisterAnschrift);
    }

    return zustellanweisungProperty;
  }

  public StimmbezirkSchluesselProperty getStimmbezirkSchluesselProperty() {
    if (stimmbezirkSchluesselProperty == null) {
      stimmbezirkSchluesselProperty = new StimmbezirkSchluesselProperty(personenregisterAnschrift);
    }

    return stimmbezirkSchluesselProperty;
  }

  public static class AnschriftArtProperty extends AbstractPersonenregisterAnschriftEnumProperty<AnschriftArt> {

    public AnschriftArtProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public AnschriftArt getValue() {
      return getAnschrift().getAnschriftArt();
    }

    @Override
    public List<AnschriftArt> getValues() {
      return asList(AnschriftArt.values());
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_ANSCHRIFT_ART_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.ANSCHRIFT_ART_NULLABLE;
    }

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

  public static class StrasseProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public StrasseProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getStrasse();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.STRASSE_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_STRASSE_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.STRASSE_NULLABLE;
    }
  }

  public static class HausnummerProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public HausnummerProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getHausnummer();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.HAUSNUMMER_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_HAUSNUMMER_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.HAUSNUMMER_NULLABLE;
    }
  }

  public static class HausnummerzusatzProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public HausnummerzusatzProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getHausnummerzusatz();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.HAUSNUMMERZUSATZ_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_HAUSNUMMERZUSATZ_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.HAUSNUMMERZUSATZ_NULLABLE;
    }
  }

  public static class WohnungsnummerProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public WohnungsnummerProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getWohnungsnummer();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.WOHNUNGSNUMMER_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_WOHNUNGSNUMMER_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.WOHNUNGSNUMMER_NULLABLE;
    }
  }

  public static class PlzProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public PlzProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getPlz();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.PLZ_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_PLZ_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.PLZ_NULLABLE;
    }
  }

  public static class OrtProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public OrtProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getOrt();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.ORT_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_ORT_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.ORT_NULLABLE;
    }
  }

  public static class OrtsteilProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public OrtsteilProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getOrtsteil();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.ORTSTEIL_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_ORTSTEIL_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.ORTSTEIL_NULLABLE;
    }
  }

  public static class NameOrCodeStaatProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public NameOrCodeStaatProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getStaat();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.NAME_OR_CODE_STAAT_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_NAME_OR_CODE_STAAT_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.NAME_OR_CODE_STAAT_NULLABLE;
    }
  }

  public static class ZustellanweisungProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public ZustellanweisungProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getZustellanweisung();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.ZUSTELLANWEISUNG_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_ZUSTELLANWEISUNG_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.ZUSTELLANWEISUNG_NULLABLE;
    }
  }

  public static class StimmbezirkSchluesselProperty extends AbstractPersonenregisterAnschriftStringProperty {

    public StimmbezirkSchluesselProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super(personenregisterAnschrift);
    }

    @Override
    public String getValue() {
      return getAnschrift().getStimmbezirkSchluessel();
    }

    @Override
    public int getDefaultMaxLength() {
      return PersonenregisterAnschriftConstants.STIMMBEZIRK_SCHLUESSEL_MAX_LENGTH;
    }

    @Override
    public String getDefaultLabel() {
      return getMessage(PersonenregisterAnschriftConstants.MESSAGE_KEY_STIMMBEZIRK_SCHLUESSEL_EINZAHL);
    }

    @Override
    public boolean getDefaultRequired() {
      return !PersonenregisterAnschriftConstants.STIMMBEZIRK_SCHLUESSEL_NULLABLE;
    }
  }

  protected abstract static class AbstractPersonenregisterAnschriftStringProperty extends AbstractStringProperty {

    protected final PersonenregisterAnschrift personenregisterAnschrift;

    public AbstractPersonenregisterAnschriftStringProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super();

      this.personenregisterAnschrift = personenregisterAnschrift;
    }

    protected PersonenregisterAnschrift getAnschrift() {
      return personenregisterAnschrift;
    }

    @Override
    public boolean isReadonly() {
      return super.isReadonly() || !hasValue();
    }

    @Override
    public void setValue(String value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }

  protected abstract static class AbstractPersonenregisterAnschriftIntegerProperty extends AbstractIntegerProperty {

    protected final PersonenregisterAnschrift personenregisterAnschrift;

    public AbstractPersonenregisterAnschriftIntegerProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super();

      this.personenregisterAnschrift = personenregisterAnschrift;
    }

    protected PersonenregisterAnschrift getAnschrift() {
      return personenregisterAnschrift;
    }

    @Override
    public void setValue(Integer value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }

  protected abstract static class AbstractPersonenregisterAnschriftEnumProperty<E extends Enum<E>> extends AbstractEnumProperty<E> {

    protected final PersonenregisterAnschrift personenregisterAnschrift;

    public AbstractPersonenregisterAnschriftEnumProperty(PersonenregisterAnschrift personenregisterAnschrift) {
      super();

      this.personenregisterAnschrift = personenregisterAnschrift;
    }

    protected PersonenregisterAnschrift getAnschrift() {
      return personenregisterAnschrift;
    }

    @Override
    public boolean isReadonly() {
      return super.isReadonly() || !hasValue();
    }

    @Override
    public void setValue(E value) {
      throw new UnsupportedOperationException("CANNOT set a readonly property");
    }
  }
}
