/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Gunnar Sletta <gunnar@sletta.org>
** 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 "qquickanimatorcontroller_p.h"
#include "qquickanimatorjob_p.h"
#include "qquickanimator_p.h"
#include "qquickanimator_p_p.h"
#include <private/qquickwindow_p.h>
#include <private/qquickitem_p.h>
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
# include <private/qquickopenglshadereffectnode_p.h>
# include <private/qquickopenglshadereffect_p.h>
# include <private/qquickshadereffect_p.h>
#endif
#include <private/qanimationgroupjob_p.h>

#include <qcoreapplication.h>
#include <qdebug.h>

QT_BEGIN_NAMESPACE

struct QQuickTransformAnimatorHelperStore
{
    QHash<QQuickItem *, QQuickTransformAnimatorJob::Helper *> store;
    QMutex mutex;

    QQuickTransformAnimatorJob::Helper *acquire(QQuickItem *item) {
        mutex.lock();
        QQuickTransformAnimatorJob::Helper *helper = store.value(item);
        if (!helper) {
            helper = new QQuickTransformAnimatorJob::Helper();
            helper->item = item;
            store[item] = helper;
        } else {
            ++helper->ref;
        }
        mutex.unlock();
        return helper;
    }

    void release(QQuickTransformAnimatorJob::Helper *helper) {
        mutex.lock();
        if (--helper->ref == 0) {
            store.remove(helper->item);
            delete helper;
        }
        mutex.unlock();
    }
};
Q_GLOBAL_STATIC(QQuickTransformAnimatorHelperStore, qquick_transform_animatorjob_helper_store);

QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObject *item)
    : m_controller(nullptr)
    , m_internalState(State_Stopped)
{
    m_job.reset(job);

    m_isRenderThreadProxy = true;
    m_animation = qobject_cast<QQuickAbstractAnimation *>(item);

    setLoopCount(job->loopCount());

    // Instead of setting duration to job->duration() we need to set it to -1 so that
    // it runs as long as the job is running on the render thread. If we gave it
    // an explicit duration, it would be stopped, potentially stopping the RT animation
    // prematurely.
    // This means that the animation driver will tick on the GUI thread as long
    // as the animation is running on the render thread, but this overhead will
    // be negligiblie compared to animating and re-rendering the scene on the render thread.
    m_duration = -1;

    QObject *ctx = findAnimationContext(m_animation);
    if (!ctx) {
        qWarning("QtQuick: unable to find animation context for RT animation...");
        return;
    }

    QQuickWindow *window = qobject_cast<QQuickWindow *>(ctx);
    if (window) {
        setWindow(window);
    } else {
        QQuickItem *item = qobject_cast<QQuickItem *>(ctx);
        if (item->window())
            setWindow(item->window());
        connect(item, &QQuickItem::windowChanged, this, &QQuickAnimatorProxyJob::windowChanged);
    }
}

QQuickAnimatorProxyJob::~QQuickAnimatorProxyJob()
{
    if (m_job && m_controller)
        m_controller->cancel(m_job);
    m_job.reset();
}

QObject *QQuickAnimatorProxyJob::findAnimationContext(QQuickAbstractAnimation *a)
{
    QObject *p = a->parent();
    while (p != nullptr && qobject_cast<QQuickWindow *>(p) == nullptr && qobject_cast<QQuickItem *>(p) == nullptr)
        p = p->parent();
    return p;
}

void QQuickAnimatorProxyJob::updateCurrentTime(int)
{
    if (m_internalState != State_Running)
        return;

    // A proxy which is being ticked should be associated with a window, (see
    // setWindow() below). If we get here when there is no more controller we
    // have a problem.
    Q_ASSERT(m_controller);

    // We do a simple check here to see if the animator has run and stopped on
    // the render thread. isPendingStart() will perform a check against jobs
    // that have been scheduled for start, but that will not yet have entered
    // the actual running state.
    // Secondly, we make an unprotected read of the job's state to figure out
    // if it is running, but this is ok, since we're only reading the state
    // and if the render thread should happen to be writing it concurrently,
    // we might get the wrong value for this update,  but then we'll simply
    // pick it up on the next iterationm when the job is stopped and render
    // thread is no longer using it.
    if (!m_controller->isPendingStart(m_job)
        && !m_job->isRunning()) {
        stop();
    }
}

void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State)
{
    if (m_state == Running) {
        m_internalState = State_Starting;
        if (m_controller) {
            m_internalState = State_Running;
            m_controller->start(m_job);
        }

    } else if (newState == Stopped) {
        m_internalState = State_Stopped;
        if (m_controller) {
            syncBackCurrentValues();
            m_controller->cancel(m_job);
        }
    }
}

