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

import java.io.Serializable;

import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.apache.deltaspike.core.api.scope.ConversationGroup;

import de.ivu.elect.jee.exception.ElectCommonException;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.faces.UserLocale;
import de.ivu.elect.jee.presentation.AjaxHelper;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilderConfig;
import de.ivu.elect.jee.presentation.redirect.Redirect;

public abstract class AbstractView implements Serializable, ViewMarker {

  private static final long serialVersionUID = 1L;

  public static final String RESET_VIEW_STACK_REQUEST_PARAMETER_NAME = "resetViewStack";

  public static final String RESET_VIEW_STACK_REQUEST_VALUE = "true";

  @Inject
  protected transient AjaxHelper ajaxHelper;

  @Inject
  protected transient FormBuilderConfig formBuilderConfig;

  @Inject
  @ConversationGroup(ViewStack.class)
  protected transient ViewStack viewStack;

  @Inject
  protected transient UserLocale userLocale;

  @Inject
  protected transient Messages messages;

  public AbstractView() {
    super();
  }

  @PostConstruct
  public void initStack() {
    if (viewStack != null) {
      if (isResetViewStack()) {
        viewStack.reset();
      }

      viewStack.enter();
    }
  }

  @Nullable
  @Redirect
  public String goBack() {
    if (viewStack == null) {
      return null;
    }

    return viewStack.back();
  }

  @Redirect
  public String goBack(String fallBackViewId) {
    String goBack = goBack();

    if (goBack == null) {
      return fallBackViewId;
    }

    return goBack;
  }

  private boolean isResetViewStack() {
    try {
      HttpServletRequest request = FacesContextUtil.getRequest();
      if (request != null) {
        return RESET_VIEW_STACK_REQUEST_VALUE.equalsIgnoreCase(request.getParameter(RESET_VIEW_STACK_REQUEST_PARAMETER_NAME));
      }
    } catch (Exception e) {
      // ignore
    }
    return false;
  }

  protected boolean isViewStackEmpty() {
    return viewStack.isEmpty();
  }

  public void redirectToCurrentView() {
    redirectToView(FacesContextUtil.getCurrentViewId());
  }

  public void redirectToView(String viewId) {
    FacesContextUtil.redirectToView(viewId);
  }

  protected FormBuilder createFormBuilder() {
    return new FormBuilder();
  }

  protected String getMessage(Enum< ? > enumValue) {
    return getMessages().lokalisiere(enumValue);
  }

  protected String getMessage(String msgKey, Object... params) {
    return getMessages().getMessageForMessageKey(msgKey, params);
  }

  protected void addInfoMessage(String msgKey, Object... params) {
    getMessages().addInfoMessage(msgKey, params);
  }

  protected void addWarningMessage(String msgKey, Object... params) {
    getMessages().addWarnMessage(msgKey, params);
  }

  protected void addErrorMessage(ElectCommonException ex) {
    addErrorMessage(ex.getMessageKey(), ex.getObjects());
  }

  protected void addErrorMessage(Throwable cause) {
    if (cause != null) {
      addErrorMessage(Messages.LOCALIZED_MESSAGE_ONLY_MSG_KEY, cause.getLocalizedMessage());
    }
  }

  protected void addErrorMessage(String msgKey, Object... params) {
    getMessages().addErrorMessage(msgKey, params);
  }

  protected Messages getMessages() {
    return messages;
  }

  protected UserLocale getUserLocale() {
    return userLocale;
  }

  public boolean isBtnGoBackRendered() {
    return viewStackContainsOtherViewsAndShouldNotReset();
  }

  public boolean isBtnShowAllFormFieldsRendered() {
    return false;
  }

  // ELECT-5044
  protected boolean viewStackContainsOtherViewsAndShouldNotReset() {
    boolean viewStackEnthaeltAnderenView = !(isViewStackEmpty() || viewStack.containsOnly(FacesContextUtil.getCurrentViewId()));

    return viewStackEnthaeltAnderenView && !isResetViewStack();
  }

  // Möglichkeit, den PrimeFaces Spotlight immer zu setzen, siehe auch ELECTDD-260
  public boolean isForceSpotlight() {
    return false;
  }

  public String getStyleClass() {
    return "";
  }
}
