#include "game.h"

Game::Game()
{
    // Place the player with 10 initial charges onto x: 1, y: 1
    hero = std::make_unique<Hero>(1, 1, 2);

    // Generate level
    level = std::make_unique<Level>();

    audio = std::make_unique<Audio>("background_music.ogg", std::array<std::string, N_SOUNDS> { "footstep_sound.wav" });

    // Prepare level renderer
    renderer = std::make_unique<Renderer>();

    main_window.create(sf::VideoMode(renderer->windowSize() * 3, renderer->windowSize() * 2), "SFML-Test Application", sf::Style::Default);
    main_window.setActive();
    main_window.setFramerateLimit(60);

    current_level = 1;

    audio->setBackgroundVolume(15.f);
}

int Game::run()
{
    audio->playBackground();
    // On the game loop
    while (main_window.isOpen())
    {
        sf::Event event;
        while (main_window.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                main_window.close();
                break;

            case sf::Event::KeyPressed:
                audio->playSound(FOOTSTEP_SOUND);
                onMoving(event.key.code);
                break;

            default:
                break;
            }
        }

        renderer->render(level, hero, main_window);
        main_window.display();
    }

    audio->stopBackground();

    return EXIT_SUCCESS;
}

////////////////////////////////////////////////////
Direction Game::getDirection(sf::Keyboard::Key &key) const
{
    switch (key)
    {
    case sf::Keyboard::A:
    case sf::Keyboard::Left:
    case sf::Keyboard::Num4:
        return Direction::Left;

    case sf::Keyboard::W:
    case sf::Keyboard::Up:
    case sf::Keyboard::Num8:
        return Direction::Up;

    case sf::Keyboard::D:
    case sf::Keyboard::Right:
    case sf::Keyboard::Num6:
        return Direction::Right;

    case sf::Keyboard::S:
    case sf::Keyboard::Down:
    case sf::Keyboard::Num2:
        return Direction::Down;

    default:
        return Direction::None;
    }
}

void Game::onMoving(sf::Keyboard::Key &key)
{
    // Determine where to move
    const Direction direction = getDirection(key);

    if (direction == Direction::None)
        return;

    // Save the initial coordinates
    coordinate initial_row, initial_col;
    hero->position(initial_row, initial_col);

    // Try to move hero
    hero->move(direction);

    // Save the new coordinates after moving
    coordinate attempt_row, attempt_col;
    hero->position(attempt_row, attempt_col);

    //////////////////////////

    if (!level->getCellAt(attempt_row, attempt_col)->onMovingTo(hero, level))
        hero->setPosition(initial_row, initial_col);
}
