
package de.ivu.elect.jee.presentation.dynamicform;

import java.util.function.BiFunction;
import java.util.function.Predicate;

import de.ivu.elect.jee.presentation.Icons;

public abstract class AbstractSelectOneMenuProperty<E> extends AbstractProperty implements SelectOneMenuProperty<E> {

  private static final int SHOW_FILTER_VALUE_SIZE = 10; // willkürlich

  private BiFunction<Icons, E, String> itemIconMapper;

  protected String noSelectionLabel = null;

  private Predicate<E> valueFilter = e -> true;

  protected AbstractSelectOneMenuProperty() {
    super();
  }

  @Override
  protected boolean mustBeAccessableOnPageLoadByValue() {
    if (super.mustBeAccessableOnPageLoadByValue()) {
      return true;
    }

    return notAllEqual(getDefaultValue(), getValue());
  }

  @Override
  protected boolean hasDefaultValue() {
    return notNullOrBlank(getDefaultValue());
  }

  @Override
  public E getDefaultValue() {
    return null;
  }

  @Override
  public boolean hasValue() {
    return notNullOrBlank(getValue());
  }

  @Override
  public boolean isRequired() {
    // NOTE ELECT-1204
    return super.isRequired() && hasNoSelectionItem();
  }

  @Override
  public PropertyType getDefaultType() {
    if (hasNoSelectionItem()) {
      return PropertyType.SELECT_ONE_MENU_NO_SELECTION_ITEM;
    }

    return PropertyType.SELECT_ONE_MENU;
  }

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

  @Override
  public String getNoSelectionLabel() {
    if (noSelectionLabel != null) {
      return noSelectionLabel;
    }

    if (isRequired() && hasNoSelectionItem() && !getValues().isEmpty()) {
      return getMessage("component.selection.required");
    }

    return null;
  }

  public BiFunction<Icons, E, String> getItemIconMapper() {
    return itemIconMapper;
  }

  public void setItemIconMapper(BiFunction<Icons, E, String> itemIconMapper) {
    this.itemIconMapper = itemIconMapper;
  }

  @Override
  public boolean isItemIconPresent() {
    return getItemIconMapper() != null && getIcons() != null;
  }

  @Override
  public String getItemIcon(E item) {
    if (isItemIconPresent()) {
      return getItemIconMapper().apply(getIcons(), item);
    }

    return "";
  }

  public void setNoSelectionLabel(String noSelectionLabel) {
    this.noSelectionLabel = noSelectionLabel;
  }

  private boolean editable;

  @Override
  public boolean isEditable() {
    return editable;
  }

  public void setEditable(boolean editable) {
    this.editable = editable;
  }

  private Boolean showFilter = null;

  public void setShowFilter(boolean showFilter) {
    this.showFilter = showFilter;
  }

  @Override
  public boolean isShowFilter() {
    if (showFilter == null) {
      showFilter = getValues().size() >= SHOW_FILTER_VALUE_SIZE;
    }
    return showFilter;
  }

  protected Predicate<E> getValueFilter() {
    return valueFilter;
  }

  public void setValueFilter(Predicate<E> valueFilter) {
    this.valueFilter = valueFilter;
  }
}
