/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#define Q_TEST_QPIXMAPCACHE
#include "qpixmapcache.h"
#include "qobject.h"
#include "qdebug.h"
#include "qpixmapcache_p.h"
#include "qthread.h"
#include "qcoreapplication.h"

QT_BEGIN_NAMESPACE

/*!
    \class QPixmapCache
    \inmodule QtGui

    \brief The QPixmapCache class provides an application-wide cache for pixmaps.

    This class is a tool for optimized drawing with QPixmap. You can
    use it to store temporary pixmaps that are expensive to generate
    without using more storage space than cacheLimit(). Use insert()
    to insert pixmaps, find() to find them, and clear() to empty the
    cache.

    QPixmapCache contains no member data, only static functions to
    access the global pixmap cache. It creates an internal QCache
    object for caching the pixmaps.

    The cache associates a pixmap with a user-provided string as a key,
    or with a QPixmapCache::Key that the cache generates.
    Using QPixmapCache::Key for keys is faster than using strings. The string API is
    very convenient for complex keys but the QPixmapCache::Key API will be very
    efficient and convenient for a one-to-one object-to-pixmap mapping - in
    this case, you can store the keys as members of an object.

    If two pixmaps are inserted into the cache using equal keys then the
    last pixmap will replace the first pixmap in the cache. This follows the
    behavior of the QHash and QCache classes.

    The cache becomes full when the total size of all pixmaps in the
    cache exceeds cacheLimit(). The initial cache limit is 10240 KB (10 MB);
    you can change this by calling setCacheLimit() with the required value.
    A pixmap takes roughly (\e{width} * \e{height} * \e{depth})/8 bytes of
    memory.

    The \e{Qt Quarterly} article
    \l{http://doc.qt.io/archives/qq/qq12-qpixmapcache.html}{Optimizing
    with QPixmapCache} explains how to use QPixmapCache to speed up
    applications by caching the results of painting.

    \note QPixmapCache is only usable from the application's main thread.
    Access from other threads will be ignored and return failure.

    \sa QCache, QPixmap
*/

static const int cache_limit_default = 10240; // 10 MB cache limit

static inline int cost(const QPixmap &pixmap)
{
    // make sure to do a 64bit calculation
    const qint64 costKb = static_cast<qint64>(pixmap.width()) *
            pixmap.height() * pixmap.depth() / (8 * 1024);
    const qint64 costMax = std::numeric_limits<int>::max();
    // a small pixmap should have at least a cost of 1(kb)
    return static_cast<int>(qBound(1LL, costKb, costMax));
}

static inline bool qt_pixmapcache_thread_test()
{
    if (Q_LIKELY(QCoreApplication::instance() && QThread::currentThread() == QCoreApplication::instance()->thread()))
        return true;

    return false;
}

/*!
    \class QPixmapCache::Key
    \brief The QPixmapCache::Key class can be used for efficient access
    to the QPixmapCache.
    \inmodule QtGui
    \since 4.6

    Use QPixmapCache::insert() to receive an instance of Key generated
    by the pixmap cache. You can store the key in your own objects for
    a very efficient one-to-one object-to-pixmap mapping.
*/

/*!
    Constructs an empty Key object.
*/
QPixmapCache::Key::Key() : d(nullptr)
{
}

/*!
   \internal
    Constructs a copy of \a other.
*/
QPixmapCache::Key::Key(const Key &other)
{
    if (other.d)
        ++(other.d->ref);
    d = other.d;
}

/*!
    Destroys the key.
*/
QPixmapCache::Key::~Key()
{
    if (d && --(d->ref) == 0)
        delete d;
}

/*!
    \internal

    Returns \c true if this key is the same as the given \a key; otherwise returns
    false.
*/
bool QPixmapCache::Key::operator ==(const Key &key) const
{
    return (d == key.d);
}

/*!
    \fn bool QPixmapCache::Key::operator !=(const Key &key) const
    \internal
*/

/*!
    \fn QPixmapCache::Key::Key(Key &&)
    \internal
    \since 5.6
*/

/*!
    \fn QPixmapCache::Key &QPixmapCache::Key::operator=(Key &&)
    \internal
    \since 5.6
*/

/*!
    \fn void QPixmapCache::Key::swap(Key &)
    \internal
    \since 5.6
*/

/*!
    Returns \c true if there is a cached pixmap associated with this key.
    Otherwise, if pixmap was flushed, the key is no longer valid.
    \since 5.7
*/
bool QPixmapCache::Key::isValid() const noexcept
{
    return d && d->isValid;
}

/*!
    \internal
*/
QPixmapCache::Key &QPixmapCache::Key::operator =(const Key &other)
{
    if (d != other.d) {
        if (other.d)
            ++(other.d->ref);
        if (d && --(d->ref) == 0)
            delete d;
        d = other.d;
    }
    return *this;
}

