/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmorphinganimation.h"
#include <private/qmorphinganimation_p.h>

QT_BEGIN_NAMESPACE

namespace Qt3DAnimation {

/*!
    \class Qt3DAnimation::QMorphingAnimation
    \brief A class implementing blend-shape morphing animation.
    \inmodule Qt3DAnimation
    \since 5.9
    \inherits Qt3DAnimation::QAbstractAnimation

    A Qt3DAnimation::QMorphingAnimation class implements blend-shape morphing animation
    to a target \l {Qt3DRender::QGeometryRenderer}{QGeometryRenderer}. The QMorphingAnimation
    sets the correct \l {Qt3DRender::QAttribute}{QAttributes} from the
    \l {Qt3DAnimation::QMorphTarget}{morph targets} to the target
    \l {Qt3DRender::QGeometryRenderer::geometry} {QGeometryRenderer::geometry} and calculates
    interpolator for the current position. The actual blending between the attributes must
    be implemented in the material. Qt3DAnimation::QMorphPhongMaterial implements material
    with morphing support for phong lighting model. The blending happens between
    2 attributes - 'base' and 'target'. The names for the base and target attributes are taken from
    the morph target names, where the base attribute retains the name it already has and the
    target attribute name gets 'Target' appended to the name. The interpolator can be
    set as a \l {Qt3DRender::QParameter}{QParameter} to the used material.
    All morph targets in the animation should contain the attributes with same names as those
    in the base geometry.

*/
/*!
    \qmltype MorphingAnimation
    \brief A type implementing blend-shape morphing animation.
    \inqmlmodule Qt3D.Animation
    \since 5.9
    \inherits AbstractAnimation
    \instantiates Qt3DAnimation::QMorphingAnimation

    A MorphingAnimation type implements blend-shape morphing animation
    to a target \l GeometryRenderer. The MorphingAnimation sets the correct
    \l {Attribute}{Attributes} from the morph targets to the target
    \l {Qt3D.Render::GeometryRenderer::geometry}{GeometryRenderer::geometry} and calculates
    interpolator for the current position. The actual blending between the attributes must
    be implemented in the material. MorphPhongMaterial implements material
    with morphing support for phong lighting model. The blending happens between
    2 attributes - 'base' and 'target'. The names for the base and target attributes are taken from
    the morph target names, where the base attribute retains the name it already has and the
    target attribute name gets 'Target' appended to the name. All morph targets in the animation
    should contain the attributes with same names as those in the base geometry.

*/
/*!
    \property Qt3DAnimation::QMorphingAnimation::targetPositions
    Holds the position values of the morph target. Each position in the list specifies the position
    of the corresponding morph target with the same index. The values must be in an ascending order.
    Values can be positive or negative and do not have any predefined unit.
*/
/*!
    \property Qt3DAnimation::QMorphingAnimation::interpolator
    Holds the interpolator between base and target attributes.
    \readonly
*/
/*!
    \property Qt3DAnimation::QMorphingAnimation::target
    Holds the target QGeometryRenderer the morphing animation is applied to.
*/
/*!
    \property Qt3DAnimation::QMorphingAnimation::targetName
    Holds the name of the target geometry. This is a convenience property making it
    easier to match the target geometry to the morphing animation. The name
    is usually same as the name of the parent entity of the target QGeometryRenderer, but
    does not have to be.
*/
/*!
    \property Qt3DAnimation::QMorphingAnimation::method
    Holds the morphing method. The default is Relative.
*/
/*!
    \property Qt3DAnimation::QMorphingAnimation::easing
    Holds the easing curve of the interpolator between morph targets.
*/
/*!
    \enum Qt3DAnimation::QMorphingAnimation::Method

    This enumeration specifies the morphing method.
    \value Normalized The blending should use the normalized formula;
                      V' = Vbase * (1.0 - sum(Wi)) + sum[Vi * Wi]
    \value Relative The blending should use the relative formula;
                      V' = Vbase + sum[Vi * Wi]
*/

/*!
    \qmlproperty list<real> MorphingAnimation::targetPositions
    Holds the position values of the morph target. Each position in the list specifies the position
    of the corresponding morph target with the same index. The values must be in an ascending order.
    Values can be positive or negative and do not have any predefined unit.
*/
/*!
    \qmlproperty real MorphingAnimation::interpolator
    Holds the interpolator between base and target attributes.
    \readonly
*/
/*!
    \qmlproperty GeometryRenderer MorphingAnimation::target
    Holds the target GeometryRenderer the morphing animation is applied to.
*/
/*!
    \qmlproperty string MorphingAnimation::targetName
    Holds the name of the target geometry. This is a convenience property making it
    easier to match the target geometry to the morphing animation. The name
    is usually same as the name of the parent entity of the target GeometryRenderer, but
    does not have to be.
*/
/*!
    \qmlproperty enumeration MorphingAnimation::method
    Holds the morphing method.  The default is Relative.
    \list
    \li Normalized
    \li Relative
    \endlist
*/
/*!
    \qmlproperty EasingCurve MorphingAnimation::easing
    Holds the easing curve of the interpolator between morph targets.
*/
/*!
    \qmlproperty list<MorphTarget> MorphingAnimation::morphTargets
    Holds the list of morph targets in the morphing animation.
*/

QMorphingAnimationPrivate::QMorphingAnimationPrivate()
    : QAbstractAnimationPrivate(QAbstractAnimation::MorphingAnimation)
    , m_minposition(0.0f)
    , m_maxposition(0.0f)
    , m_flattened(nullptr)
    , m_method(QMorphingAnimation::Relative)
    , m_interpolator(0.0f)
    , m_target(nullptr)
    , m_currentTarget(nullptr)
{

}

QMorphingAnimationPrivate::~QMorphingAnimationPrivate()
{
    for (QVector<float> *weights : qAsConst(m_weights))
        delete weights;
}

void QMorphingAnimationPrivate::updateAnimation(float position)
{
    Q_Q(QMorphingAnimation);
    if (!m_target || !m_target->geometry())
        return;

    QVector<int> relevantValues;
    float sum = 0.0f;
    float interpolator = 0.0f;
    m_morphKey.resize(m_morphTargets.size());

    // calculate morph key
    if (position < m_minposition) {
        m_morphKey = *m_weights.first();
    } else if (position >= m_maxposition) {
        m_morphKey = *m_weights.last();
    } else {
        for (int i = 0; i < m_targetPositions.size() - 1; ++i) {
            if (position >= m_targetPositions.at(i) && position < m_targetPositions.at(i + 1)) {
                interpolator = (position - m_targetPositions.at(i))
                        / (m_targetPositions.at(i + 1) - m_targetPositions.at(i));
                interpolator = m_easing.valueForProgress(interpolator);
                float iip = 1.0f - interpolator;

                for (int j = 0; j < m_morphTargets.size(); ++j) {
                    m_morphKey[j] = interpolator * m_weights.at(i + 1)->at(j)
                                        + iip * m_weights.at(i)->at(j);
                }
            }
        }
    }

    // check relevant values
    for (int j = 0; j < m_morphKey.size(); ++j) {
        sum += m_morphKey[j];
        if (!qFuzzyIsNull(m_morphKey[j]))
            relevantValues.push_back(j);
    }

    if (relevantValues.size() == 0 || qFuzzyIsNull(sum)) {
        // only base is used
        interpolator = 0.0f;
    } else if (relevantValues.size() == 1) {
        // one morph target has non-zero weight
        setTargetInterpolated(relevantValues[0]);
        interpolator = sum;
    } else {
        // more than one morph target has non-zero weight
        // flatten morph targets to one
        qWarning() << Q_FUNC_INFO << "Flattening required";
    }

    // Relative method uses negative interpolator, normalized uses positive
    if (m_method == QMorphingAnimation::Relative)
        interpolator = -interpolator;

    if (!qFuzzyCompare(interpolator, m_interpolator)) {
        m_interpolator = interpolator;
        emit q->interpolatorChanged(m_interpolator);
    }
}

void QMorphingAnimationPrivate::setTargetInterpolated(int morphTarget)
{
    QMorphTarget *target = m_morphTargets[morphTarget];
    Qt3DRender::QGeometry *geometry = m_target->geometry();

    // remove attributes from previous frame
    if (m_currentTarget && (target != m_currentTarget)) {
        const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList();
        for (int i = 0; i < targetAttributes.size(); ++i)
            geometry->removeAttribute(targetAttributes.at(i));
    }

    const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList();

    // add attributes from current frame to the geometry
    if (target != m_currentTarget) {
        for (int i = 0; i < m_attributeNames.size(); ++i) {
            QString targetName = m_attributeNames.at(i);
            targetName.append(QLatin1String("Target"));
            targetAttributes[i]->setName(targetName);
            geometry->addAttribute(targetAttributes.at(i));
        }
    }
    m_currentTarget = target;
}

/*!
    Construct a new QMorphingAnimation with \a parent.
 */
QMorphingAnimation::QMorphingAnimation(QObject *parent)
    : QAbstractAnimation(*new QMorphingAnimationPrivate, parent)
{
    Q_D(QMorphingAnimation);
    d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged,
                                               this, &QMorphingAnimation::updateAnimation);
}

