/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** 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 "qquicksmoothedanimation_p.h"
#include "qquicksmoothedanimation_p_p.h"

#include "qquickanimation_p_p.h"
#include "private/qcontinuinganimationgroupjob_p.h"

#include <qmath.h>
#include <qqmlproperty.h>
#include <private/qqmlproperty_p.h>

#include <private/qqmlglobal_p.h>

#include <QtCore/qdebug.h>


#define DELAY_STOP_TIMER_INTERVAL 32

QT_BEGIN_NAMESPACE


QSmoothedAnimationTimer::QSmoothedAnimationTimer(QSmoothedAnimation *animation, QObject *parent)
    : QTimer(parent)
    , m_animation(animation)
{
    connect(this, SIGNAL(timeout()), this, SLOT(stopAnimation()));
}

QSmoothedAnimationTimer::~QSmoothedAnimationTimer()
{
}

void QSmoothedAnimationTimer::stopAnimation()
{
    m_animation->stop();
}

QSmoothedAnimation::QSmoothedAnimation(QQuickSmoothedAnimationPrivate *priv)
    : QAbstractAnimationJob(), to(0), velocity(200), userDuration(-1), maximumEasingTime(-1),
      reversingMode(QQuickSmoothedAnimation::Eased), initialVelocity(0),
      trackVelocity(0), initialValue(0), invert(false), finalDuration(-1), lastTime(0),
      skipUpdate(false), delayedStopTimer(new QSmoothedAnimationTimer(this)), animationTemplate(priv)
{
    delayedStopTimer->setInterval(DELAY_STOP_TIMER_INTERVAL);
    delayedStopTimer->setSingleShot(true);
}

QSmoothedAnimation::~QSmoothedAnimation()
{
    delete delayedStopTimer;
    if (animationTemplate) {
        if (target.object()) {
            QHash<QQmlProperty, QSmoothedAnimation* >::iterator it =
                    animationTemplate->activeAnimations.find(target);
            if (it != animationTemplate->activeAnimations.end() && it.value() == this)
                animationTemplate->activeAnimations.erase(it);
        } else {
            //target is no longer valid, need to search linearly
            QHash<QQmlProperty, QSmoothedAnimation* >::iterator it;
            for (it = animationTemplate->activeAnimations.begin(); it != animationTemplate->activeAnimations.end(); ++it) {
                if (it.value() == this) {
                    animationTemplate->activeAnimations.erase(it);
                    break;
                }
            }
        }
    }
}

void QSmoothedAnimation::restart()
{
    initialVelocity = trackVelocity;
    if (isRunning())
        init();
    else
        start();
}

void QSmoothedAnimation::prepareForRestart()
{
    initialVelocity = trackVelocity;
    if (isRunning()) {
        //we are joining a new wrapper group while running, our times need to be restarted
        skipUpdate = true;
        init();
        lastTime = 0;
    } else {
        skipUpdate = false;
        //we'll be started when the group starts, which will force an init()
    }
}

void QSmoothedAnimation::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State /*oldState*/)
{
    if (newState == QAbstractAnimationJob::Running)
        init();
}

void QSmoothedAnimation::delayedStop()
{
    if (!delayedStopTimer->isActive())
        delayedStopTimer->start();
}

int QSmoothedAnimation::duration() const
{
    return -1;
}

