
package de.ivu.elect.presentation.kandidatur.action;

import static de.ivu.elect.jee.entity.EntityUtil.castTo;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;

import de.ivu.elect.business.kandidatur.boundary.ListenkandidaturChangeEvent;
import de.ivu.elect.business.kandidatur.boundary.ListenkandidaturExtendedDAO;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;

public abstract class AbstractListenkandidaturAction extends AbstractKandidaturAction {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient ListenkandidaturExtendedDAO listenkandidaturExtendedDAO;

  @Inject
  private transient ListenkandidaturChangeEvent listenkandidaturChangeEvent;

  protected AbstractListenkandidaturAction() {
    super();
  }

  @Override
  public boolean isDisabledInternal(@Nonnull Kandidatur kandidatur) {
    return super.isDisabledInternal(kandidatur) || !isListenkandidatur(kandidatur) || isDisabledInternal(asListenkandidatur(kandidatur));
  }

  protected boolean isDisabledInternal(Listenkandidatur listenkandidatur) {
    return isEinzelbewerber(listenkandidatur) || isWaehlerBenannteListenkandidatur(listenkandidatur); // Aktionen auf "Wähler benannten Personen" explizit zulassen!
  }

  @Override
  public String doIt(Kandidatur kandidatur) {
    if (isListenkandidatur(kandidatur)) {
      Listenkandidatur listenkandidatur = asListenkandidatur(kandidatur);

      if (listenkandidatur != null) {
        return doIt(listenkandidatur);
      }
    }

    throw new UnsupportedOperationException("Das Bearbeiten der uebergebenen Kandidatur [kandidatur = <" + kandidatur + ">] wird nicht unterstuetzt");
  }

  protected abstract String doIt(@Nonnull Listenkandidatur listenkandidatur);

  @Override
  protected void fireChangeEvent() {
    listenkandidaturChangeEvent.sendChangeEvent();
  }

  @Override
  protected Kandidatur attach(Kandidatur kandidatur) {
    if (isListenkandidatur(kandidatur)) {
      return asListenkandidatur(kandidatur);
    }

    return super.attach(kandidatur);
  }

  protected boolean isListenkandidatur(Kandidatur kandidatur) {
    return kandidatur != null && kandidatur.isInstanceOf(Listenkandidatur.class);
  }

  @Nullable
  protected Listenkandidatur asListenkandidatur(Kandidatur kandidatur) {
    if (isListenkandidatur(kandidatur)) {
      return listenkandidaturExtendedDAO.attach(castTo(kandidatur, Listenkandidatur.class));
    }

    return null;
  }
}
