/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml 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 <QtCore/qthreadstorage.h>

#include "private/qabstractanimationjob_p.h"
#include "private/qanimationgroupjob_p.h"
#include "private/qanimationjobutil_p.h"
#include "private/qqmlengine_p.h"
#include "private/qqmlglobal_p.h"

QT_BEGIN_NAMESPACE

#ifndef QT_NO_THREAD
Q_GLOBAL_STATIC(QThreadStorage<QQmlAnimationTimer *>, animationTimer)
#endif

DEFINE_BOOL_CONFIG_OPTION(animationTickDump, QML_ANIMATION_TICK_DUMP);

QAnimationJobChangeListener::~QAnimationJobChangeListener()
{
}

QQmlAnimationTimer::QQmlAnimationTimer() :
    QAbstractAnimationTimer(), lastTick(0),
    currentAnimationIdx(0), insideTick(false),
    startAnimationPending(false), stopTimerPending(false),
    runningLeafAnimations(0)
{
}

QQmlAnimationTimer *QQmlAnimationTimer::instance(bool create)
{
    QQmlAnimationTimer *inst;
    if (create && !animationTimer()->hasLocalData()) {
        inst = new QQmlAnimationTimer;
        animationTimer()->setLocalData(inst);
    } else {
        inst = animationTimer() ? animationTimer()->localData() : 0;
    }
    return inst;
}

QQmlAnimationTimer *QQmlAnimationTimer::instance()
{
    return instance(true);
}

void QQmlAnimationTimer::ensureTimerUpdate()
{
    QUnifiedTimer *instU = QUnifiedTimer::instance(false);
    if (instU && isPaused)
        instU->updateAnimationTimers(-1);
}

void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
{
    //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
    if (insideTick)
        return;

    lastTick += delta;

    //we make sure we only call update time if the time has actually changed
    //it might happen in some cases that the time doesn't change because events are delayed
    //when the CPU load is high
    if (delta) {
        insideTick = true;
        for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
            QAbstractAnimationJob *animation = animations.at(currentAnimationIdx);
            int elapsed = animation->m_totalCurrentTime
                          + (animation->direction() == QAbstractAnimationJob::Forward ? delta : -delta);
            animation->setCurrentTime(elapsed);
        }
        if (animationTickDump()) {
            qDebug() << "***** Dumping Animation Tree ***** ( tick:" << lastTick << "delta:" << delta << ")";
            for (int i = 0; i < animations.count(); ++i)
                qDebug() << animations.at(i);
        }
        insideTick = false;
        currentAnimationIdx = 0;
    }
}

void QQmlAnimationTimer::updateAnimationTimer()
{
    restartAnimationTimer();
}

void QQmlAnimationTimer::restartAnimationTimer()
{
    if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty())
        QUnifiedTimer::pauseAnimationTimer(this, closestPauseAnimationTimeToFinish());
    else if (isPaused)
        QUnifiedTimer::resumeAnimationTimer(this);
    else if (!isRegistered)
        QUnifiedTimer::startAnimationTimer(this);
}

void QQmlAnimationTimer::startAnimations()
{
    if (!startAnimationPending)
        return;
    startAnimationPending = false;
    //force timer to update, which prevents large deltas for our newly added animations
    QUnifiedTimer::instance()->maybeUpdateAnimationsToCurrentTime();

    //we transfer the waiting animations into the "really running" state
    animations += animationsToStart;
    animationsToStart.clear();
    if (!animations.isEmpty())
        restartAnimationTimer();
}

void QQmlAnimationTimer::stopTimer()
{
    stopTimerPending = false;
    bool pendingStart = startAnimationPending && animationsToStart.size() > 0;
    if (animations.isEmpty() && !pendingStart) {
        QUnifiedTimer::resumeAnimationTimer(this);
        QUnifiedTimer::stopAnimationTimer(this);
        // invalidate the start reference time
        lastTick = 0;
    }
}

void QQmlAnimationTimer::registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel)
{
    if (animation->userControlDisabled())
        return;

    registerRunningAnimation(animation);
    if (isTopLevel) {
        Q_ASSERT(!animation->m_hasRegisteredTimer);
        animation->m_hasRegisteredTimer = true;
        animationsToStart << animation;
        if (!startAnimationPending) {
            startAnimationPending = true;
            QMetaObject::invokeMethod(this, "startAnimations", Qt::QueuedConnection);
        }
    }
}

