/****************************************************************************
**
** Copyright (C) 2016 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick 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$
**
****************************************************************************/

#include <private/qtquickglobal_p.h>
#include "qquickitemgrabresult.h"

#include "qquickwindow.h"
#include "qquickitem.h"
#if QT_CONFIG(quick_shadereffect)
#include "qquickshadereffectsource_p.h"
#endif

#include <QtQml/QQmlEngine>
#include <QtQml/QQmlInfo>

#include <private/qquickpixmapcache_p.h>
#include <private/qquickitem_p.h>
#include <private/qsgcontext_p.h>
#include <private/qsgadaptationlayer_p.h>

QT_BEGIN_NAMESPACE

const QEvent::Type Event_Grab_Completed = static_cast<QEvent::Type>(QEvent::User + 1);

class QQuickItemGrabResultPrivate : public QObjectPrivate
{
public:
    QQuickItemGrabResultPrivate()
        : cacheEntry(nullptr)
        , qmlEngine(nullptr)
        , texture(nullptr)
    {
    }

    ~QQuickItemGrabResultPrivate()
    {
        delete cacheEntry;
    }

    void ensureImageInCache() const {
        if (url.isEmpty() && !image.isNull()) {
            url.setScheme(QQuickPixmap::itemGrabberScheme);
            url.setPath(QVariant::fromValue(item.data()).toString());
            static uint counter = 0;
            url.setFragment(QString::number(++counter));
            cacheEntry = new QQuickPixmap(url, image);
        }
    }

    static QQuickItemGrabResult *create(QQuickItem *item, const QSize &size);

    QImage image;

    mutable QUrl url;
    mutable QQuickPixmap *cacheEntry;

    QQmlEngine *qmlEngine;
    QJSValue callback;

    QPointer<QQuickItem> item;
    QPointer<QQuickWindow> window;
    QSGLayer *texture;
    QSizeF itemSize;
    QSize textureSize;
};

/*!
 * \qmlproperty url QtQuick::ItemGrabResult::url
 *
 * This property holds a URL which can be used in conjunction with
 * URL based image consumers, such as the QtQuick::Image type.
 *
 * The URL is valid while there is a reference in QML or JavaScript
 * to the ItemGrabResult or while the image the URL references is
 * actively used.
 *
 * The URL does not represent a valid file or location to read it from, it
 * is primarily a key to access images through Qt Quick's image-based types.
 */

/*!
 * \property QQuickItemGrabResult::url
 *
 * This property holds a URL which can be used in conjunction with
 * URL based image consumers, such as the QtQuick::Image type.
 *
 * The URL is valid until the QQuickItemGrabResult object is deleted.
 *
 * The URL does not represent a valid file or location to read it from, it
 * is primarily a key to access images through Qt Quick's image-based types.
 */

/*!
 * \qmlproperty variant QtQuick::ItemGrabResult::image
 *
 * This property holds the pixel results from a grab in the
 * form of a QImage.
 */

/*!
 * \property QQuickItemGrabResult::image
 *
 * This property holds the pixel results from a grab.
 *
 * If the grab is not yet complete or if it failed,
 * a null image is returned (\c {image.isNull()} will return \c true).
 */

/*!
    \class QQuickItemGrabResult
    \inmodule QtQuick
    \brief The QQuickItemGrabResult contains the result from QQuickItem::grabToImage().

    \sa QQuickItem::grabToImage()
 */

/*!
 * \fn void QQuickItemGrabResult::ready()
 *
 * This signal is emitted when the grab has completed.
 */

/*!
 * \qmltype ItemGrabResult
 * \instantiates QQuickItemGrabResult
 * \inherits QtObject
 * \inqmlmodule QtQuick
 * \ingroup qtquick-visual
 * \brief Contains the results from a call to Item::grabToImage().
 *
 * The ItemGrabResult is a small container used to encapsulate
 * the results from Item::grabToImage().
 *
 * \sa Item::grabToImage()
 */

