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

/*!
    \class QSequentialAnimationGroup
    \inmodule QtCore
    \brief The QSequentialAnimationGroup class provides a sequential group of animations.
    \since 4.6
    \ingroup animation

    QSequentialAnimationGroup is a QAnimationGroup that runs its
    animations in sequence, i.e., it starts one animation after
    another has finished playing. The animations are played in the
    order they are added to the group (using
    \l{QAnimationGroup::}{addAnimation()} or
    \l{QAnimationGroup::}{insertAnimation()}). The animation group
    finishes when its last animation has finished.

    At each moment there is at most one animation that is active in
    the group; it is returned by currentAnimation(). An empty group
    has no current animation.

    A sequential animation group can be treated as any other
    animation, i.e., it can be started, stopped, and added to other
    groups. You can also call addPause() or insertPause() to add a
    pause to a sequential animation group.

    \snippet code/src_corelib_animation_qsequentialanimationgroup.cpp 0

    In this example, \c anim1 and \c anim2 are two already set up
    \l{QPropertyAnimation}s.

    \sa QAnimationGroup, QAbstractAnimation, {The Animation Framework}
*/

#include "qsequentialanimationgroup.h"
#include "qsequentialanimationgroup_p.h"

#include "qpauseanimation.h"

#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

typedef QList<QAbstractAnimation *>::ConstIterator AnimationListConstIt;

bool QSequentialAnimationGroupPrivate::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 = QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
    return (currentLoop == loopCount - 1
        && direction == QAbstractAnimation::Forward
        && currentAnimation == animations.last()
        && animTotalCurrentTime == animationActualTotalDuration(currentAnimationIndex));
}

int QSequentialAnimationGroupPrivate::animationActualTotalDuration(int index) const
{
    QAbstractAnimation *anim = animations.at(index);
    int ret = anim->totalDuration();
    if (ret == -1 && actualDuration.size() > index)
        ret = actualDuration.at(index); //we can try the actual duration there
    return ret;
}

QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForCurrentTime() const
{
    Q_ASSERT(!animations.isEmpty());

    AnimationIndex ret;
    int duration = 0;

    for (int i = 0; i < animations.size(); ++i) {
        duration = animationActualTotalDuration(i);

        // '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 || currentTime < (ret.timeOffset + duration)
            || (currentTime == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) {
            ret.index = i;
            return ret;
        }

        // '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.index = animations.size() - 1;
    return ret;
}

void QSequentialAnimationGroupPrivate::restart()
{
    // restarting the group by making the first/last animation the current one
    if (direction == QAbstractAnimation::Forward) {
        lastLoop = 0;
        if (currentAnimationIndex == 0)
            activateCurrentAnimation();
        else
            setCurrentAnimation(0);
    } else { // direction == QAbstractAnimation::Backward
        lastLoop = loopCount - 1;
        int index = animations.size() - 1;
        if (currentAnimationIndex == index)
            activateCurrentAnimation();
        else
            setCurrentAnimation(index);
    }
}

/*!
    \internal
    This manages advancing the execution of a group running forwards (time has gone forward),
    which is the same behaviour for rewinding the execution of a group running backwards
    (time has gone backward).
*/
void QSequentialAnimationGroupPrivate::advanceForwards(const AnimationIndex &newAnimationIndex)
{
    if (lastLoop < currentLoop) {
        // we need to fast forward to the end
        for (int i = currentAnimationIndex; i < animations.size(); ++i) {
            QAbstractAnimation *anim = animations.at(i);
            setCurrentAnimation(i, true);
            anim->setCurrentTime(animationActualTotalDuration(i));
        }
        // this will make sure the current animation is reset to the beginning
        if (animations.size() == 1)
            // we need to force activation because setCurrentAnimation will have no effect
            activateCurrentAnimation();
        else
            setCurrentAnimation(0, true);
    }

    // and now we need to fast forward from the current position to
    for (int i = currentAnimationIndex; i < newAnimationIndex.index; ++i) {     //### WRONG,
        QAbstractAnimation *anim = animations.at(i);
        setCurrentAnimation(i, true);
        anim->setCurrentTime(animationActualTotalDuration(i));
    }
    // setting the new current animation will happen later
}

/*!
    \internal
    This manages rewinding the execution of a group running forwards (time has gone forward),
    which is the same behaviour for advancing the execution of a group running backwards
    (time has gone backward).
*/
void QSequentialAnimationGroupPrivate::rewindForwards(const AnimationIndex &newAnimationIndex)
{
    if (lastLoop > currentLoop) {
        // we need to fast rewind to the beginning
        for (int i = currentAnimationIndex; i >= 0 ; --i) {
            QAbstractAnimation *anim = animations.at(i);
            setCurrentAnimation(i, true);
            anim->setCurrentTime(0);
        }
        // this will make sure the current animation is reset to the end
        if (animations.size() == 1)
            // we need to force activation because setCurrentAnimation will have no effect
            activateCurrentAnimation();
        else
            setCurrentAnimation(animations.count() - 1, true);
    }

    // and now we need to fast rewind from the current position to
    for (int i = currentAnimationIndex; i > newAnimationIndex.index; --i) {
        QAbstractAnimation *anim = animations.at(i);
        setCurrentAnimation(i, true);
        anim->setCurrentTime(0);
    }
    // setting the new current animation will happen later
}

/*!
    \fn QSequentialAnimationGroup::currentAnimationChanged(QAbstractAnimation *current)

    QSequentialAnimationGroup emits this signal when currentAnimation
    has been changed. \a current is the current animation.

    \sa currentAnimation()
*/


/*!
    Constructs a QSequentialAnimationGroup.
    \a parent is passed to QObject's constructor.
*/
QSequentialAnimationGroup::QSequentialAnimationGroup(QObject *parent)
    : QAnimationGroup(*new QSequentialAnimationGroupPrivate, parent)
{
}

/*!
    \internal
*/
QSequentialAnimationGroup::QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd,
                                                     QObject *parent)
    : QAnimationGroup(dd, parent)
{
}