bool QSmoothedAnimation::recalc()
{
    s = to - initialValue;
    vi = initialVelocity;

    s = (invert? -1.0: 1.0) * s;

    if (userDuration >= 0 && velocity > 0) {
        tf = s / velocity;
        if (tf > (userDuration / 1000.)) tf = (userDuration / 1000.);
    } else if (userDuration >= 0) {
        tf = userDuration / 1000.;
    } else if (velocity > 0) {
        tf = s / velocity;
    } else {
        return false;
    }

    finalDuration = qCeil(tf * 1000.0);

    if (maximumEasingTime == 0) {
        a = 0;
        d = 0;
        tp = 0;
        td = tf;
        vp = velocity;
        sp = 0;
        sd = s;
    } else if (maximumEasingTime != -1 && tf > (maximumEasingTime / 1000.)) {
        qreal met = maximumEasingTime / 1000.;
        /*       tp|       |td
         * vp_      _______
         *         /       \
         * vi_    /         \
         *                   \
         *                    \   _ 0
         *       |ta|      |ta|
         */
        qreal ta = met / 2.;
        a = (s - (vi * tf - 0.5 * vi * ta)) / (tf * ta - ta * ta);

        vp = vi + a * ta;
        d = vp / ta;
        tp = ta;
        sp = vi * ta + 0.5 * a * tp * tp;
        sd = sp + vp * (tf - 2 * ta);
        td = tf - ta;
    } else {
        qreal c1 = 0.25 * tf * tf;
        qreal c2 = 0.5 * vi * tf - s;
        qreal c3 = -0.25 * vi * vi;

        qreal a1 = (-c2 + qSqrt(c2 * c2 - 4 * c1 * c3)) / (2. * c1);

        qreal tp1 = 0.5 * tf - 0.5 * vi / a1;
        qreal vp1 = a1 * tp1 + vi;

        qreal sp1 = 0.5 * a1 * tp1 * tp1 + vi * tp1;

        a = a1;
        d = a1;
        tp = tp1;
        td = tp1;
        vp = vp1;
        sp = sp1;
        sd = sp1;
    }
    return true;
}

qreal QSmoothedAnimation::easeFollow(qreal time_seconds)
{
    qreal value;
    if (time_seconds < tp) {
        trackVelocity = vi + time_seconds * a;
        value = 0.5 * a * time_seconds * time_seconds + vi * time_seconds;
    } else if (time_seconds < td) {
        time_seconds -= tp;
        trackVelocity = vp;
        value = sp + time_seconds * vp;
    } else if (time_seconds < tf) {
        time_seconds -= td;
        trackVelocity = vp - time_seconds * a;
        value = sd - 0.5 * d * time_seconds * time_seconds + vp * time_seconds;
    } else {
        trackVelocity = 0;
        value = s;
        delayedStop();
    }

    // to normalize 's' between [0..1], divide 'value' by 's'
    return value;
}

void QSmoothedAnimation::updateCurrentTime(int t)
{
    if (skipUpdate) {
        skipUpdate = false;
        return;
    }

    if (!isRunning() && !isPaused()) // This can happen if init() stops the animation in some cases
        return;

    qreal time_seconds = qreal(t - lastTime) / 1000.;

    qreal value = easeFollow(time_seconds);
    value *= (invert? -1.0: 1.0);
    QQmlPropertyPrivate::write(target, initialValue + value,
                                       QQmlPropertyData::BypassInterceptor
                                       | QQmlPropertyData::DontRemoveBinding);
}

void QSmoothedAnimation::init()
{
    if (velocity == 0) {
        stop();
        return;
    }

    if (delayedStopTimer->isActive())
        delayedStopTimer->stop();

    initialValue = target.read().toReal();
    lastTime = this->currentTime();

    if (to == initialValue) {
        stop();
        return;
    }

    bool hasReversed = trackVelocity != 0. &&
                      ((!invert) == ((initialValue - to) > 0));

    if (hasReversed) {
        switch (reversingMode) {
            default:
            case QQuickSmoothedAnimation::Eased:
                initialVelocity = -trackVelocity;
                break;
            case QQuickSmoothedAnimation::Sync:
                QQmlPropertyPrivate::write(target, to,
                                                   QQmlPropertyData::BypassInterceptor
                                                   | QQmlPropertyData::DontRemoveBinding);
                trackVelocity = 0;
                stop();
                return;
            case QQuickSmoothedAnimation::Immediate:
                initialVelocity = 0;
                break;
        }
    }

    trackVelocity = initialVelocity;

    invert = (to < initialValue);

    if (!recalc()) {
        QQmlPropertyPrivate::write(target, to,
                                           QQmlPropertyData::BypassInterceptor
                                           | QQmlPropertyData::DontRemoveBinding);
        stop();
        return;
    }
}

void QSmoothedAnimation::debugAnimation(QDebug d) const
{
    d << "SmoothedAnimationJob(" << Qt::hex << (const void *) this << Qt::dec << ")" << "duration:" << userDuration
      << "velocity:" << velocity << "target:" << target.object() << "property:" << target.name()
      << "to:" << to << "current velocity:" << trackVelocity;
}