class QPMCache : public QObject, public QCache<QPixmapCache::Key, QPixmapCacheEntry>
{
    Q_OBJECT
public:
    QPMCache();
    ~QPMCache();

    void timerEvent(QTimerEvent *) override;
    bool insert(const QString& key, const QPixmap &pixmap, int cost);
    QPixmapCache::Key insert(const QPixmap &pixmap, int cost);
    bool replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int cost);
    bool remove(const QString &key);
    bool remove(const QPixmapCache::Key &key);

    void resizeKeyArray(int size);
    QPixmapCache::Key createKey();
    void releaseKey(const QPixmapCache::Key &key);
    void clear();

    QPixmap *object(const QString &key) const;
    QPixmap *object(const QPixmapCache::Key &key) const;

    static inline QPixmapCache::KeyData *get(const QPixmapCache::Key &key)
    {return key.d;}

    static QPixmapCache::KeyData* getKeyData(QPixmapCache::Key *key);

    bool flushDetachedPixmaps(bool nt);

private:
    enum { soon_time = 10000, flush_time = 30000 };
    int *keyArray;
    int theid;
    int ps;
    int keyArraySize;
    int freeKey;
    QHash<QString, QPixmapCache::Key> cacheKeys;
    bool t;
};

QT_BEGIN_INCLUDE_NAMESPACE
#include "qpixmapcache.moc"
QT_END_INCLUDE_NAMESPACE

uint qHash(const QPixmapCache::Key &k)
{
    return qHash(QPMCache::get(k)->key);
}

QPMCache::QPMCache()
    : QObject(nullptr),
      QCache<QPixmapCache::Key, QPixmapCacheEntry>(cache_limit_default),
      keyArray(nullptr), theid(0), ps(0), keyArraySize(0), freeKey(0), t(false)
{
}
QPMCache::~QPMCache()
{
    clear();
    free(keyArray);
}

/*
  This is supposed to cut the cache size down by about 25% in a
  minute once the application becomes idle, to let any inserted pixmap
  remain in the cache for some time before it becomes a candidate for
  cleaning-up, and to not cut down the size of the cache while the
  cache is in active use.

  When the last detached pixmap has been deleted from the cache, kill the
  timer so Qt won't keep the CPU from going into sleep mode. Currently
  the timer is not restarted when the pixmap becomes unused, but it does
  restart once something else is added (i.e. the cache space is actually needed).

  Returns \c true if any were removed.
*/
bool QPMCache::flushDetachedPixmaps(bool nt)
{
    int mc = maxCost();
    setMaxCost(nt ? totalCost() * 3 / 4 : totalCost() -1);
    setMaxCost(mc);
    ps = totalCost();

    bool any = false;
    QHash<QString, QPixmapCache::Key>::iterator it = cacheKeys.begin();
    while (it != cacheKeys.end()) {
        if (!contains(it.value())) {
            releaseKey(it.value());
            it = cacheKeys.erase(it);
            any = true;
        } else {
            ++it;
        }
    }

    return any;
}

void QPMCache::timerEvent(QTimerEvent *)
{
    bool nt = totalCost() == ps;
    if (!flushDetachedPixmaps(nt)) {
        killTimer(theid);
        theid = 0;
    } else if (nt != t) {
        killTimer(theid);
        theid = startTimer(nt ? soon_time : flush_time);
        t = nt;
    }
}


QPixmap *QPMCache::object(const QString &key) const
{
    QPixmapCache::Key cacheKey = cacheKeys.value(key);
    if (!cacheKey.d || !cacheKey.d->isValid) {
        const_cast<QPMCache *>(this)->cacheKeys.remove(key);
        return nullptr;
    }
    QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(cacheKey);
     //We didn't find the pixmap in the cache, the key is not valid anymore
    if (!ptr) {
        const_cast<QPMCache *>(this)->cacheKeys.remove(key);
    }
    return ptr;
}

QPixmap *QPMCache::object(const QPixmapCache::Key &key) const
{
    Q_ASSERT(key.d->isValid);
    QPixmap *ptr = QCache<QPixmapCache::Key, QPixmapCacheEntry>::object(key);
    //We didn't find the pixmap in the cache, the key is not valid anymore
    if (!ptr)
        const_cast<QPMCache *>(this)->releaseKey(key);
    return ptr;
}

bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost)
{
    QPixmapCache::Key &cacheKey = cacheKeys[key];
    //If for the same key we add already a pixmap we should delete it
    if (cacheKey.d)
        QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(cacheKey);

    //we create a new key the old one has been removed
    cacheKey = createKey();

    bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost);
    if (success) {
        if (!theid) {
            theid = startTimer(flush_time);
            t = false;
        }
    } else {
        //Insertion failed we released the new allocated key
        cacheKeys.remove(key);
    }
    return success;
}

