// Copyright 2010-2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package org.mozc.android.inputmethod.japanese;

import org.mozc.android.inputmethod.japanese.InOutAnimatedFrameLayout.VisibilityChangeListener;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.Command;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.CompositionMode;
import org.mozc.android.inputmethod.japanese.view.Skin;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.res.Resources;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;

/**
 * Manages candidate views (floating, on-keyboard).
 */
class CandidateViewManager implements MemoryManageable {

  /** Listener interface to handle the height change of a keyboard candidate view. */
  public interface KeyboardCandidateViewHeightListener {
    public void onExpanded();
    public void onCollapse();
  }

  private static class ClearCandidateAnimationListener implements Animation.AnimationListener {
    private final CandidateView candidateView;

    public ClearCandidateAnimationListener(CandidateView candidateView) {
      this.candidateView = Preconditions.checkNotNull(candidateView);
    }

    @Override
    public void onAnimationEnd(Animation animation) {
      candidateView.update(EMPTY_COMMAND);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationStart(Animation animation) {
    }
  }

  /** {@link CandidateMode#FLOATING} is only available on Lollipop or later. */
  private enum CandidateMode {
    KEYBOARD, NUMBER, FLOATING,
  }

  private static final Animation NO_ANIMATION = new Animation() {};
  @VisibleForTesting static final Command EMPTY_COMMAND = Command.getDefaultInstance();

  @VisibleForTesting final CandidateView keyboardCandidateView;
  @VisibleForTesting final FloatingCandidateView floatingCandidateView;
  /**
   * SymbolInputView which number candidate view belongs to is created lazily.
   * Therefore number candidate view is not accessible when CandidateViewManager is instantiated.
   */
  @VisibleForTesting Optional<CandidateView> numberCandidateView = Optional.absent();

  private Optional<KeyboardCandidateViewHeightListener> keyboardCandidateViewHeightListener =
      Optional.absent();
  /**
   * Current active candidate view.
   * {@link CandidateMode#FLOATING} is only available on Lollipop or later.
   */
  private CandidateMode candidateMode = CandidateMode.KEYBOARD;

  /** Cache of {@link EditorInfo} instance to switch candidate views. */
  private EditorInfo editorInfo = new EditorInfo();
  /** Cache of {@link Skin} instance to switch candidate views. */
  private Skin skin = Skin.getFallbackInstance();
  /** Cache of candidate text size. */
  private float candidateTextSize;
  /** Cache of description text size. */
  private float descriptionTextSize;
  /** Cache of {@link ViewEventListener}. */
  private Optional<ViewEventListener> viewEventListener = Optional.absent();
  /** Cache of {@link VisibilityChangeListener}. */
  private Optional<VisibilityChangeListener> onVisibilityChangeListener = Optional.absent();
  /**
   * True if extracted mode (== fullscreen mode) is activated.
   * <p>
   * On extracted mode, floating candidate should be disabled in order to show extracted view
   * in the screen.
   */
  private boolean isExtractedMode = false;
  private boolean allowFloatingMode = false;
  private boolean narrowMode = false;

  /**
   * Cache of {@link CursorAnchorInfo} instance to switch candidate views.
   * This field is null if and only-if Floating candidate view is NOT available, so we don't mark
   * this value as {code @Nullable} since this field should NOT be used in that situation.
   */
  private CursorAnchorInfo cursorAnchorInfo;

  private Animation numberCandidateViewInAnimation = NO_ANIMATION;
  private Animation numberCandidateViewOutAnimation = NO_ANIMATION;

  @SuppressLint("NewApi")
  public CandidateViewManager(
      CandidateView keyboardCandidateView, FloatingCandidateView floatingCandidateView) {
    this.keyboardCandidateView = Preconditions.checkNotNull(keyboardCandidateView);
    this.floatingCandidateView = Preconditions.checkNotNull(floatingCandidateView);
    if (FloatingCandidateView.isAvailable()) {
      cursorAnchorInfo = new CursorAnchorInfo.Builder().build();
    }

    keyboardCandidateView.setOutAnimationListener(
        new ClearCandidateAnimationListener(keyboardCandidateView));
  }