/*!
    \qmltype SmoothedAnimation
    \instantiates QQuickSmoothedAnimation
    \inqmlmodule QtQuick
    \ingroup qtquick-transitions-animations
    \inherits NumberAnimation
    \brief Allows a property to smoothly track a value.

    A SmoothedAnimation animates a property's value to a set target value
    using an ease in/out quad easing curve.  When the target value changes,
    the easing curves used to animate between the old and new target values
    are smoothly spliced together to create a smooth movement to the new
    target value that maintains the current velocity.

    The follow example shows one \l Rectangle tracking the position of another
    using SmoothedAnimation. The green rectangle's \c x and \c y values are
    bound to those of the red rectangle. Whenever these values change, the
    green rectangle smoothly animates to its new position:

    \snippet qml/smoothedanimation.qml 0

    A SmoothedAnimation can be configured by setting the \l velocity at which the
    animation should occur, or the \l duration that the animation should take.
    If both the \l velocity and \l duration are specified, the one that results in
    the quickest animation is chosen for each change in the target value.

    For example, animating from 0 to 800 will take 4 seconds if a velocity
    of 200 is set, will take 8 seconds with a duration of 8000 set, and will
    take 4 seconds with both a velocity of 200 and a duration of 8000 set.
    Animating from 0 to 20000 will take 10 seconds if a velocity of 200 is set,
    will take 8 seconds with a duration of 8000 set, and will take 8 seconds
    with both a velocity of 200 and a duration of 8000 set.

    The default velocity of SmoothedAnimation is 200 units/second.  Note that if the range of the
    value being animated is small, then the velocity will need to be adjusted
    appropriately.  For example, the opacity of an item ranges from 0 - 1.0.
    To enable a smooth animation in this range the velocity will need to be
    set to a value such as 0.5 units/second.  Animating from 0 to 1.0 with a velocity
    of 0.5 will take 2000 ms to complete.

    Like any other animation type, a SmoothedAnimation can be applied in a
    number of ways, including transitions, behaviors and property value
    sources. The \l {Animation and Transitions in Qt Quick} documentation shows a
    variety of methods for creating animations.

    \sa SpringAnimation, NumberAnimation, {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation}
*/

QQuickSmoothedAnimation::QQuickSmoothedAnimation(QObject *parent)
: QQuickNumberAnimation(*(new QQuickSmoothedAnimationPrivate), parent)
{
}

QQuickSmoothedAnimation::~QQuickSmoothedAnimation()
{

}

QQuickSmoothedAnimationPrivate::QQuickSmoothedAnimationPrivate()
    : anim(new QSmoothedAnimation)
{
}

QQuickSmoothedAnimationPrivate::~QQuickSmoothedAnimationPrivate()
{
    typedef QHash<QQmlProperty, QSmoothedAnimation* >::iterator ActiveAnimationsHashIt;

    delete anim;
    for (ActiveAnimationsHashIt it = activeAnimations.begin(), end = activeAnimations.end(); it != end; ++it)
        it.value()->clearTemplate();
}

void QQuickSmoothedAnimationPrivate::updateRunningAnimations()
{
    for (QSmoothedAnimation *ease : qAsConst(activeAnimations)) {
        ease->maximumEasingTime = anim->maximumEasingTime;
        ease->reversingMode = anim->reversingMode;
        ease->velocity = anim->velocity;
        ease->userDuration = anim->userDuration;
        ease->init();
    }
}

QAbstractAnimationJob* QQuickSmoothedAnimation::transition(QQuickStateActions &actions,
                                               QQmlProperties &modified,
                                               TransitionDirection direction,
                                               QObject *defaultTarget)
{
    Q_UNUSED(direction);
    Q_D(QQuickSmoothedAnimation);

    const QQuickStateActions dataActions = QQuickPropertyAnimation::createTransitionActions(actions, modified, defaultTarget);

    QContinuingAnimationGroupJob *wrapperGroup = new QContinuingAnimationGroupJob();

    if (!dataActions.isEmpty()) {
        QSet<QAbstractAnimationJob*> anims;
        for (int i = 0; i < dataActions.size(); i++) {
            QSmoothedAnimation *ease;
            bool isActive;
            if (!d->activeAnimations.contains(dataActions[i].property)) {
                ease = new QSmoothedAnimation(d);
                d->activeAnimations.insert(dataActions[i].property, ease);
                ease->target = dataActions[i].property;
                isActive = false;
            } else {
                ease = d->activeAnimations.value(dataActions[i].property);
                isActive = true;
            }
            wrapperGroup->appendAnimation(initInstance(ease));

            ease->to = dataActions[i].toValue.toReal();

            // copying public members from main value holder animation
            ease->maximumEasingTime = d->anim->maximumEasingTime;
            ease->reversingMode = d->anim->reversingMode;
            ease->velocity = d->anim->velocity;
            ease->userDuration = d->anim->userDuration;

            ease->initialVelocity = ease->trackVelocity;

            if (isActive)
                ease->prepareForRestart();
            anims.insert(ease);
        }

        const auto copy = d->activeAnimations;
        for (QSmoothedAnimation *ease : copy) {
            if (!anims.contains(ease)) {
                ease->clearTemplate();
                d->activeAnimations.remove(ease->target);
            }
        }
    }
    return wrapperGroup;
}