QQuickItemGrabResult::QQuickItemGrabResult(QObject *parent)
    : QObject(*new QQuickItemGrabResultPrivate, parent)
{
}

/*!
 * \qmlmethod bool QtQuick::ItemGrabResult::saveToFile(fileName)
 *
 * Saves the grab result as an image to \a fileName. Returns true
 * if successful; otherwise returns false.
 */

/*!
 * Saves the grab result as an image to \a fileName. Returns true
 * if successful; otherwise returns false.
 *
 * \note In Qt versions prior to 5.9, this function is marked as non-\c{const}.
 */
bool QQuickItemGrabResult::saveToFile(const QString &fileName) const
{
    Q_D(const QQuickItemGrabResult);
    return d->image.save(fileName);
}

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
 * \overload
 * \internal
 */
bool QQuickItemGrabResult::saveToFile(const QString &fileName)
{
    return qAsConst(*this).saveToFile(fileName);
}
#endif // < Qt 6

QUrl QQuickItemGrabResult::url() const
{
    Q_D(const QQuickItemGrabResult);
    d->ensureImageInCache();
    return d->url;
}

QImage QQuickItemGrabResult::image() const
{
    Q_D(const QQuickItemGrabResult);
    return d->image;
}

/*!
 * \internal
 */
bool QQuickItemGrabResult::event(QEvent *e)
{
    Q_D(QQuickItemGrabResult);
    if (e->type() == Event_Grab_Completed) {
        // JS callback
        if (d->qmlEngine && d->callback.isCallable()) {
            d->callback.call(QJSValueList() << d->qmlEngine->newQObject(this));
            deleteLater();
        } else {
            Q_EMIT ready();
        }
        return true;
    }
    return QObject::event(e);
}

void QQuickItemGrabResult::setup()
{
    Q_D(QQuickItemGrabResult);
    if (!d->item) {
        disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing, this, &QQuickItemGrabResult::setup);
        disconnect(d->window.data(), &QQuickWindow::afterRendering, this, &QQuickItemGrabResult::render);
        QCoreApplication::postEvent(this, new QEvent(Event_Grab_Completed));
        return;
    }

    QSGRenderContext *rc = QQuickWindowPrivate::get(d->window.data())->context;
    d->texture = rc->sceneGraphContext()->createLayer(rc);
    d->texture->setItem(QQuickItemPrivate::get(d->item)->itemNode());
    d->itemSize = QSizeF(d->item->width(), d->item->height());
}

void QQuickItemGrabResult::render()
{
    Q_D(QQuickItemGrabResult);
    if (!d->texture)
        return;

    d->texture->setRect(QRectF(0, d->itemSize.height(), d->itemSize.width(), -d->itemSize.height()));
    const QSize minSize = QQuickWindowPrivate::get(d->window.data())->context->sceneGraphContext()->minimumFBOSize();
    d->texture->setSize(QSize(qMax(minSize.width(), d->textureSize.width()),
                              qMax(minSize.height(), d->textureSize.height())));
    d->texture->scheduleUpdate();
    d->texture->updateTexture();
    d->image =  d->texture->toImage();

    delete d->texture;
    d->texture = nullptr;

    disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing, this, &QQuickItemGrabResult::setup);
    disconnect(d->window.data(), &QQuickWindow::afterRendering, this, &QQuickItemGrabResult::render);
    QCoreApplication::postEvent(this, new QEvent(Event_Grab_Completed));
}

QQuickItemGrabResult *QQuickItemGrabResultPrivate::create(QQuickItem *item, const QSize &targetSize)
{
    QSize size = targetSize;
    if (size.isEmpty())
        size = QSize(item->width(), item->height());

    if (size.width() < 1 || size.height() < 1) {
        qmlWarning(item) << "grabToImage: item has invalid dimensions";
        return nullptr;
    }

    if (!item->window()) {
        qmlWarning(item) << "grabToImage: item is not attached to a window";
        return nullptr;
    }

    if (!item->window()->isVisible()) {
        qmlWarning(item) << "grabToImage: item's window is not visible";
        return nullptr;
    }

    QQuickItemGrabResult *result = new QQuickItemGrabResult();
    QQuickItemGrabResultPrivate *d = result->d_func();
    d->item = item;
    d->window = item->window();
    d->textureSize = size;

    QQuickItemPrivate::get(item)->refFromEffectItem(false);

    // trigger sync & render
    item->window()->update();

    return result;
}

