#include "ItemChipRow.h"

#include <QGridLayout>

#include "ItemChip.h"
#include "ItemIconCache.h"

namespace
{

// Size the item's colored square is drawn at inside a chip, in device-independent
// pixels. Larger than the artwork it carries, which the square insets (REQ-UI-ITEM-ICON).
const int kChipIconSizePx = 22;

// Chips per row. Two fit the panel's capped width side by side; a third would force the
// counts to shrink.
const int kChipsPerRow = 2;

}  // namespace


ItemChipRow::ItemChipRow(const SelectionContext& context, QWidget* parent)
    : QWidget(parent)
    , m_context(context)
{
    m_layout = new QGridLayout(this);
    m_layout->setContentsMargins(0, 0, 0, 0);
    m_layout->setSpacing(4);
}

void ItemChipRow::setEntries(const std::vector<Entry>& entries)
{
    std::vector<std::string> itemIds;
    itemIds.reserve(entries.size());
    for (const Entry& entry : entries)
    {
        itemIds.push_back(entry.itemId);
    }

    // Only the set of items changing is a structural change; the counts change every
    // tick and must not cost a widget rebuild.
    if (itemIds != m_itemIds)
    {
        m_itemIds = std::move(itemIds);
        rebuildChips(entries);
    }

    for (std::size_t index = 0; index < entries.size(); ++index)
    {
        m_chips[index]->setCount(entries[index].countText);
        m_chips[index]->setSubLine(entries[index].subLine);
    }
    setVisible(!entries.empty());
}

void ItemChipRow::rebuildChips(const std::vector<Entry>& entries)
{
    for (ItemChip* chip : m_chips)
    {
        m_layout->removeWidget(chip);
        chip->deleteLater();
    }
    m_chips.clear();

    for (std::size_t index = 0; index < entries.size(); ++index)
    {
        const std::string& itemId = entries[index].itemId;
        // The item's icon on its colored square (REQ-UI-ITEM-ICON). A missing icon file
        // is not an error: the chip then carries the square alone, and only an item with
        // no square either leaves the chip laid out around its count alone.
        const QPixmap icon =
            m_context.itemIcons->getSquarePixmap(itemId, kChipIconSizePx);

        ItemChip* chip = new ItemChip(m_context, itemId, icon, this);
        m_layout->addWidget(chip, static_cast<int>(index) / kChipsPerRow,
                            static_cast<int>(index) % kChipsPerRow);
        // Shown right away, because the panel measures itself as soon as this returns. A
        // widget created under an already-visible parent starts hidden, and a layout
        // treats a hidden item as empty, so an unshown chip would add nothing to the
        // size hint and the panel would be fitted to a buffer section that looks empty.
        chip->show();
        m_chips.push_back(chip);
    }
}
