#include <ToolTip/ToolTip.hpp>
#include <Widget/ItemListSelector/ItemListSelector.hpp>
#include <ItemRegistry/ItemRegistry.hpp>
#include <ItemStack/ItemStack.hpp>
#include <BlockRegistry/BlockRegistry.hpp>
#include <Widget/Layout/CompoundWidget/ItemPicker/ItemPicker.hpp>

ItemListSelector::ItemListSelector(std::vector<ItemStack> &stacks, AddCallback onItemAdded, RemoveCallback onItemRemoved) :
    stacks(stacks),
    onItemAdded(onItemAdded),
    onItemRemoved(onItemRemoved)
{}

void ItemListSelector::drawAddButton(GraphicsContext &context, int x, int y)
{
    if (m_mousePos.x >= x && m_mousePos.x < (x + slotSize) && m_mousePos.y >= y && m_mousePos.y < (y + slotSize))
    {
        ToolTip &tip = context.createToolTip();
        tip.addLine(Color::positiveStat, "Add...");

        context.color = glm::vec4(1.0f);
    }
    else if (isHostingPopup())
    {
        context.color = glm::vec4(1.0f);
    }
    else
    {
        context.color = Color::faded;
    }

    context.drawRect(x + 1, y + 1, slotSize-2, slotSize-2);
    context.color = isHostingPopup() ? glm::vec4(1.0f) : Color::widgetBackground;
    context.drawRect(x + 2, y + 2, slotSize-4, slotSize-4);
    context.color = glm::vec4(1.0f);
    context.drawMaterial(Material::create, x + 3, y + 3);
}

void ItemListSelector::drawItem(GraphicsContext &context, int x, int y, ItemStack &stack)
{
    context.color = Color::faded;
    context.drawRect(x + 1, y + 1, slotSize-2, slotSize-2);
    context.color = Color::widgetBackground;
    context.drawRect(x + 2, y + 2, slotSize-4, slotSize-4);
    context.color = glm::vec4(1.0f);

    stack.getItem()->draw(context, x + 3, y + 3, stack);

    if (m_mousePos.x >= x && m_mousePos.x < (x + slotSize) && m_mousePos.y >= y && m_mousePos.y < (y + slotSize))
    {
        ToolTip &tip = context.createToolTip();
        tip.addLine(stack.getDisplayName());

        context.drawMaterial(Material::filterRemove, x + 1, y + 1);
    }
}

void ItemListSelector::openAddFilterPopup(glm::ivec2 pos)
{
    openPopup(pos, new ItemPicker(onItemAdded));
}

void ItemListSelector::draw(GraphicsContext &context)
{
    context.color = Color::widgetBackground;
    context.drawRect(0, 0, m_size.x, m_size.y);

    int nextCol = 0;
    int nextRow = 0;

    for (ItemStack &stack : stacks)
    {
        drawItem(context, nextCol * slotSize, nextRow * slotSize, stack);

        nextCol++;
        if (nextCol == numCols)
        {
            nextCol = 0;
            nextRow++;
        }
    }

    drawAddButton(context, nextCol * slotSize, nextRow * slotSize);
}

glm::ivec2 ItemListSelector::getMinSize()
{
    int numRows = std::max(minNumRows, static_cast<int>((stacks.size() + 1) / numCols));
    return glm::ivec2(numCols * slotSize, numRows * slotSize);
}

void ItemListSelector::onMouseUp(Uint8 button)
{
    if (button == SDL_BUTTON_LEFT && isMouseInside())
    {
        int col = m_mousePos.x / slotSize;
        int row = m_mousePos.y / slotSize;
        int index = row * numCols + col;

        if (index == (int) stacks.size())
        {
            openAddFilterPopup(glm::ivec2(col * slotSize + 1, row * slotSize + slotSize - 1));
            return;
        }

        if (index < 0 || index >= (int) stacks.size())
        {
            return;
        }

        stacks.erase(stacks.begin() + index);
        onItemRemoved(index);

        return;
    }

    Widget::onMouseUp(button);
}