#include "ItemIconCache.h"

#include <QFile>
#include <QPainter>
#include <QSvgRenderer>

ItemIconCache::ItemIconCache(const QString& iconDir)
    : m_iconDir(iconDir)
{
}

const QByteArray& ItemIconCache::getSvg(const std::string& itemId)
{
    const std::map<std::string, QByteArray>::const_iterator cached =
        m_svgById.find(itemId);
    if (cached != m_svgById.end())
    {
        return cached->second;
    }

    // An absent or unreadable file caches an empty byte array so it is not retried;
    // a missing icon is not an error (REQ-UI-ITEM-ICON).
    QByteArray svg;
    QFile file(m_iconDir + "/" + QString::fromStdString(itemId) + ".svg");
    if (file.open(QIODevice::ReadOnly))
    {
        svg = file.readAll();
    }
    return m_svgById.emplace(itemId, std::move(svg)).first->second;
}

bool ItemIconCache::hasIcon(const std::string& itemId)
{
    return !getSvg(itemId).isEmpty();
}

QPixmap ItemIconCache::getPixmap(const std::string& itemId, int sizePx)
{
    if (sizePx <= 0)
    {
        return QPixmap();
    }

    const std::pair<std::string, int> key(itemId, sizePx);
    const std::map<std::pair<std::string, int>, QPixmap>::const_iterator cached =
        m_pixmapCache.find(key);
    if (cached != m_pixmapCache.end())
    {
        return cached->second;
    }

    const QByteArray& svg = getSvg(itemId);
    QPixmap pixmap;
    if (!svg.isEmpty())
    {
        QSvgRenderer renderer(svg);
        pixmap = QPixmap(sizePx, sizePx);
        pixmap.fill(Qt::transparent);
        QPainter painter(&pixmap);
        painter.setRenderHint(QPainter::Antialiasing, true);
        renderer.render(&painter);
    }
    return m_pixmapCache.emplace(key, std::move(pixmap)).first->second;
}
