#include "musicsfml.h"

MusicSFML::MusicSFML() :
    _sfml_music_offset(0),
    _previous_frame_offset(0),
    _absolute_offset(0)
{}

bool MusicSFML::open(const std::string& filepath)
{
    return _music.openFromFile(filepath);
}

void MusicSFML::play()
{
    _music.play();
    _sfml_music_offset = _offset_interpolator.restart().asMicroseconds();
}

void MusicSFML::pause()
{
    _music.pause();
}

void MusicSFML::stop()
{
    _music.stop();
}

bool MusicSFML::isPlaying() const
{
    return _music.getStatus() == sf::Music::Playing;
}

void MusicSFML::setVolume(float volume)
{
    _music.setVolume(volume);
}

void MusicSFML::setOffset(const kku::microsec& offset)
{
    //_previous_frame_offset += (offset - _absolute_offset);
    _music.setPlayingOffset(sf::microseconds(offset));
}

kku::microsec MusicSFML::fetchOffset()
{
    if (_music.getStatus() != sf::Music::Status::Playing)
        return _absolute_offset;

    const auto interpolator_timestamp = _offset_interpolator.getElapsedTime().asMicroseconds();
    const auto sfml_new_offset = _music.getPlayingOffset().asMicroseconds();

    _absolute_offset += (interpolator_timestamp - _previous_frame_offset);
    _previous_frame_offset = interpolator_timestamp;
    if (sfml_new_offset != _sfml_music_offset)
    {
        _absolute_offset = ((_absolute_offset + sfml_new_offset) / 2);
        _sfml_music_offset = sfml_new_offset;
    }

    return _absolute_offset;
}

void MusicSFML::moveOffset(const kku::microsec& delta)
{
    const auto offset = fetchOffset();
    const auto result = offset + delta;

    if (result < 0)
    {
        setOffset(0);
    }
    else if (result > getDuration())
    {
        setOffset(_music.getDuration().asMicroseconds());
        pause();
    }
    else
    {
        setOffset(result);
    }
}

kku::microsec MusicSFML::getDuration() const
{
    return _music.getDuration().asMicroseconds();
}

