/****************************************************************************
**
** 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"

#define DEFAULT_TIMER_INTERVAL 16

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(" << hex << (const void *) this << 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"