QPixmapCache::Key QPMCache::insert(const QPixmap &pixmap, int cost)
{
    QPixmapCache::Key cacheKey = createKey();
    bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost);
    if (success) {
        if (!theid) {
            theid = startTimer(flush_time);
            t = false;
        }
    }
    return cacheKey;
}

bool QPMCache::replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int cost)
{
    Q_ASSERT(key.d->isValid);
    //If for the same key we had already an entry so we should delete the pixmap and use the new one
    QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(key);

    QPixmapCache::Key cacheKey = createKey();

    bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost);
    if (success) {
        if(!theid) {
            theid = startTimer(flush_time);
            t = false;
        }
        const_cast<QPixmapCache::Key&>(key) = cacheKey;
    }
    return success;
}

bool QPMCache::remove(const QString &key)
{
    auto cacheKey = cacheKeys.constFind(key);
    //The key was not in the cache
    if (cacheKey == cacheKeys.constEnd())
        return false;
    const bool result = QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(cacheKey.value());
    cacheKeys.erase(cacheKey);
    return result;
}

bool QPMCache::remove(const QPixmapCache::Key &key)
{
    return QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(key);
}

void QPMCache::resizeKeyArray(int size)
{
    if (size <= keyArraySize || size == 0)
        return;
    keyArray = q_check_ptr(reinterpret_cast<int *>(realloc(keyArray,
                    size * sizeof(int))));
    for (int i = keyArraySize; i != size; ++i)
        keyArray[i] = i + 1;
    keyArraySize = size;
}

QPixmapCache::Key QPMCache::createKey()
{
    if (freeKey == keyArraySize)
        resizeKeyArray(keyArraySize ? keyArraySize << 1 : 2);
    int id = freeKey;
    freeKey = keyArray[id];
    QPixmapCache::Key key;
    QPixmapCache::KeyData *d = QPMCache::getKeyData(&key);
    d->key = ++id;
    return key;
}

void QPMCache::releaseKey(const QPixmapCache::Key &key)
{
    if (key.d->key > keyArraySize || key.d->key <= 0)
        return;
    key.d->key--;
    keyArray[key.d->key] = freeKey;
    freeKey = key.d->key;
    key.d->isValid = false;
    key.d->key = 0;
}

void QPMCache::clear()
{
    free(keyArray);
    keyArray = nullptr;
    freeKey = 0;
    keyArraySize = 0;
    //Mark all keys as invalid
    QList<QPixmapCache::Key> keys = QCache<QPixmapCache::Key, QPixmapCacheEntry>::keys();
    for (int i = 0; i < keys.size(); ++i)
        keys.at(i).d->isValid = false;
    QCache<QPixmapCache::Key, QPixmapCacheEntry>::clear();
}

QPixmapCache::KeyData* QPMCache::getKeyData(QPixmapCache::Key *key)
{
    if (!key->d)
        key->d = new QPixmapCache::KeyData;
    return key->d;
}

Q_GLOBAL_STATIC(QPMCache, pm_cache)

int Q_AUTOTEST_EXPORT q_QPixmapCache_keyHashSize()
{
    return pm_cache()->size();
}

