#pragma once

#include "core/systemevent.h"
#include <SFML/Window/Event.hpp>

namespace kku
{

constexpr kku::SystemEvent::Key::Code convert(sf::Keyboard::Key key) noexcept
{
    return kku::SystemEvent::Key::Code{int(key)};
}

constexpr kku::SystemEvent convert(const sf::Event& event) noexcept
{
    switch (event.type)
    {
    default:
        break;

    case sf::Event::Resized:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::Resize,
            kku::SystemEvent::Size
            {
                event.size.width,
                event.size.height
            }
        };

    case sf::Event::KeyPressed:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::KeyPress,
            kku::SystemEvent::Key
            {
                kku::convert(event.key.code),
                event.key.alt,
                event.key.control,
                event.key.shift
            }
        };

    case sf::Event::KeyReleased:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::KeyRelease,
            kku::SystemEvent::Key
            {
                kku::convert(event.key.code),
                event.key.alt,
                event.key.control,
                event.key.shift
            }
        };

    case sf::Event::MouseWheelScrolled:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::MouseWheelScroll,
            kku::SystemEvent::Mouse
            {
                kku::Point
                {
                    event.mouseWheelScroll.x,
                    event.mouseWheelScroll.y
                },

                (event.mouseWheelScroll.delta > 0),
                kku::SystemEvent::Mouse::Button::Wheel
            }
        };

    case sf::Event::MouseMoved:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::MouseMove,
            kku::SystemEvent::Mouse
            {
                kku::Point
                {
                    event.mouseMove.x,
                    event.mouseMove.y
                },

                false,
                kku::SystemEvent::Mouse::Button::None
            }
        };

    case sf::Event::MouseButtonPressed:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::MousePress,
            kku::SystemEvent::Mouse
            {
                kku::Point
                {
                    event.mouseButton.x,
                    event.mouseButton.y
                },

                false,
                ((event.mouseButton.button == sf::Mouse::Button::Left)
                 ? kku::SystemEvent::Mouse::Button::Left
                 : kku::SystemEvent::Mouse::Button::Right)
            }
        };

    case sf::Event::MouseButtonReleased:
        return kku::SystemEvent
        {
            kku::SystemEvent::Type::MouseRelease,
            kku::SystemEvent::Mouse
            {
                kku::Point
                {
                    event.mouseButton.x,
                    event.mouseButton.y
                },

                false,
                ((event.mouseButton.button == sf::Mouse::Button::Left)
                 ? kku::SystemEvent::Mouse::Button::Left
                 : kku::SystemEvent::Mouse::Button::Right)
            }
        };
    }

    return kku::SystemEvent
    {
        kku::SystemEvent::Type::None,
        kku::SystemEvent::None{}
    };
}

}
