#include "classicgame.h"
#include "classicnote.h"
#include "classicmapcreator.h"
#include "holdmanager.h"

ClassicGame::ClassicGame(std::shared_ptr<ClassicGraphicsManager>&& manager) :
    _graphics_manager(std::move(manager)),
    _hold_manager(std::make_unique<HoldManager>(_graphics_manager))
{
    _slap_buffer.loadFromFile("Tick.ogg");
    _slap.setBuffer(_slap_buffer);
    _slap.setVolume(50);

    _keys_to_buttons =
    {
        {sf::Keyboard::Up, Type::UP},      // Load from settings
        {sf::Keyboard::Right, Type::RIGHT},
        {sf::Keyboard::Down, Type::DOWN},
        {sf::Keyboard::Left, Type::LEFT},

        {sf::Keyboard::W, Type::UP},
        {sf::Keyboard::D, Type::RIGHT},
        {sf::Keyboard::S, Type::DOWN},
        {sf::Keyboard::A, Type::LEFT},

        {sf::Keyboard::E, Type::SLIDER_RIGHT},
        {sf::Keyboard::Q, Type::SLIDER_LEFT}
    };

    _buttons_to_pressed_actions=
    {
        {Type::UP, Action::PRESS_UP},
        {Type::RIGHT, Action::PRESS_RIGHT},
        {Type::DOWN, Action::PRESS_DOWN},
        {Type::LEFT, Action::PRESS_LEFT},

        {Type::SLIDER_RIGHT, Action::PRESS_SLIDER_RIGHT},
        {Type::SLIDER_LEFT, Action::PRESS_SLIDER_LEFT}
    };

    _buttons_to_released_actions=
    {
        {Type::UP, Action::RELEASE_UP},
        {Type::RIGHT, Action::RELEASE_RIGHT},
        {Type::DOWN, Action::RELEASE_DOWN},
        {Type::LEFT, Action::RELEASE_LEFT},

        {Type::SLIDER_RIGHT, Action::RELEASE_SLIDER_RIGHT},
        {Type::SLIDER_LEFT, Action::RELEASE_SLIDER_LEFT}
    };
}

ClassicGame::~ClassicGame()
{}

void ClassicGame::run()
{
    _context.hold_manager = _hold_manager;
    _context.graphics_manager = _graphics_manager;

    auto beatmap = classic::createBeatmap("aa", _context);
    _music.openFromFile("METEOR.flac");
    _music.setVolume(10);
    _music.play();
    _timeline.setNotes(beatmap.notes, beatmap.visibility_offset);
}

void ClassicGame::input(PlayerInput&& inputdata)
{
    inputdata.timestamp = _music.fetchOffset();

    switch (inputdata.event.type)
    {
    default:
        return;
        break;

    case sf::Event::KeyPressed:
    {
        if (inputdata.event.key.code == sf::Keyboard::Space)
        {
            if (_music.isPaused())
            {
                _music.play();
                return;
            }
            else
            {
                _music.pause();
                return;
            }
        }

        auto note_it = _timeline.getActiveNote();

        if (!_timeline.isExpired(note_it))
        {
            auto note = (*note_it);
            note->input(std::move(inputdata));
            _slap.play();
        }
    }
    break;

    case sf::Event::KeyReleased:
    {
        _hold_manager->checkRelease(inputdata.event.key.code);
    }
    break;

    }
}

void ClassicGame::update()
{
    _timeline.update(_music.fetchOffset());
    _timeline.fetchVisibleNotes();
}

void ClassicGame::draw() const
{
    _timeline.drawVisibleNotes();
}