#include "window.h"

Window::Window(const std::shared_ptr<kku::CoreFactory>& factory, const std::string& title) :
    _core_factory(factory),
    _is_dragging(false)
{
    _bar_title = _core_factory->getText(kku::Font::Id::GUI);
    _bar_title->setString(title);
    _bar_title->setCharacterSize(12);
    _bar_title->setColor(kku::Color{188, 157, 207, 255});

    _bar = _core_factory->getRectangle();
    _bar->setColor(kku::Color{88, 57, 107, 255});

    _window_content = _core_factory->getRectangle();
    _window_content->setColor(kku::Color{188, 157, 207, 255});
}

void Window::input(const kku::SystemEvent& event)
{
    Widget::input(event);

    switch (event.type)
    {
    default:
        break;

    case kku::SystemEvent::Type::MousePress:
    {
        const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
        if (_bar->contains(position))
        {
            _is_dragging = true;
            _previous_click_position = position;
        }
        break;
    }

    case kku::SystemEvent::Type::MouseRelease:
        _is_dragging = false;
        break;

    case kku::SystemEvent::Type::MouseMove:
    {
        const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
        if (_is_dragging)
        {
            float x_mouse_diff = position.x - _previous_click_position.x;
            float y_mouse_diff = position.y - _previous_click_position.y;

            _previous_click_position = position;

            move(kku::Vector2<float>{x_mouse_diff, y_mouse_diff});
        }
        break;
    }
    }
}

void Window::update(const kku::microsec& dt)
{
    Widget::update(dt);
}

void Window::display() const
{
    if (_is_visible)
    {
        _window_content->display();
        _bar->display();
        _bar_title->display();
        Widget::display();
    }
}

void Window::setRect(const kku::Area<float>& rect)
{
    _window_content->setRect(rect);

    kku::Area<float> bar_rect = {rect.left, rect.top, rect.width, 30};
    _bar->setRect(bar_rect);
    
    _bar_title->setPosition(kku::Point{rect.left + 5,
                                      rect.top  + 5});
}

void Window::setPosition(const kku::Point& position)
{
    _window_content->setPosition(position);
    _bar->setPosition(position);

    auto new_position = position;
    new_position.moveBy(5.f, 5.f);
    _bar_title->setPosition(new_position);
}

void Window::move(const kku::Vector2<float>& delta)
{
    _window_content->move(delta);
    _bar->move(delta);
    _bar_title->move(delta);

    Widget::move(delta);
}

bool Window::isUnderMouse(const kku::Point& position) const
{
    return _is_visible && _window_content->contains(position);
}

void Window::addBarButton(const std::string &text, kku::lambda callback)
{
    const auto area = _window_content->getRect();

    auto b = std::make_shared<PushButton>(text, _core_factory, 20);
    b->setCallback(callback);
    b->setRect({area.left + area.width - 35,
                area.top, 30, 30});

    Widget::addChild(b);
}

kku::Area<float> Window::getRect() const
{
    return _window_content->getRect();
}

kku::Point Window::getPosition() const
{
    return _window_content->getPosition();
}
