/****************************************************************************
**
** Copyright (C) 2016 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 "qvertexblendanimation.h"

#include <private/qvertexblendanimation_p.h>

QT_BEGIN_NAMESPACE

namespace Qt3DAnimation {

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

    A Qt3DAnimation::QVertexBlendAnimation class implements vertex-blend morphing animation
    to a target \l {Qt3DRender::QGeometryRenderer}{QGeometryRenderer}. The QVertexBlendAnimation
    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. Unlike with QMorphingAnimation, where the blending is
    controller with blend weights, the blending occurs between sequential morph targets.
    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 VertexBlendAnimation
    \brief A type implementing vertex-blend morphing animation.
    \inqmlmodule Qt3D.Animation
    \since 5.9
    \inherits AbstractAnimation
    \instantiates Qt3DAnimation::QVertexBlendAnimation

    A VertexBlendAnimation type implements vertex-blend morphing animation
    to a target \l GeometryRenderer. The VertexBlendAnimation 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. Unlike with MorphingAnimation, where the blending is
    controller with blend weights, the blending occurs between sequential morph targets.
    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::QVertexBlendAnimation::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::QVertexBlendAnimation::interpolator
    Holds the interpolator between base and target attributes.
    \readonly
*/
/*!
    \property Qt3DAnimation::QVertexBlendAnimation::target
    Holds the target QGeometryRenderer the morphing animation is applied to.
*/
/*!
    \property Qt3DAnimation::QVertexBlendAnimation::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.
*/

/*!
    \qmlproperty list<real> VertexBlendAnimation::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 VertexBlendAnimation::interpolator
    Holds the interpolator between base and target attributes.
    \readonly
*/
/*!
    \qmlproperty GeometryRenderer VertexBlendAnimation::target
    Holds the target GeometryRenderer the morphing animation is applied to.
*/
/*!
    \qmlproperty string VertexBlendAnimation::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 list<MorphTarget> VertexBlendAnimation::morphTargets
    Holds the list of \l {MorphTarget}{morph targets} added to the animation.
*/

QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate()
    : QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation)
    , m_interpolator(0.0f)
    , m_target(nullptr)
    , m_currentBase(nullptr)
    , m_currentTarget(nullptr)
{

}

void QVertexBlendAnimationPrivate::getAttributesInPosition(float position, int *target0,
                                                           int *target1, float *interpolator)
{
    if (position < m_targetPositions.first()) {
        *target0 = 0;
        *target1 = qMin(1, m_targetPositions.size());
        *interpolator = 0.0f;
    } else if (position > m_targetPositions.last()) {
        *target0 = qMax(m_targetPositions.size() - 2, 0);
        *target1 = qMax(m_targetPositions.size() - 1, 0);
        *interpolator = 1.0f;
    } else {
        for (int i = 0; i < m_targetPositions.size() - 1; i++) {
            if (position >= m_targetPositions[i] && position < m_targetPositions[i + 1]) {
                *target0 = i;
                *target1 = i + 1;
                float a = (position - m_targetPositions[i])
                            / (m_targetPositions[i + 1] - m_targetPositions[i]);
                *interpolator = a;
            }
        }
    }
}

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

    Qt3DAnimation::QMorphTarget *base;
    Qt3DAnimation::QMorphTarget *target;
    int target0, target1;
    float interpolator;
    getAttributesInPosition(position, &target0, &target1, &interpolator);

    base = m_morphTargets.at(target0);
    target = m_morphTargets.at(target1);

    Qt3DRender::QGeometry *geometry = m_target->geometry();

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

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

    // add attributes from current frame to the geometry
    if (base != m_currentBase || target != m_currentTarget) {
        for (int i = 0; i < baseAttributes.size(); ++i) {
            const QString baseName = attributeNames.at(i);
            QString targetName = baseName;
            targetName.append(QLatin1String("Target"));

            baseAttributes[i]->setName(baseName);
            geometry->addAttribute(baseAttributes.at(i));
            targetAttributes[i]->setName(targetName);
            geometry->addAttribute(targetAttributes.at(i));
        }
    }
    m_currentBase = base;
    m_currentTarget = target;

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

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

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

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

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

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

/*!
    Set morph \a targets to animation. Old targets are cleared.
*/
void QVertexBlendAnimation::setMorphTargets(const QVector<Qt3DAnimation::QMorphTarget *> &targets)
{
    Q_D(QVertexBlendAnimation);
    d->m_morphTargets = targets;
}

/*!
    Add new morph \a target at the end of the animation.
*/
void QVertexBlendAnimation::addMorphTarget(Qt3DAnimation::QMorphTarget *target)
{
    Q_D(QVertexBlendAnimation);
    if (!d->m_morphTargets.contains(target))
        d->m_morphTargets.push_back(target);
}

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

void QVertexBlendAnimation::setTargetPositions(const QVector<float> &targetPositions)
{
    Q_D(QVertexBlendAnimation);
    if (d->m_targetPositions == targetPositions)
        return;
    d->m_targetPositions = targetPositions;
    emit targetPositionsChanged(targetPositions);
    setDuration(d->m_targetPositions.last());
}

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

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

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

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

} // Qt3DAnimation

QT_END_NAMESPACE