/*!
    \qmlproperty enumeration QtQuick::SmoothedAnimation::reversingMode

    Sets how the SmoothedAnimation behaves if an animation direction is reversed.

    Possible values are:

    \list
    \li SmoothedAnimation.Eased (default) - the animation will smoothly decelerate, and then reverse direction
    \li SmoothedAnimation.Immediate - the animation will immediately begin accelerating in the reverse direction, beginning with a velocity of 0
    \li SmoothedAnimation.Sync - the property is immediately set to the target value
    \endlist
*/
QQuickSmoothedAnimation::ReversingMode QQuickSmoothedAnimation::reversingMode() const
{
    Q_D(const QQuickSmoothedAnimation);
    return (QQuickSmoothedAnimation::ReversingMode) d->anim->reversingMode;
}

void QQuickSmoothedAnimation::setReversingMode(ReversingMode m)
{
    Q_D(QQuickSmoothedAnimation);
    if (d->anim->reversingMode == m)
        return;

    d->anim->reversingMode = m;
    emit reversingModeChanged();
    d->updateRunningAnimations();
}

/*!
    \qmlproperty int QtQuick::SmoothedAnimation::duration

    This property holds the animation duration, in msecs, used when tracking the source.

    Setting this to -1 (the default) disables the duration value.

    If the velocity value and the duration value are both enabled, then the animation will
    use whichever gives the shorter duration.
*/
int QQuickSmoothedAnimation::duration() const
{
    Q_D(const QQuickSmoothedAnimation);
    return d->anim->userDuration;
}

void QQuickSmoothedAnimation::setDuration(int duration)
{
    Q_D(QQuickSmoothedAnimation);
    if (duration != -1)
        QQuickNumberAnimation::setDuration(duration);
    if(duration == d->anim->userDuration)
        return;
    d->anim->userDuration = duration;
    d->updateRunningAnimations();
}

qreal QQuickSmoothedAnimation::velocity() const
{
    Q_D(const QQuickSmoothedAnimation);
    return d->anim->velocity;
}

/*!
    \qmlproperty real QtQuick::SmoothedAnimation::velocity

    This property holds the average velocity allowed when tracking the 'to' value.

    The default velocity of SmoothedAnimation is 200 units/second.

    Setting this to -1 disables the velocity value.

    If the velocity value and the duration value are both enabled, then the animation will
    use whichever gives the shorter duration.
*/
void QQuickSmoothedAnimation::setVelocity(qreal v)
{
    Q_D(QQuickSmoothedAnimation);
    if (d->anim->velocity == v)
        return;

    d->anim->velocity = v;
    emit velocityChanged();
    d->updateRunningAnimations();
}

/*!
    \qmlproperty int QtQuick::SmoothedAnimation::maximumEasingTime

    This property specifies the maximum time, in msecs, any "eases" during the follow should take.
    Setting this property causes the velocity to "level out" after at a time.  Setting
    a negative value reverts to the normal mode of easing over the entire animation
    duration.

    The default value is -1.
*/
int QQuickSmoothedAnimation::maximumEasingTime() const
{
    Q_D(const QQuickSmoothedAnimation);
    return d->anim->maximumEasingTime;
}

void QQuickSmoothedAnimation::setMaximumEasingTime(int v)
{
    Q_D(QQuickSmoothedAnimation);
    if(v == d->anim->maximumEasingTime)
        return;
    d->anim->maximumEasingTime = v;
    emit maximumEasingTimeChanged();
    d->updateRunningAnimations();
}

QT_END_NAMESPACE

#include "moc_qquicksmoothedanimation_p.cpp"