/*!
    Destroys the animation group. It will also destroy all its animations.
*/
QSequentialAnimationGroup::~QSequentialAnimationGroup()
{
}

/*!
    Adds a pause of \a msecs to this animation group.
    The pause is considered as a special type of animation, thus
    \l{QAnimationGroup::animationCount()}{animationCount} will be
    increased by one.

    \sa insertPause(), QAnimationGroup::addAnimation()
*/
QPauseAnimation *QSequentialAnimationGroup::addPause(int msecs)
{
    QPauseAnimation *pause = new QPauseAnimation(msecs);
    addAnimation(pause);
    return pause;
}

/*!
    Inserts a pause of \a msecs milliseconds at \a index in this animation
    group.

    \sa addPause(), QAnimationGroup::insertAnimation()
*/
QPauseAnimation *QSequentialAnimationGroup::insertPause(int index, int msecs)
{
    Q_D(const QSequentialAnimationGroup);

    if (index < 0 || index > d->animations.size()) {
        qWarning("QSequentialAnimationGroup::insertPause: index is out of bounds");
        return 0;
    }

    QPauseAnimation *pause = new QPauseAnimation(msecs);
    insertAnimation(index, pause);
    return pause;
}


/*!
    \property QSequentialAnimationGroup::currentAnimation
    Returns the animation in the current time.
*/
QAbstractAnimation *QSequentialAnimationGroup::currentAnimation() const
{
    Q_D(const QSequentialAnimationGroup);
    return d->currentAnimation;
}

/*!
    \reimp
*/
int QSequentialAnimationGroup::duration() const
{
    Q_D(const QSequentialAnimationGroup);
    int ret = 0;

    for (AnimationListConstIt it = d->animations.constBegin(), cend = d->animations.constEnd(); it != cend; ++it) {
        const int currentDuration = (*it)->totalDuration();
        if (currentDuration == -1)
            return -1; // Undetermined length

        ret += currentDuration;
    }

    return ret;
}

/*!
    \reimp
*/
void QSequentialAnimationGroup::updateCurrentTime(int currentTime)
{
    Q_D(QSequentialAnimationGroup);
    if (!d->currentAnimation)
        return;

    const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForCurrentTime();

    // remove unneeded animations from actualDuration list
    while (newAnimationIndex.index < d->actualDuration.size())
        d->actualDuration.removeLast();

    // newAnimationIndex.index is the new current animation
    if (d->lastLoop < d->currentLoop
        || (d->lastLoop == d->currentLoop && d->currentAnimationIndex < newAnimationIndex.index)) {
            // advancing with forward direction is the same as rewinding with backwards direction
            d->advanceForwards(newAnimationIndex);
    } else if (d->lastLoop > d->currentLoop
        || (d->lastLoop == d->currentLoop && d->currentAnimationIndex > newAnimationIndex.index)) {
            // rewinding with forward direction is the same as advancing with backwards direction
            d->rewindForwards(newAnimationIndex);
    }

    d->setCurrentAnimation(newAnimationIndex.index);

    const int newCurrentTime = currentTime - newAnimationIndex.timeOffset;

    if (d->currentAnimation) {
        d->currentAnimation->setCurrentTime(newCurrentTime);
        if (d->atEnd()) {
            //we make sure that we don't exceed the duration here
            d->currentTime += QAbstractAnimationPrivate::get(d->currentAnimation)->totalCurrentTime - newCurrentTime;
            stop();
        }
    } else {
        //the only case where currentAnimation could be null
        //is when all animations have been removed
        Q_ASSERT(d->animations.isEmpty());
        d->currentTime = 0;
        stop();
    }

    d->lastLoop = d->currentLoop;
}

