#include <Widget/Widget.hpp>
#include <Widget/Layout/PopupContainer/PopupContainer.hpp>

std::vector<Widget*> Widget::cleanupQueue;

Widget* Widget::popup = nullptr;
Widget* Widget::focused = nullptr;
Widget* Widget::popupHost = nullptr;
Widget* Widget::dragged = nullptr;
bool Widget::isRequestingMousePosUpdate = false;
Material* Widget::currentCursor = nullptr;
glm::ivec2 Widget::currentHotPoint;

void Widget::doPostUpdateCleanup()
{
    for (Widget *widget : cleanupQueue)
    {
        delete widget;
    }

    cleanupQueue.clear();
}

Widget::Widget() : m_size(0, 0), m_mousePos(-1, -1) {}

Widget::~Widget()
{
    if (focused == this)
    {
        focused = nullptr;
    }

    if (popupHost == this)
    {
        closePopup();
    }

    if (dragged == this)
    {
        dragged = nullptr;
    }
}

void Widget::closePopup()
{
    if (popup != nullptr)
    {
        cleanupQueue.push_back(popup);
    }

    popup = nullptr;

    if (popupHost != nullptr)
    {
        popupHost->onPopupClosed();
        popupHost = nullptr;
    }
}

void Widget::setCursor(Material &cursor, glm::ivec2 hotPoint)
{
    Widget::currentCursor = &cursor;
    Widget::currentHotPoint = hotPoint;
}

bool Widget::isMouseInside()
{
    return m_mousePos[0] >= 0 && m_mousePos[1] >= 0 && m_mousePos[0] < m_size[0] && m_mousePos[1] < m_size[1];
}

void Widget::focus()
{
    focused = this;
}

bool Widget::isFocused()
{
    return focused == this;
}

void Widget::openPopup(glm::ivec2 relPos, Widget *content)
{
    closePopup();
    popupHost = this;
    popup = new PopupContainer(widgetAbsPos + relPos, content);
}

bool Widget::isHostingPopup()
{
    return popupHost == this;
}

void Widget::onResize(glm::ivec2 newSize)
{
    m_size = newSize;
}

void Widget::onMouseMoved(glm::ivec2 pos)
{
    m_mousePos = pos;
}

void Widget::onMouseUp(Uint8 button)
{
    if (dragged == this)
    {
        dragged = nullptr;
    }
}

void Widget::onMouseDown(Uint8 button)
{
    if (isMouseInside())
    {
        focus();

        if (button == SDL_BUTTON_LEFT)
        {
            dragged = this;
        }
    }
}

void Widget::onKeyDown(SDL_Keycode keycode)
{
    // NOP
}

void Widget::onKeyUp(SDL_Keycode keycode)
{
    // NOP
}

void Widget::onScroll(int delta)
{
    // NOP
}

bool Widget::isTextInput()
{
    return false;
}

void Widget::onTextInput(std::string text)
{
    // NOP
}

void Widget::onPopupClosed()
{
    // NOP
}

glm::ivec2 Widget::getCurrentSize()
{
    return m_size;
}

void Widget::getInternalTabOrder(std::vector<Widget*> &tabOrder)
{
    // NOP
}