void QQmlAnimationTimer::unregisterAnimation(QAbstractAnimationJob *animation)
{
    unregisterRunningAnimation(animation);

    if (!animation->m_hasRegisteredTimer)
        return;

    int idx = animations.indexOf(animation);
    if (idx != -1) {
        animations.removeAt(idx);
        // this is needed if we unregister an animation while its running
        if (idx <= currentAnimationIdx)
            --currentAnimationIdx;

        if (animations.isEmpty() && !stopTimerPending) {
            stopTimerPending = true;
            QMetaObject::invokeMethod(this, "stopTimer", Qt::QueuedConnection);
        }
    } else {
        animationsToStart.removeOne(animation);
    }
    animation->m_hasRegisteredTimer = false;
}

void QQmlAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animation)
{
    Q_ASSERT(!animation->userControlDisabled());

    if (animation->m_isGroup)
        return;

    if (animation->m_isPause) {
        runningPauseAnimations << animation;
    } else
        runningLeafAnimations++;
}

void QQmlAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *animation)
{
    if (animation->userControlDisabled())
        return;

    if (animation->m_isGroup)
        return;

    if (animation->m_isPause)
        runningPauseAnimations.removeOne(animation);
    else
        runningLeafAnimations--;
    Q_ASSERT(runningLeafAnimations >= 0);
}

int QQmlAnimationTimer::closestPauseAnimationTimeToFinish()
{
    int closestTimeToFinish = INT_MAX;
    for (int i = 0; i < runningPauseAnimations.size(); ++i) {
        QAbstractAnimationJob *animation = runningPauseAnimations.at(i);
        int timeToFinish;

        if (animation->direction() == QAbstractAnimationJob::Forward)
            timeToFinish = animation->duration() - animation->currentLoopTime();
        else
            timeToFinish = animation->currentLoopTime();

        if (timeToFinish < closestTimeToFinish)
            closestTimeToFinish = timeToFinish;
    }
    return closestTimeToFinish;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

QAbstractAnimationJob::QAbstractAnimationJob()
    : m_loopCount(1)
    , m_group(nullptr)
    , m_direction(QAbstractAnimationJob::Forward)
    , m_state(QAbstractAnimationJob::Stopped)
    , m_totalCurrentTime(0)
    , m_currentTime(0)
    , m_currentLoop(0)
    , m_uncontrolledFinishTime(-1)
    , m_currentLoopStartTime(0)
    , m_nextSibling(nullptr)
    , m_previousSibling(nullptr)
    , m_hasRegisteredTimer(false)
    , m_isPause(false)
    , m_isGroup(false)
    , m_disableUserControl(false)
    , m_hasCurrentTimeChangeListeners(false)
    , m_isRenderThreadJob(false)
    , m_isRenderThreadProxy(false)

{
}

QAbstractAnimationJob::~QAbstractAnimationJob()
{
    //we can't call stop here. Otherwise we get pure virtual calls
    if (m_state != Stopped) {
        State oldState = m_state;
        m_state = Stopped;
        stateChanged(oldState, m_state);

        Q_ASSERT(m_state == Stopped);
        if (oldState == Running) {
            Q_ASSERT(QQmlAnimationTimer::instance() == m_timer);
            m_timer->unregisterAnimation(this);
        }
        Q_ASSERT(!m_hasRegisteredTimer);
    }

    if (m_group)
        m_group->removeAnimation(this);
}

void QAbstractAnimationJob::fireTopLevelAnimationLoopChanged()
{
    m_uncontrolledFinishTime = -1;
    if (m_group)
        m_currentLoopStartTime = 0;
    topLevelAnimationLoopChanged();
}

void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
{
    if (m_state == newState)
        return;

    if (m_loopCount == 0)
        return;

    if (!m_timer)
        m_timer = QQmlAnimationTimer::instance();

    State oldState = m_state;
    int oldCurrentTime = m_currentTime;
    int oldCurrentLoop = m_currentLoop;
    Direction oldDirection = m_direction;

    // check if we should Rewind
    if ((newState == Paused || newState == Running) && oldState == Stopped) {
        //here we reset the time if needed
        //we don't call setCurrentTime because this might change the way the animation
        //behaves: changing the state or changing the current value
        m_totalCurrentTime = m_currentTime = (m_direction == Forward) ?
            0 : (m_loopCount == -1 ? duration() : totalDuration());

        // Reset uncontrolled finish time and currentLoopStartTime for this run.
        m_uncontrolledFinishTime = -1;
        if (!m_group)
            m_currentLoopStartTime = m_totalCurrentTime;
    }

    m_state = newState;
    //(un)registration of the animation must always happen before calls to
    //virtual function (updateState) to ensure a correct state of the timer
    bool isTopLevel = !m_group || m_group->isStopped();
    if (oldState == Running) {
        if (newState == Paused && m_hasRegisteredTimer)
            m_timer->ensureTimerUpdate();
        //the animation, is not running any more
        m_timer->unregisterAnimation(this);
    } else if (newState == Running) {
        m_timer->registerAnimation(this, isTopLevel);
    }

    //starting an animation qualifies as a top level loop change
    if (newState == Running && oldState == Stopped && !m_group)
        fireTopLevelAnimationLoopChanged();

    RETURN_IF_DELETED(updateState(newState, oldState));

    if (newState != m_state) //this is to be safe if updateState changes the state
        return;

    // Notify state change
    RETURN_IF_DELETED(stateChanged(newState, oldState));
    if (newState != m_state) //this is to be safe if updateState changes the state
        return;

    switch (m_state) {
    case Paused:
        break;
    case Running:
        {
            // this ensures that the value is updated now that the animation is running
            if (oldState == Stopped) {
                m_currentLoop = 0;
                if (isTopLevel) {
                    // currentTime needs to be updated if pauseTimer is active
                    RETURN_IF_DELETED(m_timer->ensureTimerUpdate());
                    RETURN_IF_DELETED(setCurrentTime(m_totalCurrentTime));
                }
            }
        }
        break;
    case Stopped:
        // Leave running state.
        int dura = duration();

        if (dura == -1 || m_loopCount < 0
            || (oldDirection == Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * m_loopCount))
            || (oldDirection == Backward && oldCurrentTime == 0)) {
               finished();
        }
        break;
    }
}

