// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.cobalt.coat;

import static dev.cobalt.util.Log.TAG;

import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.customview.widget.ExploreByTouchHelper;
import dev.cobalt.util.Log;
import java.util.BitSet;
import java.util.List;

/**
 * An ExploreByTouchHelper that create a virtual d-pad grid, so that Cobalt remains functional when
 * the TalkBack screen reader is enabled (which otherwise intercepts d-pad events for most
 * applications).
 */
class CobaltA11yHelper extends ExploreByTouchHelper {
  // These are from starboard/key.h
  private static final int SB_KEY_GAMEPAD_DPAD_UP = 0x800C;
  private static final int SB_KEY_GAMEPAD_DPAD_DOWN = 0x800D;
  private static final int SB_KEY_GAMEPAD_DPAD_LEFT = 0x800E;
  private static final int SB_KEY_GAMEPAD_DPAD_RIGHT = 0x800F;

  // The fake dimensions for the nine virtual views.
  // These values are arbitrary as long as the views stay on the screen.
  private static final int FAKE_VIEW_HEIGHT = 10;
  private static final int FAKE_VIEW_WIDTH = 10;

  private static final int CENTER_VIEW_ID = 5;
  private static final int UP_VIEW_ID = 2;
  private static final int DOWN_VIEW_ID = 8;
  private static final int LEFT_VIEW_ID = 4;
  private static final int RIGHT_VIEW_ID = 6;

  private static final int INPUT_FOCUS_CHANGE_DELAY = 1500; // milliseconds

  // This set tracks whether onPopulateNodeForVirtualView has been
  // called for each virtual view id.
  private final BitSet nodePopulatedSet = new BitSet(9);
  private final Handler handler = new Handler();
  private boolean unhandledInput;
  private boolean hasInitialFocusBeenSet;

  public CobaltA11yHelper(View view) {
    super(view);
    ViewCompat.setAccessibilityDelegate(view, this);
  }

  private static native void nativeInjectKeyEvent(int key);

  @Override
  protected int getVirtualViewAt(float x, float y) {
    // This method is only required for touch or mouse interfaces.
    // Since we don't support either, we simply always return HOST_ID.
    return HOST_ID;
  }

  @Override
  protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
    if (!virtualViewIds.isEmpty()) {
      throw new RuntimeException("Expected empty list");
    }
    // We always have precisely 9 virtual views.
    for (int i = 1; i <= 9; i++) {
      virtualViewIds.add(i);
    }
  }

  private void focusOnCenter() {
    // Setting Accessibility focus to CENTER_VIEW_ID will make TalkBack focus
    // on CENTER_VIEW_ID immediately, but the actual mouse focus is either
    // unchanged or return INVALID_ID.
    handler.post(
        new Runnable() {
          @Override
          public void run() {
            sendEventForVirtualView(
                CENTER_VIEW_ID, AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
          }
        });

    // There is a knwon Android bug about setting focus too early
    // taking no effect. The impact for Cobalt is that sometimes after
    // we click on a video, TalkBack sees nothing in focus in the watch
    // page if no user input happens. To avoid this bug we have to
    // delay the focus long enough for all the TalkBack movements to settle
    // down. More details here: https://stackoverflow.com/questions/28472985.
    handler.postDelayed(
        new Runnable() {
          @Override
          public void run() {
            sendEventForVirtualView(
                CENTER_VIEW_ID, AccessibilityEvent.TYPE_VIEW_FOCUSED);
          }
        }, INPUT_FOCUS_CHANGE_DELAY);
  }

  private void maybeInjectEvent(int currentFocusedViewId) {
    if (!unhandledInput) { 
      return;
    }
    switch (currentFocusedViewId) {
      case CENTER_VIEW_ID:
        // no move;
        break;
      case UP_VIEW_ID:
        nativeInjectKeyEvent(SB_KEY_GAMEPAD_DPAD_UP);
        break;
      case LEFT_VIEW_ID:
        nativeInjectKeyEvent(SB_KEY_GAMEPAD_DPAD_LEFT);
        break;
      case RIGHT_VIEW_ID:
        nativeInjectKeyEvent(SB_KEY_GAMEPAD_DPAD_RIGHT);
        break;
      case DOWN_VIEW_ID:
        nativeInjectKeyEvent(SB_KEY_GAMEPAD_DPAD_DOWN);
        break;
      default:
        // TODO: Could support diagonal movements, although it's likely
        // not possible to reach this.
        break;
    }
    unhandledInput = false;
    focusOnCenter();
  }

  /**
   * <p>Fake number grid:
   *   |+-+-+-+
   *   ||1|2|3|
   *   |+-+-+-|
   *   ||4|5|6|
   *   |+-+-+-|
   *   ||7|8|9|
   *   |+-+-+-+
   *
   * <p>The focus always starts from the middle number 5. When user changes
   * focus, the focus is then moved to either 2, 4, 6 or 8 and we can capture
   * the movement this way. The focus is then quickly switched back to the
   * center 5 to be ready for the next movement.
   *
   */
  @Override
  protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat node) {
    int focusedViewId = getAccessibilityFocusedVirtualViewId();

    if (focusedViewId < 1 || focusedViewId > 9) {
      // If this is not one of our nine-patch views, it's probably HOST_ID
      // In any case, assume there is no focus change.
      focusedViewId = CENTER_VIEW_ID;
    }

    // onPopulateNodeForVirtualView() gets called at least once every
    // time the focused view changes. So see if it's changed since the
    // last time we've been called and inject an event if so.
    if (focusedViewId != CENTER_VIEW_ID) {
      maybeInjectEvent(focusedViewId);
    } else {
      unhandledInput = true;
    }

    int x = (virtualViewId - 1) % 3;
    int y = (virtualViewId - 1) / 3;

    // Note that the specific bounds here are arbitrary. The importance
    // is the relative bounds to each other.
    node.setBoundsInParent(new Rect(
        x * FAKE_VIEW_WIDTH,
        y * FAKE_VIEW_HEIGHT,
        x * FAKE_VIEW_WIDTH + FAKE_VIEW_WIDTH,
        y * FAKE_VIEW_HEIGHT + FAKE_VIEW_HEIGHT));
    node.setText("");

    if (virtualViewId >= 1 || virtualViewId <= 9) {
      nodePopulatedSet.set(virtualViewId - 1);
    }
    if (!hasInitialFocusBeenSet && nodePopulatedSet.cardinality() == 9) {
      // Once the ExploreByTouchHelper knows about all of our virtual views,
      // but not before, ask that the accessibility focus be moved from
      // it's initial position on HOST_ID to the one we want to start with.
      hasInitialFocusBeenSet = true;
      focusOnCenter();
    }
  }

  @Override
  protected boolean onPerformActionForVirtualView(int virtualViewId, int action, Bundle arguments) {
    return false;
  }
}
