/*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 "SoundEngine.hpp"
#include "Engines/Resources/SoundBufferManager.hpp"

SoundEngine::SoundEngine() :
m_generator(std::random_device{}()),
m_pitchDist(0.f, 1.f), m_volume(100.f), m_manager(nullptr)
{

}

void SoundEngine::playSound(const std::string &soundPath, float pitch,
                            float volumeFactor)
{
    SoundBuffer *buffer = nullptr;
    if (m_manager != nullptr && m_manager->getSoundBuffer(soundPath, buffer))
    {
        m_playingSounds.emplace_back();
        m_playingSounds.back().setBuffer((*buffer));
        m_playingSounds.back().setPitch(pitch);
        m_playingSounds.back().setVolume(m_volume * volumeFactor);
        m_playingSounds.back().play();
    }
}

void SoundEngine::playSoundEffect(const std::string &effect,
                                  const std::string &character,
                                  float volumeFactor)
{
    SoundData soundData;
    if (m_effects.getSoundData(effect, character, soundData))
    {
        const float pitch = 1.f - soundData.pitchVariation +
            m_pitchDist(m_generator) * soundData.pitchVariation * 2.f;
        playSound(soundData.path, pitch, volumeFactor);
    }
}

void SoundEngine::update()
{
    //Playing sounds
    std::list<Sound>::iterator it = m_playingSounds.begin();

    while (it != m_playingSounds.end())
    {
        if (!it->isPlaying())
            it = m_playingSounds.erase(it);
        else
            ++it;
    }
}

void SoundEngine::loadSoundEffects(const std::string &effectsPath)
{
    m_effects.load(effectsPath);
}

void SoundEngine::setManager(SoundBufferManager &manager)
{
    m_manager = &manager;
}

void SoundEngine::setVolume(float volume)
{
    if (volume >= 0.f && volume <= 100.f)
        m_volume = volume;
}
