/****************************************************************************
**
** 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 "private/qsequentialanimationgroupjob_p.h"
#include "private/qpauseanimationjob_p.h"
#include "private/qanimationjobutil_p.h"

QT_BEGIN_NAMESPACE

QSequentialAnimationGroupJob::QSequentialAnimationGroupJob()
    : QAnimationGroupJob()
    , m_currentAnimation(nullptr)
    , m_previousLoop(0)
{
}

QSequentialAnimationGroupJob::~QSequentialAnimationGroupJob()
{
}

bool QSequentialAnimationGroupJob::atEnd() const
{
    // we try to detect if we're at the end of the group
    //this is true if the following conditions are true:
    // 1. we're in the last loop
    // 2. the direction is forward
    // 3. the current animation is the last one
    // 4. the current animation has reached its end

    const int animTotalCurrentTime = m_currentAnimation->currentTime();
    return (m_currentLoop == m_loopCount - 1
        && m_direction == Forward
        && !m_currentAnimation->nextSibling()
        && animTotalCurrentTime == animationActualTotalDuration(m_currentAnimation));
}

int QSequentialAnimationGroupJob::animationActualTotalDuration(QAbstractAnimationJob *anim) const
{
    int ret = anim->totalDuration();
    if (ret == -1) {
        int done = uncontrolledAnimationFinishTime(anim);
        // If the animation has reached the end, use the uncontrolledFinished value.
        if (done >= 0 && (anim->loopCount() - 1 == anim->currentLoop() || anim->state() == Stopped))
            return done;
    }
    return ret;
}

QSequentialAnimationGroupJob::AnimationIndex QSequentialAnimationGroupJob::indexForCurrentTime() const
{
    Q_ASSERT(firstChild());

    AnimationIndex ret;
    QAbstractAnimationJob *anim = nullptr;
    int duration = 0;

    for (anim = firstChild(); anim; anim = anim->nextSibling()) {
        duration = animationActualTotalDuration(anim);

        // 'animation' is the current animation if one of these reasons is true:
        // 1. it's duration is undefined
        // 2. it ends after msecs
        // 3. it is the last animation (this can happen in case there is at least 1 uncontrolled animation)
        // 4. it ends exactly in msecs and the direction is backwards
        if (duration == -1 || m_currentTime < (ret.timeOffset + duration)
            || (m_currentTime == (ret.timeOffset + duration) && m_direction == QAbstractAnimationJob::Backward)) {
            ret.animation = anim;
            return ret;
        }

        if (anim == m_currentAnimation) {
            ret.afterCurrent = true;
        }

        // 'animation' has a non-null defined duration and is not the one at time 'msecs'.
        ret.timeOffset += duration;
    }

    // this can only happen when one of those conditions is true:
    // 1. the duration of the group is undefined and we passed its actual duration
    // 2. there are only 0-duration animations in the group
    ret.timeOffset -= duration;
    ret.animation = lastChild();
    return ret;
}

void QSequentialAnimationGroupJob::restart()
{
    // restarting the group by making the first/last animation the current one
    if (m_direction == Forward) {
        m_previousLoop = 0;
        if (m_currentAnimation == firstChild())
            activateCurrentAnimation();
        else
            setCurrentAnimation(firstChild());
    }
    else { // direction == Backward
        m_previousLoop = m_loopCount - 1;
        if (m_currentAnimation == lastChild())
            activateCurrentAnimation();
        else
            setCurrentAnimation(lastChild());
    }
}

void QSequentialAnimationGroupJob::advanceForwards(const AnimationIndex &newAnimationIndex)
{
    if (m_previousLoop < m_currentLoop) {
        // we need to fast forward to the end
        for (QAbstractAnimationJob *anim = m_currentAnimation; anim; anim = anim->nextSibling()) {
            RETURN_IF_DELETED(setCurrentAnimation(anim, true));
            RETURN_IF_DELETED(anim->setCurrentTime(animationActualTotalDuration(anim)));
        }
        // this will make sure the current animation is reset to the beginning
        if (firstChild() && !firstChild()->nextSibling()) {   //count == 1
            // we need to force activation because setCurrentAnimation will have no effect
            RETURN_IF_DELETED(activateCurrentAnimation());
        } else {
            RETURN_IF_DELETED(setCurrentAnimation(firstChild(), true));
        }
    }

    // and now we need to fast forward from the current position to
    for (QAbstractAnimationJob *anim = m_currentAnimation; anim && anim != newAnimationIndex.animation; anim = anim->nextSibling()) {     //### WRONG,
        RETURN_IF_DELETED(setCurrentAnimation(anim, true));
        RETURN_IF_DELETED(anim->setCurrentTime(animationActualTotalDuration(anim)));
    }
    // setting the new current animation will happen later
}

void QSequentialAnimationGroupJob::rewindForwards(const AnimationIndex &newAnimationIndex)
{
    if (m_previousLoop > m_currentLoop) {
        // we need to fast rewind to the beginning
        for (QAbstractAnimationJob *anim = m_currentAnimation; anim; anim = anim->previousSibling()) {
            RETURN_IF_DELETED(setCurrentAnimation(anim, true));
            RETURN_IF_DELETED(anim->setCurrentTime(0));
        }
        // this will make sure the current animation is reset to the end
        if (lastChild() && !lastChild()->previousSibling()) {   //count == 1
            // we need to force activation because setCurrentAnimation will have no effect
            RETURN_IF_DELETED(activateCurrentAnimation());
        } else {
            RETURN_IF_DELETED(setCurrentAnimation(lastChild(), true));
        }
    }

    // and now we need to fast rewind from the current position to
    for (QAbstractAnimationJob *anim = m_currentAnimation; anim && anim != newAnimationIndex.animation; anim = anim->previousSibling()) {
        RETURN_IF_DELETED(setCurrentAnimation(anim, true));
        RETURN_IF_DELETED(anim->setCurrentTime(0));
    }
    // setting the new current animation will happen later
}

int QSequentialAnimationGroupJob::duration() const
{
    int ret = 0;

    for (QAbstractAnimationJob *anim = firstChild(); anim; anim = anim->nextSibling()) {
        const int currentDuration = anim->totalDuration();
        if (currentDuration == -1)
            return -1; // Undetermined length

        ret += currentDuration;
    }

    return ret;
}

void QSequentialAnimationGroupJob::clear()
{
    m_previousLoop = 0;
    QAnimationGroupJob::clear();

    // clear() should call removeAnimation(), which will clear m_currentAnimation, eventually.
    Q_ASSERT(m_currentAnimation == nullptr);
}

void QSequentialAnimationGroupJob::updateCurrentTime(int currentTime)
{
    if (!m_currentAnimation)
        return;

    const QSequentialAnimationGroupJob::AnimationIndex newAnimationIndex = indexForCurrentTime();

    // newAnimationIndex.index is the new current animation
    if (m_previousLoop < m_currentLoop
        || (m_previousLoop == m_currentLoop && m_currentAnimation != newAnimationIndex.animation && newAnimationIndex.afterCurrent)) {
            // advancing with forward direction is the same as rewinding with backwards direction
            RETURN_IF_DELETED(advanceForwards(newAnimationIndex));

    } else if (m_previousLoop > m_currentLoop
        || (m_previousLoop == m_currentLoop && m_currentAnimation != newAnimationIndex.animation && !newAnimationIndex.afterCurrent)) {
            // rewinding with forward direction is the same as advancing with backwards direction
            RETURN_IF_DELETED(rewindForwards(newAnimationIndex));
    }

    RETURN_IF_DELETED(setCurrentAnimation(newAnimationIndex.animation));

    const int newCurrentTime = currentTime - newAnimationIndex.timeOffset;

    if (m_currentAnimation) {
        RETURN_IF_DELETED(m_currentAnimation->setCurrentTime(newCurrentTime));
        if (atEnd()) {
            //we make sure that we don't exceed the duration here
            m_currentTime += m_currentAnimation->currentTime() - newCurrentTime;
            RETURN_IF_DELETED(stop());
        }
    } else {
        //the only case where currentAnimation could be null
        //is when all animations have been removed
        Q_ASSERT(!firstChild());
        m_currentTime = 0;
        RETURN_IF_DELETED(stop());
    }

    m_previousLoop = m_currentLoop;
}

void QSequentialAnimationGroupJob::updateState(QAbstractAnimationJob::State newState,
                                            QAbstractAnimationJob::State oldState)
{
    QAnimationGroupJob::updateState(newState, oldState);

    if (!m_currentAnimation)
        return;

    switch (newState) {
    case Stopped:
        m_currentAnimation->stop();
        break;
    case Paused:
        if (oldState == m_currentAnimation->state() && oldState == Running)
            m_currentAnimation->pause();
        else
            restart();
        break;
    case Running:
        if (oldState == m_currentAnimation->state() && oldState == Paused)
            m_currentAnimation->start();
        else
            restart();
        break;
    }
}

void QSequentialAnimationGroupJob::updateDirection(QAbstractAnimationJob::Direction direction)
{
    // we need to update the direction of the current animation
    if (!isStopped() && m_currentAnimation)
        m_currentAnimation->setDirection(direction);
}

void QSequentialAnimationGroupJob::setCurrentAnimation(QAbstractAnimationJob *anim, bool intermediate)
{
    if (!anim) {
        Q_ASSERT(!firstChild());
        m_currentAnimation = nullptr;
        return;
    }

    if (anim == m_currentAnimation)
        return;

    // stop the old current animation
    if (m_currentAnimation)
        m_currentAnimation->stop();

    m_currentAnimation = anim;

    activateCurrentAnimation(intermediate);
}

void QSequentialAnimationGroupJob::activateCurrentAnimation(bool intermediate)
{
    if (!m_currentAnimation || isStopped())
        return;

    m_currentAnimation->stop();

    // we ensure the direction is consistent with the group's direction
    m_currentAnimation->setDirection(m_direction);

    // reset the finish time of the animation if it is uncontrolled
    if (m_currentAnimation->totalDuration() == -1)
        resetUncontrolledAnimationFinishTime(m_currentAnimation);

    RETURN_IF_DELETED(m_currentAnimation->start());
    if (!intermediate && isPaused())
        m_currentAnimation->pause();
}

void QSequentialAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimationJob *animation)
{
    Q_UNUSED(animation);
    Q_ASSERT(animation == m_currentAnimation);

    setUncontrolledAnimationFinishTime(m_currentAnimation, m_currentAnimation->currentTime());

    int totalTime = currentTime();
    if (m_direction == Forward) {
        // set the current animation to be the next one
        if (m_currentAnimation->nextSibling())
            setCurrentAnimation(m_currentAnimation->nextSibling());

        for (QAbstractAnimationJob *a = animation->nextSibling(); a; a = a->nextSibling()) {
            int dur = a->duration();
            if (dur == -1) {
                totalTime = -1;
                break;
            } else {
                totalTime += dur;
            }
        }

    } else {
        // set the current animation to be the previous one
        if (m_currentAnimation->previousSibling())
            setCurrentAnimation(m_currentAnimation->previousSibling());

        for (QAbstractAnimationJob *a = animation->previousSibling(); a; a = a->previousSibling()) {
            int dur = a->duration();
            if (dur == -1) {
                totalTime = -1;
                break;
            } else {
                totalTime += dur;
            }
        }
    }
    if (totalTime >= 0)
        setUncontrolledAnimationFinishTime(this, totalTime);
    if (atEnd())
        stop();
}

void QSequentialAnimationGroupJob::animationInserted(QAbstractAnimationJob *anim)
{
    if (m_currentAnimation == nullptr)
        setCurrentAnimation(firstChild()); // initialize the current animation

    if (m_currentAnimation == anim->nextSibling()
        && m_currentAnimation->currentTime() == 0 && m_currentAnimation->currentLoop() == 0) {
            //in this case we simply insert the animation before the current one has actually started
            setCurrentAnimation(anim);
    }

//    TODO
//    if (index < m_currentAnimationIndex || m_currentLoop != 0) {
//        qWarning("QSequentialGroup::insertAnimation only supports to add animations after the current one.");
//        return; //we're not affected because it is added after the current one
//    }
}

void QSequentialAnimationGroupJob::animationRemoved(QAbstractAnimationJob *anim, QAbstractAnimationJob *prev, QAbstractAnimationJob *next)
{
    QAnimationGroupJob::animationRemoved(anim, prev, next);

    Q_ASSERT(m_currentAnimation); // currentAnimation should always be set

    bool removingCurrent = anim == m_currentAnimation;
    if (removingCurrent) {
        if (next)
            setCurrentAnimation(next); //let's try to take the next one
        else if (prev)
            setCurrentAnimation(prev);
        else// case all animations were removed
            setCurrentAnimation(nullptr);
    }

    // duration of the previous animations up to the current animation
    m_currentTime = 0;
    for (QAbstractAnimationJob *job = firstChild(); job; job = job->nextSibling()) {
        if (job == m_currentAnimation)
            break;
        m_currentTime += animationActualTotalDuration(job);

    }

    if (!removingCurrent) {
        //the current animation is not the one being removed
        //so we add its current time to the current time of this group
        m_currentTime += m_currentAnimation->currentTime();
    }

    //let's also update the total current time
    m_totalCurrentTime = m_currentTime + m_loopCount * duration();
}

void QSequentialAnimationGroupJob::debugAnimation(QDebug d) const
{
    d << "SequentialAnimationGroupJob(" << hex << (const void *) this << dec << ")" << "currentAnimation:" << (void *)m_currentAnimation;

    debugChildren(d);
}

QT_END_NAMESPACE