void QQuickAnimatorProxyJob::debugAnimation(QDebug d) const
{
    d << "QuickAnimatorProxyJob("<< Qt::hex << (const void *) this << Qt::dec
      << "state:" << state() << "duration:" << duration()
      << "proxying: (" << job() << ')';
}

void QQuickAnimatorProxyJob::windowChanged(QQuickWindow *window)
{
    setWindow(window);
}

void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window)
{
    if (!window) {
        if (m_job && m_controller) {
            disconnect(m_controller->window(), &QQuickWindow::sceneGraphInitialized,
                       this, &QQuickAnimatorProxyJob::sceneGraphInitialized);
            m_controller->cancel(m_job);
        }

        m_controller = nullptr;
        stop();

    } else if (!m_controller && m_job) {
        m_controller = QQuickWindowPrivate::get(window)->animationController.get();
        if (window->isSceneGraphInitialized())
            readyToAnimate();
        else
            connect(window, &QQuickWindow::sceneGraphInitialized, this, &QQuickAnimatorProxyJob::sceneGraphInitialized);
    }
}

void QQuickAnimatorProxyJob::sceneGraphInitialized()
{
    if (m_controller) {
        disconnect(m_controller->window(), &QQuickWindow::sceneGraphInitialized, this, &QQuickAnimatorProxyJob::sceneGraphInitialized);
        readyToAnimate();
    }
}

void QQuickAnimatorProxyJob::readyToAnimate()
{
    Q_ASSERT(m_controller);
    if (m_internalState == State_Starting) {
        m_internalState = State_Running;
        m_controller->start(m_job);
    }
}

static void qquick_syncback_helper(QAbstractAnimationJob *job)
{
    if (job->isRenderThreadJob()) {
        static_cast<QQuickAnimatorJob *>(job)->writeBack();

    } else if (job->isGroup()) {
        QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job);
        for (QAbstractAnimationJob *a = g->firstChild(); a; a = a->nextSibling())
            qquick_syncback_helper(a);
    }

}

void QQuickAnimatorProxyJob::syncBackCurrentValues()
{
    if (m_job)
        qquick_syncback_helper(m_job.data());
}

QQuickAnimatorJob::QQuickAnimatorJob()
    : m_target(nullptr)
    , m_controller(nullptr)
    , m_from(0)
    , m_to(0)
    , m_value(0)
    , m_duration(0)
    , m_isTransform(false)
    , m_isUniform(false)
{
    m_isRenderThreadJob = true;
}

void QQuickAnimatorJob::debugAnimation(QDebug d) const
{
    d << "QuickAnimatorJob(" << Qt::hex << (const void *) this << Qt::dec
      << ") state:" << state() << "duration:" << duration()
      << "target:" << m_target << "value:" << m_value;
}

qreal QQuickAnimatorJob::progress(int time) const
{
    return m_easing.valueForProgress((m_duration == 0) ? qreal(1) : qreal(time) / qreal(m_duration));
}

qreal QQuickAnimatorJob::value() const
{
    qreal value = m_to;
    if (m_controller) {
        m_controller->lock();
        value = m_value;
        m_controller->unlock();
    }
    return value;
}

void QQuickAnimatorJob::setTarget(QQuickItem *target)
{
    m_target = target;
}

void QQuickAnimatorJob::initialize(QQuickAnimatorController *controller)
{
    m_controller = controller;
}

QQuickTransformAnimatorJob::QQuickTransformAnimatorJob()
    : m_helper(nullptr)
{
    m_isTransform = true;
}

QQuickTransformAnimatorJob::~QQuickTransformAnimatorJob()
{
    if (m_helper)
        qquick_transform_animatorjob_helper_store()->release(m_helper);
}

void QQuickTransformAnimatorJob::setTarget(QQuickItem *item)
{
    // In the extremely unlikely event that the target of an animator has been
    // changed into a new item that sits in the exact same pointer address, we
    // want to force syncing it again.
    if (m_helper && m_target)
        m_helper->wasSynced = false;
    QQuickAnimatorJob::setTarget(item);
}

void QQuickTransformAnimatorJob::preSync()
{
    // If the target has changed or become null, release and reset the helper
    if (m_helper && (m_helper->item != m_target || !m_target)) {
        qquick_transform_animatorjob_helper_store()->release(m_helper);
        m_helper = nullptr;
    }

    if (!m_target) {
        invalidate();
        return;
    }

    if (!m_helper) {
        m_helper = qquick_transform_animatorjob_helper_store()->acquire(m_target);

        // This is a bit superfluous, but it ends up being simpler than the
        // alternative.  When an item happens to land on the same address as a
        // previous item, that helper might not have been fully cleaned up by
        // the time it gets taken back into use. As an alternative to storing
        // connections to each and every item's QObject::destroyed() and
        // having to clean those up afterwards, we simply sync all helpers on
        // the first run. The sync is only done once for the run of an
        // animation and it is a fairly light function (compared to storing
        // potentially thousands of connections and managing their lifetime.
        m_helper->wasSynced = false;
    }

    m_helper->sync();
}

