/*Copyright (C) 2010-2023 Duncan Deveaux

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Joystick.hpp"
#include "Key.hpp"

Joystick::Joystick() : m_gameController(nullptr), m_joystick(nullptr)
{

}

Joystick::~Joystick()
{
    close();
}

void Joystick::close()
{
    if (m_gameController != nullptr)
        SDL_GameControllerClose(m_gameController);
    else if (m_joystick != nullptr)
        SDL_JoystickClose(m_joystick);

    m_gameController = nullptr;
    m_joystick = nullptr;
}

bool Joystick::load(int joyIndex)
{
    close(); //Close any opened joystick

    if (SDL_IsGameController(joyIndex))
    {
        m_gameController = SDL_GameControllerOpen(joyIndex);
        m_joystick = SDL_GameControllerGetJoystick(m_gameController);
    }
    else
        m_joystick = SDL_JoystickOpen(joyIndex);

    return (m_joystick != nullptr);
}

std::string Joystick::getName() const
{
    const char *name = nullptr;
    if (m_gameController != nullptr)
        name = SDL_GameControllerName(m_gameController);
    else if (m_joystick != nullptr)
        name = SDL_JoystickName(m_joystick);

    return (name != nullptr) ? std::string(name) : "undefined";
}

int Joystick::getInstanceID() const
{
    return SDL_JoystickInstanceID(m_joystick);
}

Key Joystick::getKeyFor(SDL_GameControllerButton button) const
{
    if (m_gameController == nullptr)
        return Key();

    SDL_GameControllerButtonBind bindedKey =
        SDL_GameControllerGetBindForButton(m_gameController, button);

    if (bindedKey.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON)
        return JoyButtonKey(static_cast<Uint8>(bindedKey.value.button));
    else if (bindedKey.bindType == SDL_CONTROLLER_BINDTYPE_HAT)
    {
        JoyHatMove hatMove;
        if (JoyHatKey::hatMoveFromSDLCode(
                static_cast<Uint8>(bindedKey.value.hat.hat_mask),
                hatMove))
            return JoyHatKey(static_cast<Uint8>(bindedKey.value.hat.hat),
                             hatMove);
    }

    return Key();
}
