#include "RecipeSummaryRow.h"

#include <QHBoxLayout>
#include <QLabel>
#include <QLayoutItem>
#include <QPixmap>

#include "ItemIconCache.h"

namespace
{

// Size the item icons are drawn at on the summary line, in device-independent pixels.
const int kSummaryIconSizePx = 14;

// Adds a freshly built label to the summary and shows it.
//
// The show is what makes it count: a widget created under an already-visible parent
// starts hidden, and a layout treats a hidden item as empty, so an unshown label would
// add nothing to the size hint the panel measures itself against as soon as this
// returns.
void addAndShow(QHBoxLayout* layout, QLabel* label)
{
    layout->addWidget(label);
    label->show();
}

}  // namespace


RecipeSummaryRow::RecipeSummaryRow(ItemIconCache* itemIcons, QWidget* parent)
    : QWidget(parent)
    , m_itemIcons(itemIcons)
{
    m_layout = new QHBoxLayout(this);
    m_layout->setContentsMargins(0, 0, 0, 0);
    m_layout->setSpacing(4);

    hide();
}

void RecipeSummaryRow::setSummary(const std::vector<Amount>& inputs,
                                  const std::vector<Amount>& outputs,
                                  double durationSeconds)
{
    if (outputs.empty() && inputs.empty())
    {
        // Forgotten as well as hidden, so re-selecting the same recipe later is seen as
        // a change and shows the row again.
        m_inputs.clear();
        m_outputs.clear();
        m_durationSeconds = -1.0;
        hide();
        return;
    }
    if (inputs == m_inputs && outputs == m_outputs
        && durationSeconds == m_durationSeconds)
    {
        return;
    }

    m_inputs          = inputs;
    m_outputs         = outputs;
    m_durationSeconds = durationSeconds;
    rebuild(inputs, outputs, durationSeconds);
    show();
}

void RecipeSummaryRow::rebuild(const std::vector<Amount>& inputs,
                               const std::vector<Amount>& outputs,
                               double durationSeconds)
{
    while (QLayoutItem* item = m_layout->takeAt(0))
    {
        if (item->widget())
        {
            item->widget()->deleteLater();
        }
        delete item;
    }

    addAmounts(inputs);
    if (!inputs.empty())
    {
        const QChar rightArrow(0x2192);  // U+2192 RIGHTWARDS ARROW
        addAndShow(m_layout, new QLabel(QString(rightArrow), this));
    }
    addAmounts(outputs);

    if (durationSeconds > 0.0)
    {
        const QChar middleDot(0x00B7);  // U+00B7 MIDDLE DOT
        addAndShow(m_layout, new QLabel(
            QStringLiteral("%1 %2").arg(middleDot).arg(
                tr("%1 s").arg(durationSeconds, 0, 'f', 1)), this));
    }
    m_layout->addStretch(1);
}

void RecipeSummaryRow::addAmounts(const std::vector<Amount>& amounts)
{
    for (const Amount& entry : amounts)
    {
        // A missing icon file is not an error (REQ-UI-ITEM-ICON): the item's id then
        // stands in for its icon.
        if (m_itemIcons->hasIcon(entry.itemId))
        {
            QLabel* iconLabel = new QLabel(this);
            iconLabel->setPixmap(
                m_itemIcons->getPixmap(entry.itemId, kSummaryIconSizePx));
            addAndShow(m_layout, iconLabel);
        }
        else
        {
            addAndShow(m_layout,
                       new QLabel(QString::fromStdString(entry.itemId), this));
        }
        addAndShow(m_layout, new QLabel(QString::number(entry.amount), this));
    }
}
