/**
 * @file Button.cpp
 * @author apio (cloudapio.eu)
 * @brief A clickable component that triggers an action when pressed.
 *
 * @copyright Copyright (c) 2023, the Luna authors.
 *
 */

#include <ui/Button.h>
#include <ui/Mouse.h>

namespace ui
{
    Button::Button(Rect rect)
    {
        m_rect = rect;
    }

    void Button::set_widget(Widget& widget)
    {
        widget.rect() = m_rect;
        m_child = &widget;
        widget.set_parent(this);
    }

    void Button::set_action(os::Action&& action)
    {
        m_action = move(action);
    }

    Result<EventResult> Button::handle_mouse_move(Point position)
    {
        m_hovered = true;
        return m_child->handle_mouse_move(position);
    }

    Result<EventResult> Button::handle_mouse_leave()
    {
        m_hovered = m_clicked = false;
        return m_child->handle_mouse_leave();
    }

    Result<EventResult> Button::handle_mouse_down(Point position, int buttons)
    {
        auto result = TRY(m_child->handle_mouse_down(position, buttons));
        if (result == EventResult::DidNotHandle)
        {
            if (!m_clicked && (buttons == ui::MouseButtons::LEFT))
            {
                m_clicked = true;
                m_action();
            }
        }
        return EventResult::DidHandle;
    }

    Result<EventResult> Button::handle_mouse_up(Point position, int buttons)
    {
        if (buttons & ui::MouseButtons::LEFT) m_clicked = false;
        return m_child->handle_mouse_up(position, buttons);
    }

    Result<EventResult> Button::handle_key_event(const ui::KeyEventRequest& request)
    {
        return m_child->handle_key_event(request);
    }

    Result<void> Button::draw(Canvas& canvas)
    {
        return m_child->draw(canvas);
    }
}