/*
 * Copyright 2017 Google Inc. 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.
 */

#include "starboard/shared/uwp/analog_thumbstick_input.h"

#include <Windows.Gaming.Input.h>
#include <algorithm>

#include "starboard/log.h"
#include "starboard/shared/win32/error_utils.h"
#include "starboard/types.h"

#pragma comment(lib, "xinput9_1_0.lib")

using Windows::Foundation::Collections::IVectorView;
using Windows::Gaming::Input::Gamepad;
using Windows::Gaming::Input::GamepadReading;
using Windows::Gaming::Input::RawGameController;

namespace starboard {
namespace shared {
namespace uwp {
namespace {

const int kMaxPlayerCounter = 4;
const float kDeadZoneThreshold = .24f;

float ApplyLinearDeadZone(float value, float maxValue, float deadZoneSize) {
  if (value < -deadZoneSize) {
    // Increase negative values to remove the deadzone discontinuity.
    value += deadZoneSize;
  } else if (value > deadZoneSize) {
    // Decrease positive values to remove the deadzone discontinuity.
    value -= deadZoneSize;
  } else {
    // Values inside the deadzone come out zero.
    return 0;
  }

  // Scale into 0-1 range.
  float scaledValue = value / (maxValue - deadZoneSize);
  return std::max(-1.f, std::min(scaledValue, 1.f));
}

void ApplyStickDeadZone(float x,
                        float y,
                        float max_value,
                        float dead_zone_size,
                        float* result_x,
                        float* result_y) {
  *result_x = ApplyLinearDeadZone(x, max_value, dead_zone_size);
  *result_y = ApplyLinearDeadZone(y, max_value, dead_zone_size);
}

ThumbSticks ReadThumbStick(Gamepad ^ controller) {
  ThumbSticks output;
  GamepadReading reading = controller->GetCurrentReading();

  ApplyStickDeadZone(static_cast<float>(reading.LeftThumbstickX),
                     static_cast<float>(reading.LeftThumbstickY), 1.f,
                     kDeadZoneThreshold, &output.left_x, &output.left_y);

  ApplyStickDeadZone(static_cast<float>(reading.RightThumbstickX),
                     static_cast<float>(reading.RightThumbstickY), 1.f,
                     kDeadZoneThreshold, &output.right_x, &output.right_y);
  return output;
}
}  // namespace

void GetGamepadThumbSticks(std::vector<ThumbSticks>* destination) {
  destination->erase(destination->begin(), destination->end());

  // This profiled to an average time of 33us to execute.
  IVectorView<Gamepad ^> ^ gamepads = Gamepad::Gamepads;

  // This profiled to take on average 9us of time to read controller state.
  const uint32_t n = gamepads->Size;
  for (uint32_t i = 0; i < n; ++i) {
    Gamepad ^ gamepad = gamepads->GetAt(i);
    ThumbSticks thumb_stick = ReadThumbStick(gamepad);
    destination->push_back(thumb_stick);
  }
}

}  // namespace uwp
}  // namespace shared
}  // namespace starboard