/*!
    \reimp
*/
void QSequentialAnimationGroup::updateState(QAbstractAnimation::State newState,
                                            QAbstractAnimation::State oldState)
{
    Q_D(QSequentialAnimationGroup);
    QAnimationGroup::updateState(newState, oldState);

    if (!d->currentAnimation)
        return;

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

/*!
    \reimp
*/
void QSequentialAnimationGroup::updateDirection(QAbstractAnimation::Direction direction)
{
    Q_D(QSequentialAnimationGroup);
    // we need to update the direction of the current animation
    if (state() != Stopped && d->currentAnimation)
        d->currentAnimation->setDirection(direction);
}

/*!
    \reimp
*/
bool QSequentialAnimationGroup::event(QEvent *event)
{
    return QAnimationGroup::event(event);
}

void QSequentialAnimationGroupPrivate::setCurrentAnimation(int index, bool intermediate)
{
    Q_Q(QSequentialAnimationGroup);

    index = qMin(index, animations.count() - 1);

    if (index == -1) {
        Q_ASSERT(animations.isEmpty());
        currentAnimationIndex = -1;
        currentAnimation = 0;
        return;
    }

    // need these two checks below because this func can be called after the current animation
    // has been removed
    if (index == currentAnimationIndex && animations.at(index) == currentAnimation)
        return;

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

    currentAnimation = animations.at(index);
    currentAnimationIndex = index;

    emit q->currentAnimationChanged(currentAnimation);

    activateCurrentAnimation(intermediate);
}

void QSequentialAnimationGroupPrivate::activateCurrentAnimation(bool intermediate)
{
    if (!currentAnimation || state == QSequentialAnimationGroup::Stopped)
        return;

    currentAnimation->stop();

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

    // connects to the finish signal of uncontrolled animations
    if (currentAnimation->totalDuration() == -1)
        connectUncontrolledAnimation(currentAnimation);

    currentAnimation->start();
    if (!intermediate && state == QSequentialAnimationGroup::Paused)
        currentAnimation->pause();
}

void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished()
{
    Q_Q(QSequentialAnimationGroup);
    Q_ASSERT(qobject_cast<QAbstractAnimation *>(q->sender()) == currentAnimation);

    // we trust the duration returned by the animation
    while (actualDuration.size() < (currentAnimationIndex + 1))
        actualDuration.append(-1);
    actualDuration[currentAnimationIndex] = currentAnimation->currentTime();

    disconnectUncontrolledAnimation(currentAnimation);

    if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last())
        || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) {
        // we don't handle looping of a group with undefined duration
        q->stop();
    } else if (direction == QAbstractAnimation::Forward) {
        // set the current animation to be the next one
        setCurrentAnimation(currentAnimationIndex + 1);
    } else {
        // set the current animation to be the previous one
        setCurrentAnimation(currentAnimationIndex - 1);
    }
}

/*!
    \internal
    This method is called whenever an animation is added to
    the group at index \a index.
    Note: We only support insertion after the current animation
*/
void QSequentialAnimationGroupPrivate::animationInsertedAt(int index)
{
    if (currentAnimation == 0)
        setCurrentAnimation(0); // initialize the current animation

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

    //we update currentAnimationIndex in case it has changed (the animation pointer is still valid)
    currentAnimationIndex = animations.indexOf(currentAnimation);

    if (index < currentAnimationIndex || 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
    }
}

/*!
    \internal
    This method is called whenever an animation is removed from
    the group at index \a index. The animation is no more listed when this
    method is called.
*/
void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim)
{
    Q_Q(QSequentialAnimationGroup);
    QAnimationGroupPrivate::animationRemoved(index, anim);

    if (!currentAnimation)
        return;

    if (actualDuration.size() > index)
        actualDuration.removeAt(index);

    const int currentIndex = animations.indexOf(currentAnimation);
    if (currentIndex == -1) {
        //we're removing the current animation

        disconnectUncontrolledAnimation(currentAnimation);

        if (index < animations.count())
            setCurrentAnimation(index); //let's try to take the next one
        else if (index > 0)
            setCurrentAnimation(index - 1);
        else// case all animations were removed
            setCurrentAnimation(-1);
    } else if (currentAnimationIndex > index) {
        currentAnimationIndex--;
    }

    // duration of the previous animations up to the current animation
    currentTime = 0;
    for (int i = 0; i < currentAnimationIndex; ++i) {
        const int current = animationActualTotalDuration(i);
        currentTime += current;
    }

    if (currentIndex != -1) {
        //the current animation is not the one being removed
        //so we add its current time to the current time of this group
        currentTime += QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
    }

    //let's also update the total current time
    totalCurrentTime = currentTime + loopCount * q->duration();
}

QT_END_NAMESPACE

#include "moc_qsequentialanimationgroup.cpp"