QVector<float> QMorphingAnimation::targetPositions() const
{
    Q_D(const QMorphingAnimation);
    return d->m_targetPositions;
}

float QMorphingAnimation::interpolator() const
{
    Q_D(const QMorphingAnimation);
    return d->m_interpolator;
}

Qt3DRender::QGeometryRenderer *QMorphingAnimation::target() const
{
    Q_D(const QMorphingAnimation);
    return d->m_target;
}

QString QMorphingAnimation::targetName() const
{
    Q_D(const QMorphingAnimation);
    return d->m_targetName;
}

QMorphingAnimation::Method QMorphingAnimation::method() const
{
    Q_D(const QMorphingAnimation);
    return d->m_method;
}

QEasingCurve QMorphingAnimation::easing() const
{
    Q_D(const QMorphingAnimation);
    return d->m_easing;
}

/*!
    Set morph \a targets to animation. Old targets are cleared.
*/
void QMorphingAnimation::setMorphTargets(const QVector<Qt3DAnimation::QMorphTarget *> &targets)
{
    Q_D(QMorphingAnimation);
    d->m_morphTargets = targets;
    d->m_attributeNames = targets[0]->attributeNames();
    d->m_position = -1.0f;
}

/*!
    Add new morph \a target at the end of the animation.
*/
void QMorphingAnimation::addMorphTarget(Qt3DAnimation::QMorphTarget *target)
{
    Q_D(QMorphingAnimation);
    if (!d->m_morphTargets.contains(target)) {
        d->m_morphTargets.push_back(target);
        d->m_position = -1.0f;
        if (d->m_attributeNames.empty())
            d->m_attributeNames = target->attributeNames();
    }
}

