#include "Qt_Event_Adapter.h"

namespace renderive {

Pointer_Event Qt_Event_Adapter::to_pointer_event(const QMouseEvent* qt_event, Event_Type type) {
    Pointer_Event event(type);
    event.position = to_pointf(qt_event->pos());
    event.global_position = to_pointf(qt_event->globalPos());
    event.button = to_mouse_button(qt_event->button());
    event.buttons = to_mouse_buttons(qt_event->buttons());
    event.modifiers = to_keyboard_modifiers(qt_event->modifiers());
    return event;
}

Wheel_Event Qt_Event_Adapter::to_wheel_event(const QWheelEvent* qt_event) {
    Wheel_Event event;
    event.position = to_pointf(qt_event->position());
    event.global_position = to_pointf(qt_event->globalPosition());
    event.button = Mouse_Button::None;
    event.buttons = to_mouse_buttons(qt_event->buttons());
    event.modifiers = to_keyboard_modifiers(qt_event->modifiers());
    event.pixel_delta_x = static_cast<double>(qt_event->pixelDelta().x());
    event.pixel_delta_y = static_cast<double>(qt_event->pixelDelta().y());
    event.angle_delta_x = static_cast<double>(qt_event->angleDelta().x());
    event.angle_delta_y = static_cast<double>(qt_event->angleDelta().y());
    return event;
}

Key_Event Qt_Event_Adapter::to_key_event(const QKeyEvent* qt_event, Event_Type type) {
    Key_Event event(type);
    event.key = to_key(qt_event->key());
    event.native_key = qt_event->nativeVirtualKey();
    event.modifiers = to_keyboard_modifiers(qt_event->modifiers());
    event.auto_repeat = qt_event->isAutoRepeat();
    return event;
}

Resize_Event Qt_Event_Adapter::to_resize_event(const QResizeEvent* qt_event) {
    Resize_Event event;
    event.old_size = to_size(qt_event->oldSize());
    event.new_size = to_size(qt_event->size());
    return event;
}

PointF Qt_Event_Adapter::to_pointf(const QPointF& p) {
    return {p.x(), p.y()};
}

Size Qt_Event_Adapter::to_size(const QSize& s) {
    return {s.width(), s.height()};
}

Mouse_Button Qt_Event_Adapter::to_mouse_button(Qt::MouseButton button) {
    switch (button) {
    case Qt::LeftButton:
        return Mouse_Button::Left;
    case Qt::RightButton:
        return Mouse_Button::Right;
    case Qt::MiddleButton:
        return Mouse_Button::Middle;
    default:
        return Mouse_Button::None;
    }
}

std::uint8_t Qt_Event_Adapter::to_mouse_buttons(Qt::MouseButtons buttons) {
    std::uint8_t result = 0;
    if (buttons & Qt::LeftButton)
        result |= 1;
    if (buttons & Qt::RightButton)
        result |= 2;
    if (buttons & Qt::MiddleButton)
        result |= 4;
    return result;
}

Keyboard_Modifier Qt_Event_Adapter::to_keyboard_modifiers(Qt::KeyboardModifiers modifiers) {
    auto result = static_cast<Keyboard_Modifier>(0);
    if (modifiers & Qt::ShiftModifier)
        result = result | Keyboard_Modifier::Shift;
    if (modifiers & Qt::ControlModifier)
        result = result | Keyboard_Modifier::Ctrl;
    if (modifiers & Qt::AltModifier)
        result = result | Keyboard_Modifier::Alt;
    if (modifiers & Qt::MetaModifier)
        result = result | Keyboard_Modifier::Meta;
    return result;
}

Key Qt_Event_Adapter::to_key(int qt_key) {
    switch (qt_key) {
    case Qt::Key_Escape:
        return Key::Escape;
    case Qt::Key_Return:
    case Qt::Key_Enter:
        return Key::Enter;
    case Qt::Key_Space:
        return Key::Space;
    case Qt::Key_Delete:
        return Key::Delete;
    case Qt::Key_Backspace:
        return Key::Backspace;
    case Qt::Key_Left:
        return Key::Left;
    case Qt::Key_Right:
        return Key::Right;
    case Qt::Key_Up:
        return Key::Up;
    case Qt::Key_Down:
        return Key::Down;
    default:
        return Key::Unknown;
    }
}

} // namespace renderive
