// Copyright 2010-2015, 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.keyboard.BackgroundDrawableFactory.DrawableType;
import org.mozc.android.inputmethod.japanese.keyboard.Flick;
import org.mozc.android.inputmethod.japanese.keyboard.Flick.Direction;
import org.mozc.android.inputmethod.japanese.keyboard.Key;
import org.mozc.android.inputmethod.japanese.keyboard.Key.Stick;
import org.mozc.android.inputmethod.japanese.keyboard.KeyEntity;
import org.mozc.android.inputmethod.japanese.keyboard.KeyEventContext;
import org.mozc.android.inputmethod.japanese.keyboard.KeyEventHandler;
import org.mozc.android.inputmethod.japanese.keyboard.KeyState;
import org.mozc.android.inputmethod.japanese.keyboard.PopUp;
import org.mozc.android.inputmethod.japanese.protobuf.ProtoCommands.Input.TouchAction;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;

import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

import java.util.Collections;

/**
 * This class is an event listener for a view which sends a key to MozcServer.
 *
 * Note that currently, we assume all key are repeatable based on our
 * requirements. We can easily support non repeatable key if necessary.
 *
 */
public class KeyEventButtonTouchListener implements OnTouchListener {

  private final int sourceId;
  private final int keyCode;
  private KeyEventHandler keyEventHandler = null;
  @VisibleForTesting KeyEventContext keyEventContext = null;

  /**
   * This is exported as protected for testing.
   */
  protected KeyEventButtonTouchListener(int sourceId, int keyCode) {
    this.sourceId = sourceId;
    this.keyCode = keyCode;
  }

  /**
   * Resets the internal state of this listener.
   * This is exported as protected for testing.
   */
  protected void reset() {
    KeyEventHandler keyEventHandler = this.keyEventHandler;
    KeyEventContext keyEventContext = this.keyEventContext;
    if (keyEventHandler != null && keyEventContext != null) {
      keyEventHandler.cancelDelayedKeyEvent(keyEventContext);
    }
    this.keyEventContext = null;
  }

  /**
   * Sets a new event handler to this instance.
   * This is exported as protected for testing.
   */
  protected void setKeyEventHandler(KeyEventHandler keyEventHandler) {
    // We'll detach the current event context from the old key event handler.
    reset();
    this.keyEventHandler = keyEventHandler;
  }

  /**
   * Creates a (pseudo) {@link Key} instance based on the given {@code button} and its
   * {@code keyCode}.
   * This is exported as package private for testing.
   */
  @VisibleForTesting static Key createKey(View button, int sourceId, int keyCode) {
    KeyEntity keyEntity = new KeyEntity(
            sourceId, keyCode, KeyEntity.INVALID_KEY_CODE, true, 0,
            Optional.<String>absent(), false,
            Optional.<PopUp>absent(), 0, 0, 0, 0);
    Flick flick = new Flick(Direction.CENTER, keyEntity);
    KeyState keyState =
        new KeyState("",
                     Collections.<KeyState.MetaState>emptySet(),
                     Collections.<KeyState.MetaState>emptySet(),
                     Collections.<KeyState.MetaState>emptySet(),
                     Collections.singletonList(flick));
    // Now, we support repeatable keys only.
    return new Key(0, 0, button.getWidth(), button.getHeight(), 0, 0,
                   true, false, Stick.EVEN, DrawableType.TWELVEKEYS_REGULAR_KEY_BACKGROUND,
                   Collections.singletonList(keyState));
  }

  private static KeyEventContext createKeyEventContext(
      View button, int sourceId, int keyCode, float x, float y) {
    Key key = createKey(button, sourceId, keyCode);
    View parent = View.class.cast(button.getParent());
    return new KeyEventContext(
        key, 0, x, y, parent.getWidth(), parent.getHeight(), 0,
        Collections.<KeyState.MetaState>emptySet());
  }

  /**
   * Handles the button view's down event.
   * This is exported as package private for testing purpose.
   */
  void onDown(View button, float x, float y) {
    button.setPressed(true);

    KeyEventHandler keyEventHandler = this.keyEventHandler;
    if (keyEventHandler != null) {
      // At first, cancel pending repeat events and overwrite it by the given keyCode.
      KeyEventContext oldKeyEventContext = this.keyEventContext;
      if (oldKeyEventContext != null) {
        keyEventHandler.cancelDelayedKeyEvent(keyEventContext);
      }

      // Then create and start running new event. Note that we don't need create it
      // if keyEventHandler is not set, because it will be reset in setKeyEventHandler
      // when a new keyEventHandler is set.
      KeyEventContext newContext = createKeyEventContext(button, sourceId, keyCode, x, y);
      newContext.update(x, y, TouchAction.TOUCH_DOWN, 0);
      keyEventHandler.maybeStartDelayedKeyEvent(newContext);
      keyEventHandler.sendPress(newContext.getPressedKeyCode());
      this.keyEventContext = newContext;
    }
  }

  /**
   * Handles the button view's up event.
   * This is exported as package private for testing purpose.
   */
  void onUp(View button, float x, float y, long timestamp) {
    button.setPressed(false);

    KeyEventHandler keyEventHandler = this.keyEventHandler;
    KeyEventContext keyEventContext = this.keyEventContext;
    if (keyEventHandler != null && keyEventContext != null) {
      keyEventContext.update(x, y, TouchAction.TOUCH_UP, timestamp);
      keyEventHandler.cancelDelayedKeyEvent(keyEventContext);
      // TODO(hsumita): Confirm that we can put null as a touch event or not.
      keyEventHandler.sendKey(keyEventContext.getKeyCode(),
                              Collections.singletonList(keyEventContext.getTouchEvent().orNull()));
      keyEventHandler.sendRelease(keyEventContext.getPressedKeyCode());
    }
    this.keyEventContext = null;
  }

  /**
   * Handles the button view's move event.
   * This is exported as package private for testing purpose.
   */
  void onMove(float x, float y, long timestamp) {
    KeyEventContext keyEventContext = this.keyEventContext;
    if (keyEventContext != null &&
        keyEventContext.update(x, y, TouchAction.TOUCH_MOVE, timestamp)) {
      // Here, the user's touching point is moved to outside of the button view,
      // so cancel the repeating key event.
      KeyEventHandler keyEventHandler = this.keyEventHandler;
      if (keyEventHandler != null) {
        keyEventHandler.cancelDelayedKeyEvent(keyEventContext);
      }
      this.keyEventContext = null;
    }
  }

  @Override
  public boolean onTouch(View button, MotionEvent event) {
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
      case MotionEvent.ACTION_DOWN:
        onDown(button, event.getX(), event.getY());
        break;
      case MotionEvent.ACTION_UP:
        onUp(button, event.getX(), event.getY(), event.getEventTime() - event.getDownTime());
        break;
      case MotionEvent.ACTION_MOVE:
        onMove(event.getX(), event.getY(), event.getEventTime() - event.getDownTime());
        break;
      default:
        // Ignore other events intentionally.
    }

    // Consume all the events here in order not to propagate the event to views behind the button.
    return true;
  }
}