void QQuickTransformAnimatorJob::invalidate()
{
    if (m_helper)
        m_helper->node = nullptr;
}

void QQuickTransformAnimatorJob::Helper::sync()
{
    const quint32 mask = QQuickItemPrivate::Position
            | QQuickItemPrivate::BasicTransform
            | QQuickItemPrivate::TransformOrigin
            | QQuickItemPrivate::Size;

    QQuickItemPrivate *d = QQuickItemPrivate::get(item);
#if QT_CONFIG(quick_shadereffect)
    if (d->extra.isAllocated()
            && d->extra->layer
            && d->extra->layer->enabled()) {
        d = QQuickItemPrivate::get(d->extra->layer->m_effectSource);
    }
#endif

    quint32 dirty = mask & d->dirtyAttributes;

    if (!wasSynced) {
        dirty = 0xffffffffu;
        wasSynced = true;
    }

    if (dirty == 0)
        return;

    node = d->itemNode();

    if (dirty & QQuickItemPrivate::Position) {
        dx = item->x();
        dy = item->y();
    }

    if (dirty & QQuickItemPrivate::BasicTransform) {
        scale = item->scale();
        rotation = item->rotation();
    }

    if (dirty & (QQuickItemPrivate::TransformOrigin | QQuickItemPrivate::Size)) {
        QPointF o = item->transformOriginPoint();
        ox = o.x();
        oy = o.y();
    }
}

void QQuickTransformAnimatorJob::Helper::commit()
{
    if (!wasChanged || !node)
        return;

    QMatrix4x4 m;
    m.translate(dx, dy);
    m.translate(ox, oy);
    m.scale(scale);
    m.rotate(rotation, 0, 0, 1);
    m.translate(-ox, -oy);
    node->setMatrix(m);

    wasChanged = false;
}

void QQuickTransformAnimatorJob::commit()
{
    if (m_helper)
        m_helper->commit();
}

void QQuickXAnimatorJob::writeBack()
{
    if (m_target)
        m_target->setX(value());
}

void QQuickXAnimatorJob::updateCurrentTime(int time)
{
#if QT_CONFIG(opengl)
    Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
#endif
    if (!m_helper)
        return;

    m_value = m_from + (m_to - m_from) * progress(time);
    m_helper->dx = m_value;
    m_helper->wasChanged = true;
}

void QQuickYAnimatorJob::writeBack()
{
    if (m_target)
        m_target->setY(value());
}

void QQuickYAnimatorJob::updateCurrentTime(int time)
{
#if QT_CONFIG(opengl)
    Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
#endif
    if (!m_helper)
        return;

    m_value = m_from + (m_to - m_from) * progress(time);
    m_helper->dy = m_value;
    m_helper->wasChanged = true;
}

void QQuickScaleAnimatorJob::writeBack()
{
    if (m_target)
        m_target->setScale(value());
}

void QQuickScaleAnimatorJob::updateCurrentTime(int time)
{
#if QT_CONFIG(opengl)
    Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
#endif
    if (!m_helper)
        return;

    m_value = m_from + (m_to - m_from) * progress(time);
    m_helper->scale = m_value;
    m_helper->wasChanged = true;
}


QQuickRotationAnimatorJob::QQuickRotationAnimatorJob()
    : m_direction(QQuickRotationAnimator::Numerical)
{
}

extern QVariant _q_interpolateShortestRotation(qreal &f, qreal &t, qreal progress);
extern QVariant _q_interpolateClockwiseRotation(qreal &f, qreal &t, qreal progress);
extern QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal progress);

void QQuickRotationAnimatorJob::updateCurrentTime(int time)
{
#if QT_CONFIG(opengl)
    Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
#endif
    if (!m_helper)
        return;

    float t = progress(time);

    switch (m_direction) {
    case QQuickRotationAnimator::Clockwise:
        m_value = _q_interpolateClockwiseRotation(m_from, m_to, t).toFloat();
        // The logic in _q_interpolateClockwise comes out a bit wrong
        // for the case of X->0 where 0<X<360. It ends on 360 which it
        // shouldn't.
        if (t == 1)
            m_value = m_to;
        break;
    case QQuickRotationAnimator::Counterclockwise:
        m_value = _q_interpolateCounterclockwiseRotation(m_from, m_to, t).toFloat();
        break;
    case QQuickRotationAnimator::Shortest:
        m_value = _q_interpolateShortestRotation(m_from, m_to, t).toFloat();
        break;
    case QQuickRotationAnimator::Numerical:
        m_value = m_from + (m_to - m_from) * t;
        break;
    }
    m_helper->rotation = m_value;
    m_helper->wasChanged = true;
}