void QAbstractAnimationJob::setDirection(Direction direction)
{
    if (m_direction == direction)
        return;

    if (m_state == Stopped) {
        if (m_direction == Backward) {
            m_currentTime = duration();
            m_currentLoop = m_loopCount - 1;
        } else {
            m_currentTime = 0;
            m_currentLoop = 0;
        }
    }

    // the commands order below is important: first we need to setCurrentTime with the old direction,
    // then update the direction on this and all children and finally restart the pauseTimer if needed
    if (m_hasRegisteredTimer)
        m_timer->ensureTimerUpdate();

    m_direction = direction;
    updateDirection(direction);

    if (m_hasRegisteredTimer)
        // needed to update the timer interval in case of a pause animation
        m_timer->updateAnimationTimer();
}

void QAbstractAnimationJob::setLoopCount(int loopCount)
{
    m_loopCount = loopCount;
}

int QAbstractAnimationJob::totalDuration() const
{
    int dura = duration();
    if (dura <= 0)
        return dura;
    int loopcount = loopCount();
    if (loopcount < 0)
        return -1;
    return dura * loopcount;
}

void QAbstractAnimationJob::setCurrentTime(int msecs)
{
    msecs = qMax(msecs, 0);
    // Calculate new time and loop.
    int dura = duration();
    int totalDura;
    int oldLoop = m_currentLoop;

    if (dura < 0 && m_direction == Forward)  {
        totalDura = -1;
        if (m_uncontrolledFinishTime >= 0 && msecs >= m_uncontrolledFinishTime) {
            msecs = m_uncontrolledFinishTime;
            if (m_currentLoop == m_loopCount - 1) {
                totalDura = m_uncontrolledFinishTime;
            } else {
                ++m_currentLoop;
                m_currentLoopStartTime = msecs;
                m_uncontrolledFinishTime = -1;
            }
        }
        m_totalCurrentTime = msecs;
        m_currentTime = msecs - m_currentLoopStartTime;
    } else {
        totalDura = dura <= 0 ? dura : ((m_loopCount < 0) ? -1 : dura * m_loopCount);
        if (totalDura != -1)
            msecs = qMin(totalDura, msecs);
        m_totalCurrentTime = msecs;

        // Update new values.
        m_currentLoop = ((dura <= 0) ? 0 : (msecs / dura));
        if (m_currentLoop == m_loopCount) {
            //we're at the end
            m_currentTime = qMax(0, dura);
            m_currentLoop = qMax(0, m_loopCount - 1);
        } else {
            if (m_direction == Forward) {
                m_currentTime = (dura <= 0) ? msecs : (msecs % dura);
            } else {
                m_currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1;
                if (m_currentTime == dura)
                    --m_currentLoop;
            }
        }
    }


    if (m_currentLoop != oldLoop && !m_group)   //### verify Running as well?
        fireTopLevelAnimationLoopChanged();

    RETURN_IF_DELETED(updateCurrentTime(m_currentTime));

    if (m_currentLoop != oldLoop)
        currentLoopChanged();

    // All animations are responsible for stopping the animation when their
    // own end state is reached; in this case the animation is time driven,
    // and has reached the end.
    if ((m_direction == Forward && m_totalCurrentTime == totalDura)
        || (m_direction == Backward && m_totalCurrentTime == 0)) {
        RETURN_IF_DELETED(stop());
    }

    if (m_hasCurrentTimeChangeListeners)
        currentTimeChanged(m_currentTime);
}