/*!
 * Grabs the item into an in-memory image.
 *
 * The grab happens asynchronously and the signal QQuickItemGrabResult::ready()
 * is emitted when the grab has been completed.
 *
 * Use \a targetSize to specify the size of the target image. By default, the
 * result will have the same size as item.
 *
 * If the grab could not be initiated, the function returns \c null.
 *
 * \note This function will render the item to an offscreen surface and
 * copy that surface from the GPU's memory into the CPU's memory, which can
 * be quite costly. For "live" preview, use \l {QtQuick::Item::layer.enabled} {layers}
 * or ShaderEffectSource.
 *
 * \sa QQuickWindow::grabWindow()
 */
QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(const QSize &targetSize)
{
    QQuickItemGrabResult *result = QQuickItemGrabResultPrivate::create(this, targetSize);
    if (!result)
        return QSharedPointer<QQuickItemGrabResult>();

    connect(window(), &QQuickWindow::beforeSynchronizing, result, &QQuickItemGrabResult::setup, Qt::DirectConnection);
    connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);

    return QSharedPointer<QQuickItemGrabResult>(result);
}

/*!
 * \qmlmethod bool QtQuick::Item::grabToImage(callback, targetSize)
 *
 * Grabs the item into an in-memory image.
 *
 * The grab happens asynchronously and the JavaScript function \a callback is
 * invoked when the grab is completed. The callback takes one argument, which
 * is the result of the grab operation; an \l ItemGrabResult object.
 *
 * Use \a targetSize to specify the size of the target image. By default, the result
 * will have the same size as the item.
 *
 * If the grab could not be initiated, the function returns \c false.
 *
 * The following snippet shows how to grab an item and store the results to
 * a file.
 *
 * \snippet qml/itemGrab.qml grab-source
 * \snippet qml/itemGrab.qml grab-to-file
 *
 * The following snippet shows how to grab an item and use the results in
 * another image element.
 *
 * \snippet qml/itemGrab.qml grab-image-target
 * \snippet qml/itemGrab.qml grab-to-cache
 *
 * \note This function will render the item to an offscreen surface and
 * copy that surface from the GPU's memory into the CPU's memory, which can
 * be quite costly. For "live" preview, use \l {QtQuick::Item::layer.enabled} {layers}
 * or ShaderEffectSource.
 */

/*!
 * \internal
 * Only visible from QML.
 */
bool QQuickItem::grabToImage(const QJSValue &callback, const QSize &targetSize)
{
    QQmlEngine *engine = qmlEngine(this);
    if (!engine) {
        qmlWarning(this) << "grabToImage: item has no QML engine";
        return false;
    }

    if (!callback.isCallable()) {
        qmlWarning(this) << "grabToImage: 'callback' is not a function";
        return false;
    }

    QSize size = targetSize;
    if (size.isEmpty())
        size = QSize(width(), height());

    if (size.width() < 1 || size.height() < 1) {
        qmlWarning(this) << "grabToImage: item has invalid dimensions";
        return false;
    }

    if (!window()) {
        qmlWarning(this) << "grabToImage: item is not attached to a window";
        return false;
    }

    QQuickItemGrabResult *result = QQuickItemGrabResultPrivate::create(this, size);
    if (!result)
        return false;

    connect(window(), &QQuickWindow::beforeSynchronizing, result, &QQuickItemGrabResult::setup, Qt::DirectConnection);
    connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);

    QQuickItemGrabResultPrivate *d = result->d_func();
    d->qmlEngine = engine;
    d->callback = callback;
    return true;
}

QT_END_NAMESPACE

#include "moc_qquickitemgrabresult.cpp"