void QQuickRotationAnimatorJob::writeBack()
{
    if (m_target)
        m_target->setRotation(value());
}


QQuickOpacityAnimatorJob::QQuickOpacityAnimatorJob()
    : m_opacityNode(nullptr)
{
}

void QQuickOpacityAnimatorJob::postSync()
{
    if (!m_target) {
        invalidate();
        return;
    }

    QQuickItemPrivate *d = QQuickItemPrivate::get(m_target);
#if QT_CONFIG(quick_shadereffect)
    if (d->extra.isAllocated()
            && d->extra->layer
            && d->extra->layer->enabled()) {
        d = QQuickItemPrivate::get(d->extra->layer->m_effectSource);
    }
#endif

    m_opacityNode = d->opacityNode();

    if (!m_opacityNode) {
        m_opacityNode = new QSGOpacityNode();

        /* The item node subtree is like this
         *
         * itemNode
         * (opacityNode)            optional
         * (clipNode)               optional
         * (rootNode)               optional
         * children / paintNode
         *
         * If the opacity node doesn't exist, we need to insert it into
         * the hierarchy between itemNode and clipNode or rootNode. If
         * neither clip or root exists, we need to reparent all children
         * from itemNode to opacityNode.
         */
        QSGNode *iNode = d->itemNode();
        QSGNode *child = d->childContainerNode();
        if (child != iNode) {
            if (child->parent())
                child->parent()->removeChildNode(child);
            m_opacityNode->appendChildNode(child);
            iNode->appendChildNode(m_opacityNode);
        } else {
            iNode->reparentChildNodesTo(m_opacityNode);
            iNode->appendChildNode(m_opacityNode);
        }

        d->extra.value().opacityNode = m_opacityNode;
        updateCurrentTime(0);
    }
    Q_ASSERT(m_opacityNode);
}

void QQuickOpacityAnimatorJob::invalidate()
{
    m_opacityNode = nullptr;
}

void QQuickOpacityAnimatorJob::writeBack()
{
    if (m_target)
        m_target->setOpacity(value());
}

void QQuickOpacityAnimatorJob::updateCurrentTime(int time)
{
#if QT_CONFIG(opengl)
    Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread());
#endif

    if (!m_opacityNode)
        return;

    m_value = m_from + (m_to - m_from) * progress(time);
    m_opacityNode->setOpacity(m_value);
}


#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
QQuickUniformAnimatorJob::QQuickUniformAnimatorJob()
    : m_node(nullptr)
    , m_uniformIndex(-1)
    , m_uniformType(-1)
{
    m_isUniform = true;
}

void QQuickUniformAnimatorJob::setTarget(QQuickItem *target)
{
    QQuickShaderEffect* effect = qobject_cast<QQuickShaderEffect*>(target);
    if (effect && effect->isOpenGLShaderEffect())
        m_target = target;
}

void QQuickUniformAnimatorJob::invalidate()
{
    m_node = nullptr;
    m_uniformIndex = -1;
    m_uniformType = -1;
}

void QQuickUniformAnimatorJob::postSync()
{
    if (!m_target) {
        invalidate();
        return;
    }

    m_node = static_cast<QQuickOpenGLShaderEffectNode *>(QQuickItemPrivate::get(m_target)->paintNode);

    if (m_node && m_uniformIndex == -1 && m_uniformType == -1) {
        QQuickOpenGLShaderEffectMaterial *material =
                static_cast<QQuickOpenGLShaderEffectMaterial *>(m_node->material());
        bool found = false;
        for (int t=0; !found && t<QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++t) {
            const QVector<QQuickOpenGLShaderEffectMaterial::UniformData> &uniforms = material->uniforms[t];
            for (int i=0; i<uniforms.size(); ++i) {
                if (uniforms.at(i).name == m_uniform) {
                    m_uniformIndex = i;
                    m_uniformType = t;
                    found = true;
                    break;
                }
            }
        }
    }

}

void QQuickUniformAnimatorJob::updateCurrentTime(int time)
{
    if (!m_controller)
        return;

    if (!m_node || m_uniformIndex == -1 || m_uniformType == -1)
        return;

    m_value = m_from + (m_to - m_from) * progress(time);

    QQuickOpenGLShaderEffectMaterial *material =
            static_cast<QQuickOpenGLShaderEffectMaterial *>(m_node->material());
    material->uniforms[m_uniformType][m_uniformIndex].value = m_value;
    // As we're not touching the nodes, we need to explicitly mark it dirty.
    // Otherwise, the renderer will abort repainting if this was the only
    // change in the graph currently rendering.
    m_node->markDirty(QSGNode::DirtyMaterial);
}

void QQuickUniformAnimatorJob::writeBack()
{
    if (m_target)
        m_target->setProperty(m_uniform, value());
}
#endif

QT_END_NAMESPACE

#include "moc_qquickanimatorjob_p.cpp"