  public void setNumberCandidateView(CandidateView numberCandidateView) {
    this.numberCandidateView = Optional.of(numberCandidateView);
    numberCandidateView.setSkin(skin);
    numberCandidateView.enableFoldButton(true);
    numberCandidateView.setInAnimation(numberCandidateViewInAnimation);
    numberCandidateView.setOutAnimation(numberCandidateViewOutAnimation);
    numberCandidateView.setOutAnimationListener(
        new ClearCandidateAnimationListener(numberCandidateView));
    if (candidateTextSize > 0 && descriptionTextSize > 0) {
      numberCandidateView.setCandidateTextDimension(candidateTextSize, descriptionTextSize);
    }
    if (viewEventListener.isPresent()) {
      numberCandidateView.setViewEventListener(viewEventListener.get());
    }
    numberCandidateView.setOnVisibilityChangeListener(onVisibilityChangeListener.orNull());
  }

  /**
   * Updates the candidate views by {@code outCommand} and may invoke some animations.
   * <p>
   * On-keyboard candidate view may animate and the animation listener may be invoked.
   */
  public void update(Command outCommand) {
    updateInternal(Preconditions.checkNotNull(outCommand), true);
  }

  private void updateWithoutAnimation(Command outCommand) {
    updateInternal(outCommand, false);
  }

  private void updateInternal(Command outCommand, boolean withAnimation) {
    if (candidateMode == CandidateMode.FLOATING) {
      floatingCandidateView.setCandidates(outCommand);
      return;
    }

    Preconditions.checkState(
        candidateMode == CandidateMode.KEYBOARD
        || (candidateMode == CandidateMode.NUMBER && numberCandidateView.isPresent()));
    CandidateView candidateView = (candidateMode == CandidateMode.KEYBOARD)
        ? keyboardCandidateView : numberCandidateView.get();

    if (withAnimation) {
      if (hasCandidates(outCommand)) {
        candidateView.update(outCommand);
        // Call CandidateView#update only if there are some candidates in the output.
        // In such case the candidate view will clear its canvas.
        startKeyboardCandidateViewInAnimation();
      } else {
        // We don't call update method here and clear candidates at the end of this animation,
        // because it will clear the view's contents during the animation.
        startKeyboardCandidateViewOutAnimation();
      }
    } else {
      candidateView.update(outCommand);
      if (hasCandidates(outCommand)) {
        candidateView.setVisibility(View.VISIBLE);
      } else {
        candidateView.setVisibility(View.GONE);
      }
    }
  }

  public void setOnVisibilityChangeListener(Optional<VisibilityChangeListener> listener) {
    this.onVisibilityChangeListener = Preconditions.checkNotNull(listener);
    keyboardCandidateView.setOnVisibilityChangeListener(listener.orNull());
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().setOnVisibilityChangeListener(listener.orNull());
    }
  }

  /**
   * Enables/Disables a floating candidate view.
   * <p>
   * This method turned floating mode on if it is preferred.
   * The floating candidate view is only available on Lollipop or later.
   */
  private void updateCandiadateWindowActivation() {
    boolean floatingMode = narrowMode && allowFloatingMode && !isExtractedMode;
    if (floatingMode == (candidateMode == CandidateMode.FLOATING)) {
      return;
    }

    // Clears candidates on the current candidate window.
    updateWithoutAnimation(EMPTY_COMMAND);

    // Updates the other candidate view.
    candidateMode = floatingMode ? CandidateMode.FLOATING : CandidateMode.KEYBOARD;
    updateWithoutAnimation(EMPTY_COMMAND);
    setEditorInfo(editorInfo);
    if (FloatingCandidateView.isAvailable()) {
      setCursorAnchorInfo(cursorAnchorInfo);
    }
    // In order to show extracted view correctly, make the visibility GONE when it is not activated.
    floatingCandidateView.setVisibility(floatingMode ? View.VISIBLE : View.GONE);
  }