void QAbstractAnimationJob::start()
{
    if (m_state == Running)
        return;

    if (QQmlEnginePrivate::designerMode()) {
        if (state() != Stopped) {
            m_currentTime = duration();
            m_totalCurrentTime = totalDuration();
            setState(Running);
            setState(Stopped);
        }
    } else {
        setState(Running);
    }
}

void QAbstractAnimationJob::stop()
{
    if (m_state == Stopped)
        return;
    setState(Stopped);
}

void QAbstractAnimationJob::pause()
{
    if (m_state == Stopped) {
        qWarning("QAbstractAnimationJob::pause: Cannot pause a stopped animation");
        return;
    }

    setState(Paused);
}

void QAbstractAnimationJob::resume()
{
    if (m_state != Paused) {
        qWarning("QAbstractAnimationJob::resume: "
                 "Cannot resume an animation that is not paused");
        return;
    }
    setState(Running);
}

void QAbstractAnimationJob::setEnableUserControl()
{
    m_disableUserControl = false;
}

bool QAbstractAnimationJob::userControlDisabled() const
{
    return m_disableUserControl;
}

void QAbstractAnimationJob::setDisableUserControl()
{
    m_disableUserControl = true;
    start();
    pause();
}

void QAbstractAnimationJob::updateState(QAbstractAnimationJob::State newState,
                                     QAbstractAnimationJob::State oldState)
{
    Q_UNUSED(oldState);
    Q_UNUSED(newState);
}

void QAbstractAnimationJob::updateDirection(QAbstractAnimationJob::Direction direction)
{
    Q_UNUSED(direction);
}

void QAbstractAnimationJob::finished()
{
    //TODO: update this code so it is valid to delete the animation in animationFinished
    for (const auto &change : changeListeners) {
        if (change.types & QAbstractAnimationJob::Completion) {
            RETURN_IF_DELETED(change.listener->animationFinished(this));
        }
    }

    if (m_group && (duration() == -1 || loopCount() < 0)) {
        //this is an uncontrolled animation, need to notify the group animation we are finished
        m_group->uncontrolledAnimationFinished(this);
    }
}

void QAbstractAnimationJob::stateChanged(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState)
{
    for (const auto &change : changeListeners) {
        if (change.types & QAbstractAnimationJob::StateChange) {
            RETURN_IF_DELETED(change.listener->animationStateChanged(this, newState, oldState));
        }
    }
}

void QAbstractAnimationJob::currentLoopChanged()
{
    for (const auto &change : changeListeners) {
        if (change.types & QAbstractAnimationJob::CurrentLoop) {
           RETURN_IF_DELETED(change.listener->animationCurrentLoopChanged(this));
        }
    }
}

void QAbstractAnimationJob::currentTimeChanged(int currentTime)
{
    Q_ASSERT(m_hasCurrentTimeChangeListeners);

    for (const auto &change : changeListeners) {
        if (change.types & QAbstractAnimationJob::CurrentTime) {
           RETURN_IF_DELETED(change.listener->animationCurrentTimeChanged(this, currentTime));
        }
    }
}

void QAbstractAnimationJob::addAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes changes)
{
    if (changes & QAbstractAnimationJob::CurrentTime)
        m_hasCurrentTimeChangeListeners = true;

    changeListeners.push_back(ChangeListener(listener, changes));
}

void QAbstractAnimationJob::removeAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes changes)
{
    m_hasCurrentTimeChangeListeners = false;

    const auto it = std::find(changeListeners.begin(), changeListeners.end(), ChangeListener(listener, changes));
    if (it != changeListeners.end())
        changeListeners.erase(it);

    for (const auto &change: changeListeners) {
        if (change.types & QAbstractAnimationJob::CurrentTime) {
            m_hasCurrentTimeChangeListeners = true;
            break;
        }
    }
}

void QAbstractAnimationJob::debugAnimation(QDebug d) const
{
    d << "AbstractAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ") state:"
      << m_state << "duration:" << duration();
}

QDebug operator<<(QDebug d, const QAbstractAnimationJob *job)
{
    if (!job) {
        d << "AbstractAnimationJob(null)";
        return d;
    }
    job->debugAnimation(d);
    return d;
}

QT_END_NAMESPACE

//#include "moc_qabstractanimation2_p.cpp"
#include "moc_qabstractanimationjob_p.cpp"