/*!
    Remove morph \a target from the animation.
*/
void QMorphingAnimation::removeMorphTarget(Qt3DAnimation::QMorphTarget *target)
{
    Q_D(QMorphingAnimation);
    d->m_morphTargets.removeAll(target);
    d->m_position = -1.0f;
}

void QMorphingAnimation::setTargetPositions(const QVector<float> &targetPositions)
{
    Q_D(QMorphingAnimation);
    d->m_targetPositions = targetPositions;
    emit targetPositionsChanged(targetPositions);
    d->m_minposition = targetPositions.first();
    d->m_maxposition = targetPositions.last();
    setDuration(d->m_targetPositions.last());
    if (d->m_weights.size() < targetPositions.size()) {
        d->m_weights.resize(targetPositions.size());
        for (int i = 0; i < d->m_weights.size(); ++i) {
            if (d->m_weights[i] == nullptr)
                d->m_weights[i] = new QVector<float>();
        }
    }
    d->m_position = -1.0f;
}

void QMorphingAnimation::setTarget(Qt3DRender::QGeometryRenderer *target)
{
    Q_D(QMorphingAnimation);
    if (d->m_target != target) {
        d->m_position = -1.0f;
        d->m_target = target;
        emit targetChanged(target);
    }
}

/*!
    Sets morph \a weights at \a positionIndex.
*/
void QMorphingAnimation::setWeights(int positionIndex, const QVector<float> &weights)
{
    Q_D(QMorphingAnimation);
    if (d->m_weights.size() < positionIndex)
        d->m_weights.resize(positionIndex + 1);
    if (d->m_weights[positionIndex] == nullptr)
        d->m_weights[positionIndex] = new QVector<float>();
    *d->m_weights[positionIndex] = weights;
    d->m_position = -1.0f;
}

/*!
    Return morph weights at \a positionIndex.
*/
QVector<float> QMorphingAnimation::getWeights(int positionIndex)
{
    Q_D(QMorphingAnimation);
    return *d->m_weights[positionIndex];
}

/*!
    Return morph target list.
*/
QVector<Qt3DAnimation::QMorphTarget *> QMorphingAnimation::morphTargetList()
{
    Q_D(QMorphingAnimation);
    return d->m_morphTargets;
}

void QMorphingAnimation::setTargetName(const QString name)
{
    Q_D(QMorphingAnimation);
    if (d->m_targetName != name) {
        d->m_targetName = name;
        emit targetNameChanged(name);
    }
}

void QMorphingAnimation::setMethod(QMorphingAnimation::Method method)
{
    Q_D(QMorphingAnimation);
    if (d->m_method != method) {
        d->m_method = method;
        d->m_position = -1.0f;
        emit methodChanged(method);
    }
}

void QMorphingAnimation::setEasing(const QEasingCurve &easing)
{
    Q_D(QMorphingAnimation);
    if (d->m_easing != easing) {
        d->m_easing = easing;
        d->m_position = -1.0f;
        emit easingChanged(easing);
    }
}

void QMorphingAnimation::updateAnimation(float position)
{
    Q_D(QMorphingAnimation);
    d->updateAnimation(position);
}

} // Qt3DAnimation

QT_END_NAMESPACE
