/*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 "Platform.hpp"
#include "Engines/Physics/PhysicsWorld.hpp"
#include "Engines/Sound/SoundInterface.hpp"

#include "Engines/Sound/SoundEffectsList.hpp"

Platform::Platform() : PhysicsObject(),
m_soundInterface(nullptr), m_hitable(false)
{

}

void Platform::setSourceBox(const Box &sourceBox)
{
    m_sourceBox = sourceBox;
}

const Box &Platform::getSourceBox() const
{
    return m_sourceBox;
}

void Platform::setDrawSize(const Vector &drawSize)
{
    m_drawSize = drawSize;
}

const Vector &Platform::getDrawSize() const
{
    return m_drawSize;
}

void Platform::setBodyBox(const Box &bodyBox)
{
    m_bodyBox = bodyBox;
}

const Box &Platform::getBodyBox() const
{
    return m_bodyBox;
}

void Platform::setSpawnPosition(const Vector &spawnPosition)
{
    m_spawnPosition = spawnPosition;
}

const Vector &Platform::getSpawnPosition() const
{
    return m_spawnPosition;
}

void Platform::setHitable(bool hitable)
{
    m_hitable = hitable;
}

void Platform::setSoundInterface(SoundInterface *soundInterface)
{
    m_soundInterface = soundInterface;
}

void Platform::collideWorld(bool /*ground*/)
{
    //Nothing to do :)
}

void Platform::collide(PhysicsObject& /*obj*/)
{
    //Nothing to do :)
}

void Platform::takeAHit(float strength, HitDirection side,
                        const Player */*source*/)
{
    if (m_hitable)
    {
        //Play impact sound
        if (m_soundInterface != nullptr)
        {
            std::string material = getMaterial();
            if (material != MATERIAL_NONE)
                m_soundInterface->playSoundEffect("impact_" + material,
                                                  CHARACTER_AGNOSTIC);
        }

        //Pulse
        float pulse = 40.f * strength;
        if (side == HitDirection::FromRight) pulse *= -1.f;

        if (m_physicsWorld != nullptr)
            m_physicsWorld->pulseObject((*this), pulse, 0.f);
    }
}

void Platform::pushDamage(float strength, HitDirection side,
                          const Player &source, DamageTracker &/*damage*/)
{
    //Apply the damage immediately (platforms cannot fight back so the
    //tracker would not allow simultaneous hits in that case)
    takeAHit(strength, side, &source);
}

bool Platform::interceptsShadows() const
{
    //Platforms should intercept the shadow of objects over them
    return true;
}
