// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include <map>
#include <algorithm>
#include <iterator>

#include "common/emu_window.h"

#include "input_core/key_map.h"
#include "input_core/input_core.h"

namespace KeyMap {
    constexpr int MAX_CIRCLEPAD_POS = 0x9C; /// Max value for a circle pad position
    const std::array<KeyTarget, Settings::NativeInput::NUM_INPUTS> mapping_targets = { {
        Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y,
        Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR,
        Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_TOUCH,
        Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT,
        Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT,

        Service::HID::PAD_CIRCLE_UP,
        Service::HID::PAD_CIRCLE_DOWN,
        Service::HID::PAD_CIRCLE_LEFT,
        Service::HID::PAD_CIRCLE_RIGHT,
    } };
    ///Array of inputs that are analog only, and require a strength when set
    const std::array<KeyTarget, 4> analog_inputs = {
        Service::HID::PAD_CIRCLE_UP,
        Service::HID::PAD_CIRCLE_DOWN,
        Service::HID::PAD_CIRCLE_LEFT,
        Service::HID::PAD_CIRCLE_RIGHT
    };

    void PressKey(KeyTarget target, const float strength) {
        if (std::find(std::begin(analog_inputs), std::end(analog_inputs), target) == std::end(analog_inputs)) { // If is digital keytarget
            InputCore::pad_state.hex |= target.target.direct_target_hex;
        }
        else { // it is analog input
            if (target == Service::HID::PAD_CIRCLE_UP || target == Service::HID::PAD_CIRCLE_DOWN) {
                std::get<1>(InputCore::circle_pad) = MAX_CIRCLEPAD_POS * strength * -1;
            }
            else if (target == Service::HID::PAD_CIRCLE_LEFT || target == Service::HID::PAD_CIRCLE_RIGHT) {
                std::get<0>(InputCore::circle_pad) = MAX_CIRCLEPAD_POS * strength;
            }
        }
    }

    void ReleaseKey(KeyTarget target) {
        if (std::find(std::begin(analog_inputs), std::end(analog_inputs), target) == std::end(analog_inputs)) { // If is digital keytarget
            InputCore::pad_state.hex &= ~target.target.direct_target_hex;
        }
        else { // it is analog input
            if (target == Service::HID::PAD_CIRCLE_UP || target == Service::HID::PAD_CIRCLE_DOWN) {
                std::get<1>(InputCore::circle_pad) = 0;
            }
            else if (target == Service::HID::PAD_CIRCLE_LEFT || target == Service::HID::PAD_CIRCLE_RIGHT) {
                std::get<0>(InputCore::circle_pad) = 0;
            }
        }
    }
}