#include "menubar.h"

MenuBar::MenuBar(const std::shared_ptr<kku::CoreFactory>& factory) :
    _core_factory(factory),
    _bar_rect(factory->getRectangle()),
    _amount_buttons(0),
    _button_width(170)
{
    _bar_rect->setColor(kku::Color{88, 57, 107, 255});
}

void MenuBar::input(const kku::SystemEvent &event)
{
    switch (event.type)
    {
    default:
        break;

    case kku::SystemEvent::Type::MouseRelease:
    {
        const auto position = std::get<kku::SystemEvent::Mouse>(event.data).position;
        if (!isUnderMouse(position))
        {
            for (auto& submenu : _submenus)
                submenu->unlock();
        }
        break;
    }
    }

    Widget::input(event);
}

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

void MenuBar::display() const
{
    if (_is_visible)
        _bar_rect->display();

    Widget::display();
}

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

    // Buttons will not resize
}

void MenuBar::setPosition(const kku::Point& position)
{
    _bar_rect->setPosition(position);
}

void MenuBar::move(const kku::Vector2<float>& delta)
{
    _bar_rect->move(delta);

    Widget::move(delta);

    for (auto& menu : _submenus)
        menu->move(delta);
}

bool MenuBar::isUnderMouse(const kku::Point& position) const
{
    bool bar_under_mouse = _bar_rect->contains(position);

    bool submenus_under_mouse = std::any_of(_children.begin(), _children.end(),
                                            [p=position](const auto& child)
                                            {
                                                return child->isUnderMouse(p);
                                            });

    return bar_under_mouse || submenus_under_mouse;
}

void MenuBar::addRootSubMenu(std::string name, const std::shared_ptr<MenuDrop>& submenu)
{
    const auto new_button = std::make_shared<PushButton>(name, _core_factory);

    std::size_t current_index = _amount_buttons;
    new_button->setRect(kku::Area<float>{static_cast<float>(current_index * _button_width),
                                         0.f,
                                         static_cast<float>(_button_width),
                                         _bar_rect->getRect().height});
    new_button->setCallback([submenu=submenu]()
                            {
                                submenu->setVisibility(true);
                                submenu->lock();
                            });

    submenu->setPosition(kku::Point{static_cast<float>(current_index * _button_width),
                                    _bar_rect->getRect().height});

    new_button->setColors(kku::Color{171, 141, 189, 255},
                          kku::Color{48, 27, 57, 255});
    addChild(new_button);
    addChild(submenu);

    _submenus.emplace_back(submenu);

    ++_amount_buttons;
}

void MenuBar::addDependentSubmenu(const std::shared_ptr<MenuDrop> &submenu)
{
    _submenus.emplace_back(submenu);
}

void MenuBar::setVisibility(bool is_visible)
{
    Widget::setVisibility(is_visible);

    for (auto& submenu : _submenus)
        submenu->setVisibility(false);
}

kku::Area<float> MenuBar::getRect() const
{
    return _bar_rect->getRect();
}

kku::Point MenuBar::getPosition() const
{
    return _bar_rect->getPosition();
}
