/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "IconProvider.h"

#include <QDebug>
#include <QImageReader>
#include <QPainter>

#include "MvQMethods.h"
#include "MvQTheme.h"

static UnknownIconItem unknownIcon(":/desktop/unknown.svg");
static IconItem linkIcon(":/desktop/link.svg");
static IconItem linkBrokenIcon(":/desktop/link_broken.svg");
static IconItem lockIcon(":/desktop/padlock.svg");
static IconItem bookmarkGroupIcon(":/desktop/bookmark_group.svg");
static IconItem embeddedIcon(":/desktop/embedded.svg");

std::map<QString, IconItem*> IconProvider::icons_;
std::map<int, IconItem*> IconProvider::iconsById_;

//"complex" Qt objects such as QPixmap cannot be ststicly initialised! So we
// need to use a pointer.
static QPixmap* failedPix = nullptr;

static int idCnt = 0;

//===========================================
//
// IconItem
//
//===========================================

IconItem::IconItem(QString path) :
    path_(path),
    id_(idCnt++)
{
}

QPixmap IconItem::pixmap(int size)
{
    auto it = pixmaps_.find(size);
    if (it != pixmaps_.end())
        return it->second;
    else {
        QPixmap pix;
        QImageReader imgR(path_);
        if (imgR.canRead()) {
            imgR.setScaledSize(QSize(size, size));
            QImage img = imgR.read();
            pix = QPixmap::fromImage(img);
        }
        else {
            pix = unknown(size);
        }

        pixmaps_[size] = pix;
        return pix;
    }
    return {};
}

QPixmap IconItem::unknown(int size)
{
    return unknownIcon.pixmap(size);
}

UnknownIconItem::UnknownIconItem(QString path) :
    IconItem(path)
{
}

QPixmap UnknownIconItem::unknown(int /*size*/)
{
    return {};
}

//===========================================
//
// IconProvider
//
//===========================================

IconProvider::IconProvider() = default;

QString IconProvider::path(int id)
{
    auto it = iconsById_.find(id);
    if (it != iconsById_.end())
        return it->second->path();

    return {};
}

int IconProvider::add(QString path, QString name)
{
    auto it = icons_.find(name);
    if (it == icons_.end()) {
        auto* p = new IconItem(path);
        icons_[name] = p;
        iconsById_[p->id()] = p;
        return p->id();
    }

    return it->second->id();
}

IconItem* IconProvider::icon(QString name)
{
    auto it = icons_.find(name);
    if (it != icons_.end())
        return it->second;

    return &unknownIcon;
}

IconItem* IconProvider::icon(int id)
{
    auto it = iconsById_.find(id);
    if (it != iconsById_.end())
        return it->second;

    return &unknownIcon;
}

QPixmap IconProvider::pixmap(QString name, int size)
{
    return icon(name)->pixmap(size);
}

QPixmap IconProvider::pixmap(int id, int size)
{
    return icon(id)->pixmap(size);
}

QPixmap IconProvider::lockPixmap(int size)
{
    return lockIcon.pixmap(size);
}

QPixmap IconProvider::failedPixmap()
{
    if (!failedPix) {
        QString txt = "FAILED";
        QFont f;
        f.setPointSize(f.pointSize() - 2);
        f.setBold(true);
        QFontMetrics fm(f);
        int w = MvQ::textWidth(fm, txt);
        int h = fm.height();
        failedPix = new QPixmap(w + 4, h);
        failedPix->fill(Qt::transparent);
        QPainter p(failedPix);
        p.setRenderHint(QPainter::Antialiasing, true);
        p.setFont(f);
        p.setPen(MvQTheme::colour("failed_label", "border"));
        QRect bRect(0, 0, failedPix->width(), failedPix->height());
        p.setBrush(MvQTheme::colour("failed_label", "bg"));
        p.drawRoundedRect(bRect, 4, 4);
        p.setPen(MvQTheme::colour("failed_label", "text"));
        p.drawText(bRect, Qt::AlignCenter, txt);
    }
    return *failedPix;
}

static IconProvider iconProvider;
