// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/gamepad/gamepad_platform_data_fetcher_android.h"

#include <stddef.h>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"

#include "jni/GamepadList_jni.h"

using base::android::AttachCurrentThread;
using base::android::CheckException;
using base::android::ClearException;
using base::android::ConvertJavaStringToUTF8;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;

namespace device {

GamepadPlatformDataFetcherAndroid::GamepadPlatformDataFetcherAndroid() {
}

GamepadPlatformDataFetcherAndroid::~GamepadPlatformDataFetcherAndroid() {
  PauseHint(true);
}

GamepadSource GamepadPlatformDataFetcherAndroid::source() {
  return Factory::static_source();
}

void GamepadPlatformDataFetcherAndroid::OnAddedToProvider() {
  PauseHint(false);
}

void GamepadPlatformDataFetcherAndroid::GetGamepadData(
    bool devices_changed_hint) {
  TRACE_EVENT0("GAMEPAD", "GetGamepadData");

  JNIEnv* env = AttachCurrentThread();
  if (!env)
    return;

  Java_GamepadList_updateGamepadData(env, reinterpret_cast<intptr_t>(this));
}

void GamepadPlatformDataFetcherAndroid::PauseHint(bool paused) {
  JNIEnv* env = AttachCurrentThread();
  if (!env)
    return;

  Java_GamepadList_setGamepadAPIActive(env, !paused);
}

static void JNI_GamepadList_SetGamepadData(
    JNIEnv* env,
    const JavaParamRef<jobject>& obj,
    jlong data_fetcher,
    jint index,
    jboolean mapping,
    jboolean connected,
    const JavaParamRef<jstring>& devicename,
    jlong timestamp,
    const JavaParamRef<jfloatArray>& jaxes,
    const JavaParamRef<jfloatArray>& jbuttons) {
  DCHECK(data_fetcher);
  GamepadPlatformDataFetcherAndroid* fetcher =
      reinterpret_cast<GamepadPlatformDataFetcherAndroid*>(data_fetcher);
  DCHECK_LT(index, static_cast<int>(Gamepads::kItemsLengthCap));

  // Do not set gamepad parameters for all the gamepad devices that are not
  // attached.
  if (!connected)
    return;

  PadState* state = fetcher->GetPadState(index);

  if (!state)
    return;

  Gamepad& pad = state->data;

  // Is this the first time we've seen this device?
  if (state->active_state == GAMEPAD_NEWLY_ACTIVE) {
    // Map the Gamepad DeviceName String to the Gamepad Id. Ideally it should
    // be mapped to vendor and product information but it is only available at
    // kernel level and it can not be queried using class
    // android.hardware.input.InputManager.
    base::string16 device_name;
    base::android::ConvertJavaStringToUTF16(env, devicename, &device_name);
    const size_t name_to_copy =
        std::min(device_name.size(), Gamepad::kIdLengthCap - 1);
    memcpy(pad.id, device_name.data(),
           name_to_copy * sizeof(base::string16::value_type));
    pad.id[name_to_copy] = 0;

    base::string16 mapping_name = base::UTF8ToUTF16(mapping ? "standard" : "");
    const size_t mapping_to_copy =
        std::min(mapping_name.size(), Gamepad::kMappingLengthCap - 1);
    memcpy(pad.mapping, mapping_name.data(),
           mapping_to_copy * sizeof(base::string16::value_type));
    pad.mapping[mapping_to_copy] = 0;
  }

  pad.connected = true;
  pad.timestamp = timestamp;

  std::vector<float> axes;
  base::android::JavaFloatArrayToFloatVector(env, jaxes, &axes);

  // Set Gamepad axeslength to total number of axes on the gamepad device.
  // Only return the first axesLengthCap if axeslength captured by GamepadList
  // is larger than axesLengthCap.
  pad.axes_length = std::min(static_cast<int>(axes.size()),
                             static_cast<int>(Gamepad::kAxesLengthCap));

  // Copy axes state to the Gamepad axes[].
  for (unsigned int i = 0; i < pad.axes_length; i++) {
    pad.axes[i] = static_cast<double>(axes[i]);
  }

  std::vector<float> buttons;
  base::android::JavaFloatArrayToFloatVector(env, jbuttons, &buttons);

  // Set Gamepad buttonslength to total number of axes on the gamepad
  // device. Only return the first buttonsLengthCap if axeslength captured by
  // GamepadList is larger than buttonsLengthCap.
  pad.buttons_length = std::min(static_cast<int>(buttons.size()),
                                static_cast<int>(Gamepad::kButtonsLengthCap));

  // Copy buttons state to the Gamepad buttons[].
  for (unsigned int j = 0; j < pad.buttons_length; j++) {
    pad.buttons[j].pressed = buttons[j];
    pad.buttons[j].value = buttons[j];
  }
}

}  // namespace device
