// Copyright 2017 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/vr/openvr/openvr_gamepad_helper.h"

#include <memory>

#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "device/gamepad/public/cpp/gamepads.h"
#include "device/vr/vr_device.h"
#include "third_party/openvr/src/headers/openvr.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/transform_util.h"

namespace device {

namespace {

mojom::XRGamepadButtonPtr GetGamepadButton(
    const vr::VRControllerState_t& controller_state,
    uint64_t supported_buttons,
    vr::EVRButtonId button_id) {
  uint64_t button_mask = vr::ButtonMaskFromId(button_id);
  if ((supported_buttons & button_mask) != 0) {
    auto ret = mojom::XRGamepadButton::New();
    bool button_pressed = (controller_state.ulButtonPressed & button_mask) != 0;
    bool button_touched = (controller_state.ulButtonTouched & button_mask) != 0;
    ret->touched = button_touched;
    ret->pressed = button_pressed;
    ret->value = button_pressed ? 1.0 : 0.0;
    return ret;
  }

  return nullptr;
}

}  // namespace

mojom::XRGamepadDataPtr OpenVRGamepadHelper::GetGamepadData(
    vr::IVRSystem* vr_system) {
  mojom::XRGamepadDataPtr ret = mojom::XRGamepadData::New();

  vr::TrackedDevicePose_t tracked_devices_poses[vr::k_unMaxTrackedDeviceCount];
  vr_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseSeated, 0.0f,
                                             tracked_devices_poses,
                                             vr::k_unMaxTrackedDeviceCount);
  for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) {
    if (vr_system->GetTrackedDeviceClass(i) !=
        vr::TrackedDeviceClass_Controller)
      continue;

    vr::VRControllerState_t controller_state;
    bool have_state = vr_system->GetControllerState(i, &controller_state,
                                                    sizeof(controller_state));
    if (!have_state)
      continue;

    auto gamepad = mojom::XRGamepad::New();
    gamepad->controller_id = i;

    gamepad->timestamp = base::TimeTicks::Now();

    vr::ETrackedControllerRole hand =
        vr_system->GetControllerRoleForTrackedDeviceIndex(i);
    switch (hand) {
      case vr::TrackedControllerRole_Invalid:
        gamepad->hand = device::mojom::XRHandedness::NONE;
        break;
      case vr::TrackedControllerRole_LeftHand:
        gamepad->hand = device::mojom::XRHandedness::LEFT;
        break;
      case vr::TrackedControllerRole_RightHand:
        gamepad->hand = device::mojom::XRHandedness::RIGHT;
        break;
    }

    uint64_t supported_buttons = vr_system->GetUint64TrackedDeviceProperty(
        i, vr::Prop_SupportedButtons_Uint64);
    for (uint32_t j = 0; j < vr::k_unControllerStateAxisCount; ++j) {
      int32_t axis_type = vr_system->GetInt32TrackedDeviceProperty(
          i,
          static_cast<vr::TrackedDeviceProperty>(vr::Prop_Axis0Type_Int32 + j));
      switch (axis_type) {
        case vr::k_eControllerAxis_Joystick:
        case vr::k_eControllerAxis_TrackPad: {
          gamepad->axes.push_back(controller_state.rAxis[j].x);
          gamepad->axes.push_back(controller_state.rAxis[j].y);
          auto button = GetGamepadButton(
              controller_state, supported_buttons,
              static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j));
          if (button) {
            gamepad->buttons.push_back(std::move(button));
          }
        } break;
        case vr::k_eControllerAxis_Trigger: {
          auto button = mojom::XRGamepadButton::New();
          button->value = controller_state.rAxis[j].x;
          uint64_t button_mask = vr::ButtonMaskFromId(
              static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j));
          if ((supported_buttons & button_mask) != 0) {
            button->pressed =
                (controller_state.ulButtonPressed & button_mask) != 0;
          }
          gamepad->buttons.push_back(std::move(button));
        } break;
      }
    }

    auto button =
        GetGamepadButton(controller_state, supported_buttons, vr::k_EButton_A);
    if (button)
      gamepad->buttons.push_back(std::move(button));
    button = GetGamepadButton(controller_state, supported_buttons,
                              vr::k_EButton_Grip);
    if (button)
      gamepad->buttons.push_back(std::move(button));
    button = GetGamepadButton(controller_state, supported_buttons,
                              vr::k_EButton_ApplicationMenu);
    if (button)
      gamepad->buttons.push_back(std::move(button));
    button = GetGamepadButton(controller_state, supported_buttons,
                              vr::k_EButton_DPad_Left);
    if (button)
      gamepad->buttons.push_back(std::move(button));
    button = GetGamepadButton(controller_state, supported_buttons,
                              vr::k_EButton_DPad_Up);
    if (button)
      gamepad->buttons.push_back(std::move(button));
    button = GetGamepadButton(controller_state, supported_buttons,
                              vr::k_EButton_DPad_Right);
    if (button)
      gamepad->buttons.push_back(std::move(button));
    button = GetGamepadButton(controller_state, supported_buttons,
                              vr::k_EButton_DPad_Down);
    if (button)
      gamepad->buttons.push_back(std::move(button));

    const vr::TrackedDevicePose_t& pose = tracked_devices_poses[i];
    if (pose.bPoseIsValid) {
      const vr::HmdMatrix34_t& mat = pose.mDeviceToAbsoluteTracking;
      gfx::Transform transform(
          mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0],
          mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1],
          mat.m[2][2], mat.m[2][3], 0, 0, 0, 1);

      gfx::DecomposedTransform src_pose;
      gfx::DecomposeTransform(&src_pose, transform);
      auto dst_pose = mojom::VRPose::New();

      dst_pose->orientation = std::vector<float>(
          {src_pose.quaternion.x(), src_pose.quaternion.y(),
           src_pose.quaternion.z(), src_pose.quaternion.w()});
      dst_pose->position =
          std::vector<float>({src_pose.translate[0], src_pose.translate[1],
                              src_pose.translate[2]});
      dst_pose->angularVelocity = std::vector<float>(
          {pose.vAngularVelocity.v[0], pose.vAngularVelocity.v[1],
           pose.vAngularVelocity.v[2]});
      dst_pose->linearVelocity = std::vector<float>(
          {pose.vVelocity.v[0], pose.vVelocity.v[1], pose.vVelocity.v[2]});

      gamepad->pose = std::move(dst_pose);
    }

    ret->gamepads.push_back(std::move(gamepad));
  }

  return ret;
}

}  // namespace device
