/***************************** 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 <QImage>
#include <QImageReader>
#include <QPainter>

static UnknownIconItem unknownIcon(":/desktop/unknown.svg");
static IconItem linkIcon(":/desktop/link.svg");
static IconItem linkBrokenIcon(":/desktop/link_broken.svg");
static IconItem lockIcon(":/viewer/padlock.svg");
static IconItem warningIcon(":/viewer/warning.svg");
static IconItem errorIcon(":/viewer/error.svg");
static IconItem bookmarkGroupIcon(":/desktop/bookmark_group.svg");
static IconItem embeddedIcon(":/desktop/embedded.svg");
static IconItem infoIcon(":/viewer/info.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 = 0;

static int idCnt = 0;

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

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

QPixmap IconItem::pixmap(int size)
{
    std::map<int, QPixmap>::iterator 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();
}

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

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

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

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

IconProvider::IconProvider()
{
}

QString IconProvider::path(int id)
{
    std::map<int, IconItem*>::iterator it = iconsById_.find(id);
    if (it != iconsById_.end())
        return it->second->path();

    return QString();
}

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

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

IconItem* IconProvider::icon(QString name)
{
    std::map<QString, IconItem*>::iterator it = icons_.find(name);
    if (it != icons_.end())
        return it->second;

    return &unknownIcon;
}

IconItem* IconProvider::icon(int id)
{
    std::map<int, IconItem*>::iterator 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::warningPixmap(int size)
{
    return warningIcon.pixmap(size);
}

QPixmap IconProvider::errorPixmap(int size)
{
    return errorIcon.pixmap(size);
}

QPixmap IconProvider::infoPixmap(int size)
{
    return infoIcon.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     = fm.width(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(Qt::white);
        QRect bRect(0, 0, failedPix->width(), failedPix->height());
        p.setBrush(QColor(218, 38, 38));
        p.drawRoundedRect(bRect, 4, 4);
        p.drawText(bRect, Qt::AlignCenter, txt);
    }
    return *failedPix;
}

static IconProvider iconProvider;