  public void setAllowFloatingMode(boolean allowFloatingMode) {
    Preconditions.checkArgument(!allowFloatingMode || FloatingCandidateView.isAvailable());
    this.allowFloatingMode = allowFloatingMode;
    updateCandiadateWindowActivation();
  }

  public void setNarrowMode(boolean narrowMode) {
    this.narrowMode = narrowMode;
    keyboardCandidateView.enableFoldButton(!narrowMode);
    updateCandiadateWindowActivation();
  }

  public void setNumberMode(boolean numberMode) {
    CandidateMode nextMode = numberMode ? CandidateMode.NUMBER : CandidateMode.KEYBOARD;
    if (candidateMode == nextMode) {
      return;
    }
    if (nextMode == CandidateMode.NUMBER) {
      // Hide keyboard candidate view since it is higher than symbol view.
      updateWithoutAnimation(EMPTY_COMMAND);
    }
    candidateMode = nextMode;
    // Set empty command in order to clear the candidates which have been registered into the next
    // view. Otherwise such candidates (typically they are obsolete) are shown unexpectedly.
    // TODO(hsumita): Revisit when Mozc server returns candidates for SWITCH_INPUT_MODE command.
    updateWithoutAnimation(EMPTY_COMMAND);
  }

  public void setCandidateTextDimension(float candidateTextSize, float descriptionTextSize) {
    this.candidateTextSize = candidateTextSize;
    this.descriptionTextSize = descriptionTextSize;
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().setCandidateTextDimension(
          candidateTextSize, descriptionTextSize);
    } else {
      keyboardCandidateView.setCandidateTextDimension(candidateTextSize, descriptionTextSize);
    }
  }

  public void setInputFrameFoldButtonChecked(boolean isChecked) {
    switch (candidateMode) {
      case KEYBOARD:
        keyboardCandidateView.setInputFrameFoldButtonChecked(isChecked);
        break;
      case NUMBER:
        numberCandidateView.get().setInputFrameFoldButtonChecked(isChecked);
        break;
      case FLOATING:
        throw new IllegalStateException("Fold button is not available on floating mode.");
    }
  }

  public void setEditorInfo(EditorInfo info) {
    this.editorInfo = Preconditions.checkNotNull(info);
    if (candidateMode == CandidateMode.FLOATING) {
      floatingCandidateView.setEditorInfo(info);
    }
  }

  @TargetApi(21)
  public void setCursorAnchorInfo(CursorAnchorInfo info) {
    this.cursorAnchorInfo = Preconditions.checkNotNull(info);
    if (candidateMode == CandidateMode.FLOATING) {
      floatingCandidateView.setCursorAnchorInfo(info);
    }
  }

  public void setSkin(Skin skin) {
    this.skin = Preconditions.checkNotNull(skin);
    keyboardCandidateView.setSkin(skin);
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().setSkin(skin);
    }
  }

  public void setEventListener(ViewEventListener viewEventListener,
                               KeyboardCandidateViewHeightListener hightListener) {
    this.viewEventListener = Optional.of(viewEventListener);
    this.keyboardCandidateViewHeightListener = Optional.of(hightListener);
    keyboardCandidateView.setViewEventListener(viewEventListener);
    floatingCandidateView.setViewEventListener(viewEventListener);
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().setViewEventListener(viewEventListener);
    }
  }

  /**
   * Set true if extracted mode (== fullscreen mode) is activated.
   */
  public void setExtractedMode(boolean isExtractedMode) {
    this.isExtractedMode = isExtractedMode;
    updateCandiadateWindowActivation();
  }

  public void setHardwareCompositionMode(CompositionMode mode) {
    if (isFloatingMode()) {
      floatingCandidateView.setCompositionMode(mode);
    }
  }

  public void reset() {
    keyboardCandidateView.clearAnimation();
    keyboardCandidateView.setVisibility(View.GONE);
    keyboardCandidateView.reset();
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().clearAnimation();
      numberCandidateView.get().setVisibility(View.GONE);
      numberCandidateView.get().reset();
    }

    candidateMode = CandidateMode.KEYBOARD;
    floatingCandidateView.setVisibility(View.GONE);
  }

  public void resetHeightDependingComponents(
      Resources resources, int windowHeight, int inputFrameHeight) {
    Preconditions.checkNotNull(resources);

    int keyboardCandidateViewHeight = windowHeight - inputFrameHeight;
    long duration = resources.getInteger(R.integer.candidate_frame_transition_duration);
    float fromAlpha = 0.0f;
    float toAlpha = 1.0f;

    keyboardCandidateView.setInAnimation(createKeyboardCandidateViewTransitionAnimation(
        keyboardCandidateViewHeight, 0, fromAlpha, toAlpha, duration));
    keyboardCandidateView.setOutAnimation(createKeyboardCandidateViewTransitionAnimation(
        0, keyboardCandidateViewHeight, toAlpha, fromAlpha, duration));

    int numberCandidateViewHeight = resources.getDimensionPixelSize(R.dimen.button_frame_height);
    numberCandidateViewInAnimation = createKeyboardCandidateViewTransitionAnimation(
        numberCandidateViewHeight, 0, fromAlpha, toAlpha, duration);
    numberCandidateViewOutAnimation = createKeyboardCandidateViewTransitionAnimation(
        0, numberCandidateViewHeight, toAlpha, fromAlpha, duration);
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().setInAnimation(numberCandidateViewInAnimation);
      numberCandidateView.get().setOutAnimation(numberCandidateViewOutAnimation);
    }
  }

  public boolean isKeyboardCandidateViewVisible() {
    return keyboardCandidateView.getVisibility() == View.VISIBLE;
  }

  private static Animation createKeyboardCandidateViewTransitionAnimation(
      int fromY, int toY, float fromAlpha, float toAlpha, long duration) {
    AnimationSet animation = new AnimationSet(false);
    animation.setDuration(duration);

    AlphaAnimation alphaAnimation = new AlphaAnimation(fromAlpha, toAlpha);
    alphaAnimation.setDuration(duration);
    animation.addAnimation(alphaAnimation);

    TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, fromY, toY);
    translateAnimation.setInterpolator(new DecelerateInterpolator());
    translateAnimation.setDuration(duration);
    animation.addAnimation(translateAnimation);
    return animation;
  }

  private void startKeyboardCandidateViewInAnimation() {
    switch (candidateMode) {
      case KEYBOARD:
        keyboardCandidateView.startInAnimation();
        if (keyboardCandidateViewHeightListener.isPresent()) {
          keyboardCandidateViewHeightListener.get().onExpanded();
        }
        break;
      case NUMBER:
        numberCandidateView.get().startInAnimation();
        break;
      case FLOATING:
        throw new IllegalStateException("Floating mode doesn't support in-animation.");
    }
  }

  private void startKeyboardCandidateViewOutAnimation() {
    switch (candidateMode) {
      case KEYBOARD:
        if (keyboardCandidateViewHeightListener.isPresent()) {
          keyboardCandidateViewHeightListener.get().onCollapse();
        }
        keyboardCandidateView.startOutAnimation();
        break;
      case NUMBER:
        numberCandidateView.get().startOutAnimation();
        break;
      case FLOATING:
        throw new IllegalStateException("Floating mode doesn't support out-animation.");
    }
  }

  private static boolean hasCandidates(Command command) {
    return command.getOutput().getAllCandidateWords().getCandidatesCount() > 0;
  }

  @Override
  public void trimMemory() {
    keyboardCandidateView.trimMemory();
    if (numberCandidateView.isPresent()) {
      numberCandidateView.get().trimMemory();
    }
  }

  public boolean isFloatingMode() {
    return candidateMode == CandidateMode.FLOATING;
  }
}