QPixmapCacheEntry::~QPixmapCacheEntry()
{
    pm_cache()->releaseKey(key);
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete
    \overload

    Use bool find(const QString &, QPixmap *) instead.

    Returns the pixmap associated with the \a key in the cache, or
    null if there is no such pixmap.

    \warning If valid, you should copy the pixmap immediately (this is
    fast). Subsequent insertions into the cache could cause the
    pointer to become invalid. For this reason, we recommend you use
    bool find(const QString&, QPixmap*) instead.

    Example:
    \snippet code/src_gui_image_qpixmapcache.cpp 0
*/

QPixmap *QPixmapCache::find(const QString &key)
{
    if (!qt_pixmapcache_thread_test())
        return nullptr;
    return pm_cache()->object(key);
}


/*!
    \obsolete

    Use bool find(const QString &, QPixmap *) instead.
*/

bool QPixmapCache::find(const QString &key, QPixmap &pixmap)
{
    return find(key, &pixmap);
}
#endif

/*!
    Looks for a cached pixmap associated with the given \a key in the cache.
    If the pixmap is found, the function sets \a pixmap to that pixmap and
    returns \c true; otherwise it leaves \a pixmap alone and returns \c false.

    \since 4.6

    Example:
    \snippet code/src_gui_image_qpixmapcache.cpp 1
*/

bool QPixmapCache::find(const QString &key, QPixmap *pixmap)
{
    if (!qt_pixmapcache_thread_test())
        return false;
    QPixmap *ptr = pm_cache()->object(key);
    if (ptr && pixmap)
        *pixmap = *ptr;
    return ptr != nullptr;
}

/*!
    Looks for a cached pixmap associated with the given \a key in the cache.
    If the pixmap is found, the function sets \a pixmap to that pixmap and
    returns \c true; otherwise it leaves \a pixmap alone and returns \c false. If
    the pixmap is not found, it means that the \a key is no longer valid,
    so it will be released for the next insertion.

    \since 4.6
*/
bool QPixmapCache::find(const Key &key, QPixmap *pixmap)
{
    if (!qt_pixmapcache_thread_test())
        return false;
    //The key is not valid anymore, a flush happened before probably
    if (!key.d || !key.d->isValid)
        return false;
    QPixmap *ptr = pm_cache()->object(key);
    if (ptr && pixmap)
        *pixmap = *ptr;
    return ptr != nullptr;
}

/*!
    Inserts a copy of the pixmap \a pixmap associated with the \a key into
    the cache.

    All pixmaps inserted by the Qt library have a key starting with
    "$qt", so your own pixmap keys should never begin "$qt".

    When a pixmap is inserted and the cache is about to exceed its
    limit, it removes pixmaps until there is enough room for the
    pixmap to be inserted.

    The oldest pixmaps (least recently accessed in the cache) are
    deleted when more space is needed.

    The function returns \c true if the object was inserted into the
    cache; otherwise it returns \c false.

    \sa setCacheLimit()
*/

bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
{
    if (!qt_pixmapcache_thread_test())
        return false;
    return pm_cache()->insert(key, pixmap, cost(pixmap));
}

/*!
    Inserts a copy of the given \a pixmap into the cache and returns a key
    that can be used to retrieve it.

    When a pixmap is inserted and the cache is about to exceed its
    limit, it removes pixmaps until there is enough room for the
    pixmap to be inserted.

    The oldest pixmaps (least recently accessed in the cache) are
    deleted when more space is needed.

    \sa setCacheLimit(), replace()

    \since 4.6
*/
QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
{
    if (!qt_pixmapcache_thread_test())
        return QPixmapCache::Key();
    return pm_cache()->insert(pixmap, cost(pixmap));
}

/*!
    Replaces the pixmap associated with the given \a key with the \a pixmap
    specified. Returns \c true if the \a pixmap has been correctly inserted into
    the cache; otherwise returns \c false.

    \sa setCacheLimit(), insert()

    \since 4.6
*/
bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
{
    if (!qt_pixmapcache_thread_test())
        return false;
    //The key is not valid anymore, a flush happened before probably
    if (!key.d || !key.d->isValid)
        return false;
    return pm_cache()->replace(key, pixmap, cost(pixmap));
}

/*!
    Returns the cache limit (in kilobytes).

    The default cache limit is 10240 KB.

    \sa setCacheLimit()
*/

int QPixmapCache::cacheLimit()
{
    return pm_cache()->maxCost();
}

/*!
    Sets the cache limit to \a n kilobytes.

    The default setting is 10240 KB.

    \sa cacheLimit()
*/

void QPixmapCache::setCacheLimit(int n)
{
    if (!qt_pixmapcache_thread_test())
        return;
    pm_cache()->setMaxCost(n);
}

/*!
  Removes the pixmap associated with \a key from the cache.
*/
void QPixmapCache::remove(const QString &key)
{
    if (!qt_pixmapcache_thread_test())
        return;
    pm_cache()->remove(key);
}

/*!
  Removes the pixmap associated with \a key from the cache and releases
  the key for a future insertion.

  \since 4.6
*/
void QPixmapCache::remove(const Key &key)
{
    if (!qt_pixmapcache_thread_test())
        return;
    //The key is not valid anymore, a flush happened before probably
    if (!key.d || !key.d->isValid)
        return;
    pm_cache()->remove(key);
}

/*!
    Removes all pixmaps from the cache.
*/

void QPixmapCache::clear()
{
    if (!QCoreApplication::closingDown() && !qt_pixmapcache_thread_test())
        return;
    QT_TRY {
        if (pm_cache.exists())
            pm_cache->clear();
    } QT_CATCH(const std::bad_alloc &) {
        // if we ran out of memory during pm_cache(), it's no leak,
        // so just ignore it.
    }
}

void QPixmapCache::flushDetachedPixmaps()
{
    pm_cache()->flushDetachedPixmaps(true);
}

int QPixmapCache::totalUsed()
{
    return (pm_cache()->totalCost()+1023) / 1024;
}

/*!
   \fn QPixmapCache::KeyData::KeyData()

   \internal
*/
/*!
   \fn QPixmapCache::KeyData::KeyData(const KeyData &other)
   \internal
*/
/*!
   \fn QPixmapCache::KeyData::~KeyData()

   \internal
*/
QT_END_NAMESPACE
