/*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 "Human.hpp"

Human::Human() : Player(), m_moveLeftDown(false), m_moveRightDown(false), m_crouchedDown(false)
{
    
}

Human::Human(const std::string &name, float health, float strength, float speed, float jumpEnergy, float walkPeriod) :
Player(name, health, strength, speed, jumpEnergy, walkPeriod), m_moveLeftDown(false), m_moveRightDown(false), m_crouchedDown(false)
{
    
}

void Human::act()
{
    //Update moves
    if (m_moves.getAction() == ACTION_DEFAULT && !isKo() && !isHit())
    {
        if (m_moveLeftDown)
        {
            if (m_moves.getState() != STATE_MOVING)
                m_moves.setState(STATE_MOVING);
            
            m_moves.setXFlip(true);
        }
        else if (m_moveRightDown)
        {
            if (m_moves.getState() != STATE_MOVING)
                m_moves.setState(STATE_MOVING);
            
            m_moves.setXFlip(false);
        }
        else if (m_crouchedDown)
        {
            if (m_moves.getState() != STATE_CROUCHED)
                crouch();
        }
        else if (m_moves.getState() == STATE_MOVING || m_moves.getState() == STATE_CROUCHED)
            m_moves.setState(STATE_DEFAULT); //Go back to default state
    }
}

void Human::keyEvent(const SDL_Event &event)
{
    //Key state on event
    if (!isKo() && !isHit())
    {
        if (m_inputMonitor.wasPressed(event, m_keys.getPunchKey(), m_deviceID)) punch(); //Other actions
        else if (m_inputMonitor.wasPressed(event, m_keys.getKickKey(), m_deviceID)) kick();
        else if (m_inputMonitor.wasPressed(event, m_keys.getThrowWeaponKey(), m_deviceID)) throwShuriken();
        else if (m_inputMonitor.wasPressed(event, m_keys.getJumpKey(), m_deviceID)) jump();
    }
}

void Human::updateKeyState(const SDL_Event &event)
{
    if (m_inputMonitor.wasPressed(event, m_keys.getMoveLeftKey(), m_deviceID))
        m_moveLeftDown = true;
    else if (m_inputMonitor.wasReleased(event, m_keys.getMoveLeftKey(), m_deviceID))
        m_moveLeftDown = false;
    
    if (m_inputMonitor.wasPressed(event, m_keys.getMoveRightKey(), m_deviceID))
        m_moveRightDown = true;
    else if (m_inputMonitor.wasReleased(event, m_keys.getMoveRightKey(), m_deviceID))
        m_moveRightDown = false;
    
    if (m_inputMonitor.wasPressed(event, m_keys.getCrouchKey(), m_deviceID))
        m_crouchedDown = true;
    else if (m_inputMonitor.wasReleased(event, m_keys.getCrouchKey(), m_deviceID))
        m_crouchedDown = false;
    
    m_inputMonitor.update(event, m_deviceID);
}

void Human::setDeviceID(int id)
{
    m_deviceID = id;
}

int Human::getDeviceID() const
{
    return m_deviceID;
}

void Human::setKeys(const PlayerKeys &keys)
{
    m_keys = keys;
}

const PlayerKeys &Human::getKeys() const
{
    return m_keys;
}

//Static methods
Human Human::loadFromXML(const std::string &name, const std::string &xmlRelPath)
{
    //TinyXML initialization
    std::string xmlPath = BuildValues::data(xmlRelPath); //Locate absolute path to xml data
    
    TiXmlDocument xmlFile;
    if (!xmlFile.LoadFile(xmlPath.c_str()))
        return Human();
    
    TiXmlHandle hdl(&xmlFile);
    TiXmlElement *xmlElement = hdl.FirstChildElement().FirstChildElement().Element();
    
    int i = 0;
    while (xmlElement)
    {
        std::string itemName = xmlElement->Attribute("name");
        if (itemName == name)
        {
            //Get informations
            float strenght = 10, speed = 700, jumpEnergy = 750, walkPeriod = .20;
            
            xmlElement->QueryFloatAttribute("strenght", &strenght);
            xmlElement->QueryFloatAttribute("speed", &speed);
            xmlElement->QueryFloatAttribute("jumpEnergy", &jumpEnergy);
            xmlElement->QueryFloatAttribute("walkPeriod", &walkPeriod);
            
            //Create player
            return Human(name, 100, strenght, speed, jumpEnergy, walkPeriod);
        }
        
        xmlElement = xmlElement->NextSiblingElement();
        i++;
    }
    
    return Human();
}
