/*Copyright (C) 2010-2020 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 "JoyAxisKey.hpp"

///////////////
///JOYHATKEY///
///////////////
JoyAxisKey::JoyAxisKey() : AbstractJoystickKey()
{
    
}

JoyAxisKey::JoyAxisKey(const std::string &joystickName, int axisID, JoyAxisMove axisMove) :
AbstractJoystickKey(), m_joystickName(joystickName), m_axisID(axisID), m_axisMove(axisMove)
{
    
}

bool JoyAxisKey::keyPressed(const SDL_Event &event, int deviceID, const std::map<Uint8, AxisState> &previousAxisStates) const
{
    if (event.type == SDL_JOYAXISMOTION && deviceID == event.jaxis.which && m_axisID == event.jaxis.axis)
    {
        AxisState previousState = AXIS_STATE_CENTERED;
        
        std::map<Uint8, AxisState>::const_iterator it = previousAxisStates.find(m_axisID);
        if (it != previousAxisStates.end())
            previousState = it->second;
        
        AxisState newState = JoyAxisKey::axisStateFromSDLCode(event.jaxis.value);
        
        if (previousState == newState)
            return false;
        else
        {
            return ((newState == AXIS_STATE_NEGATIVE && m_axisMove == JOY_AXIS_NEGATIVE) ||
                    (newState == AXIS_STATE_POSITIVE && m_axisMove == JOY_AXIS_POSITIVE));
        }
    }
    
    return false;
}

bool JoyAxisKey::keyReleased(const SDL_Event &event, int deviceID, const std::map<Uint8, AxisState> &previousAxisStates) const
{
    if (event.type == SDL_JOYAXISMOTION && deviceID == event.jaxis.which && m_axisID == event.jaxis.axis)
    {
        AxisState previousState = AXIS_STATE_CENTERED;
        
        std::map<Uint8, AxisState>::const_iterator it = previousAxisStates.find(m_axisID);
        if (it != previousAxisStates.end())
            previousState = it->second;
        
        AxisState newState = JoyAxisKey::axisStateFromSDLCode(event.jaxis.value);
        
        return ((previousState == AXIS_STATE_NEGATIVE && m_axisMove == JOY_AXIS_NEGATIVE) ||
                    (previousState == AXIS_STATE_POSITIVE && m_axisMove == JOY_AXIS_POSITIVE)) &&
                    (newState != previousState);
    }
    
    return false;
}

std::string JoyAxisKey::getJoystickName() const
{
    return m_joystickName;
}

std::string JoyAxisKey::getName() const
{
    std::ostringstream code;
    code << "Axis " << m_axisID + 1;
    if (m_axisMove == JOY_AXIS_NEGATIVE) code << ": -";
    else code << ": +";
    
    return code.str();
}

std::string JoyAxisKey::getKeyCode() const
{
    std::ostringstream code;
    code << "ja" << m_axisID << axisMoveStringCode(m_axisMove);
    return code.str();
}

AxisState JoyAxisKey::axisStateFromSDLCode(Sint16 sdlValue)
{
    if (sdlValue >= AXIS_THRESHOLD_POS)
        return AXIS_STATE_POSITIVE;
    else if (sdlValue <= AXIS_THRESHOLD_NEG)
        return AXIS_STATE_NEGATIVE;
    
    return AXIS_STATE_CENTERED;
}

JoyAxisMove JoyAxisKey::axisMoveFromStringCode(const std::string &stringCode)
{
    if (stringCode == "n")
        return JOY_AXIS_NEGATIVE;
    
    return JOY_AXIS_POSITIVE;
}

std::string JoyAxisKey::axisMoveStringCode(const JoyAxisMove &code)
{
    if (code == JOY_AXIS_NEGATIVE)
        return "n";
    
    return "p";
}
