/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Quick 3D.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) 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.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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "keyframegroupgenerator.h"

#include <QtQuick3DAssetImport/private/qssgqmlutilities_p.h>

#include "propertymap.h"

QT_BEGIN_NAMESPACE

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
// QTextStream functions are moved to a namespace in Qt6
using Qt::endl;
#endif

KeyframeGroupGenerator::KeyframeGroupGenerator(float fps)
    : m_fps(fps)
{
}

KeyframeGroupGenerator::~KeyframeGroupGenerator()
{
    for (auto keyframeGroupMap : m_targetKeyframeMap.values())
        for (auto keyframeGroup : keyframeGroupMap.values())
            delete keyframeGroup;
}

void KeyframeGroupGenerator::addAnimation(const AnimationTrack &animation)
{
    auto keyframeGroupMap = m_targetKeyframeMap.find(animation.m_target);
    QStringList propertyParts = animation.m_property.split(".");
    auto propertyType = KeyframeGroup::getPropertyValueType(animation.m_target->type(),
                                                            animation.m_property);
    QString property = propertyType == KeyframeGroup::KeyFrame::Unhandled
            ? propertyParts.at(0) : animation.m_property;
    QString field = QStringLiteral("x");
    if (propertyParts.count() > 1)
        field = propertyParts.last();

    if (keyframeGroupMap != m_targetKeyframeMap.end()) {
        // Check if the property name already exists in the keyframes
        auto keyframeGroup = keyframeGroupMap.value().find(property);
        if (keyframeGroup != keyframeGroupMap.value().end()) {
            auto keyframeGroupInstance = keyframeGroup.value();
            // verify the keyframe lists are the same size
            if (keyframeGroupInstance->keyframes.count() == animation.m_keyFrames.count()) {
                for (int i = 0; i < keyframeGroupInstance->keyframes.count(); ++i)
                    keyframeGroupInstance->keyframes[i]->setValue(animation.m_keyFrames[i].value, field);
            } else {
                qWarning() << "Keyframe lists are not the same size, bad things are going to happen";
            }
        } else {
            // if not then add a new property
            keyframeGroupMap.value().insert(property,
                                            new KeyframeGroup(animation, property, field, m_fps));
        }
    } else {
        // Add a new KeyframeGroupMap
        auto keyframeGroupMap = KeyframeGroupMap();
        keyframeGroupMap.insert(property, new KeyframeGroup(animation, property, field, m_fps));
        m_targetKeyframeMap.insert(animation.m_target, keyframeGroupMap);
    }
}

void KeyframeGroupGenerator::generateKeyframeGroups(QTextStream &output, int tabLevel)
{
    for (auto groupMaps : m_targetKeyframeMap.values())
        for (auto keyframeGroup : groupMaps.values())
            keyframeGroup->generateKeyframeGroupQml(output, tabLevel);
}

KeyframeGroupGenerator::KeyframeGroup::KeyFrame::KeyFrame(const AnimationTrack::KeyFrame &keyframe,
                                                          ValueType type, const QString &field,
                                                          float fps)
{
    valueType = type;
    frame = qRound(keyframe.time * fps);
    setValue(keyframe.value, field);
    c2time = keyframe.c2time;
    c2value = keyframe.c2value;
    c1time = keyframe.c1time;
    c1value = keyframe.c1value;
}

void KeyframeGroupGenerator::KeyframeGroup::KeyFrame::setValue(float newValue, const QString &field)
{
    if (valueType == ValueType::Float)
        value.setX(newValue);
    else if (field == QStringLiteral("x"))
        value.setX(newValue);
    else if (field == QStringLiteral("y"))
        value.setY(newValue);
    else if (field == QStringLiteral("z"))
        value.setZ(newValue);
    else if (field == QStringLiteral("w"))
        value.setW(newValue);
    else
        value.setX(newValue);
}

QString KeyframeGroupGenerator::KeyframeGroup::KeyFrame::valueToString() const
{
    if (valueType == ValueType::Float)
        return QString::number(double(value.x()));
    if (valueType == ValueType::Vector2D) {
        return QString(QStringLiteral("Qt.vector2d(") + QString::number(double(value.x())) +
                       QStringLiteral(", ") + QString::number(double(value.y())) +
                       QStringLiteral(")"));
    }
    if (valueType == ValueType::Vector3D) {
        return QString(QStringLiteral("Qt.vector3d(") + QString::number(double(value.x())) +
                       QStringLiteral(", ") + QString::number(double(value.y())) +
                       QStringLiteral(", ") + QString::number(double(value.z())) +
                       QStringLiteral(")"));
    }
    if (valueType == ValueType::Vector4D) {
        return QString(QStringLiteral("Qt.vector4d(") + QString::number(double(value.x())) +
                       QStringLiteral(", ") + QString::number(double(value.y())) +
                       QStringLiteral(", ") + QString::number(double(value.z())) +
                       QStringLiteral(", ") + QString::number(double(value.w())) +
                       QStringLiteral(")"));
    }
    if (valueType == ValueType::Color) {
        return QLatin1Char('\"')
                + QColor::fromRgbF(double(value.x()), double(value.y()),
                                   double(value.z()), double(value.w())).name(QColor::HexArgb)
                + QLatin1Char('\"');
    }
    Q_UNREACHABLE();
    return QString();
}

KeyframeGroupGenerator::KeyframeGroup::KeyframeGroup(const AnimationTrack &animation,
                                                     const QString &p, const QString &field,
                                                     float fps)
{
    type = KeyframeGroup::AnimationType(animation.m_type);
    target = animation.m_target;
    property = getQmlPropertyName(p); // convert to qml property
    isDynamic = animation.m_dynamic;
    for (const auto &keyframe : animation.m_keyFrames) {
        keyframes.append(new KeyFrame(keyframe, getPropertyValueType(target->type(), p),
                                      field, fps));
    }
}

KeyframeGroupGenerator::KeyframeGroup::~KeyframeGroup()
{
    for (auto keyframe : keyframes)
        delete keyframe;
}

void KeyframeGroupGenerator::KeyframeGroup::generateKeyframeGroupQml(QTextStream &output,
                                                                     int tabLevel) const
{
    output << endl;
    output << QSSGQmlUtilities::insertTabs(tabLevel) << QStringLiteral("KeyframeGroup {") << endl;
    output << QSSGQmlUtilities::insertTabs(tabLevel + 1) << QStringLiteral("target: ")
           << target->qmlId() << endl;
    output << QSSGQmlUtilities::insertTabs(tabLevel + 1) << QStringLiteral("property: ")
           << QStringLiteral("\"") << property << QStringLiteral("\"") <<  endl;

    for (auto keyframe : keyframes) {
        output << QSSGQmlUtilities::insertTabs(tabLevel + 1) << QStringLiteral("Keyframe {") << endl;
        output << QSSGQmlUtilities::insertTabs(tabLevel + 2) << QStringLiteral("frame: ")
               << keyframe->frame << endl;
        // special handling just for opacity value
        if (property == QLatin1String("opacity")) {
            output << QSSGQmlUtilities::insertTabs(tabLevel + 2) << QStringLiteral("value: ")
                   << QString::number(double(keyframe->value.x()) * 0.01) << endl;
        } else {
            output << QSSGQmlUtilities::insertTabs(tabLevel + 2) << QStringLiteral("value: ")
                   << keyframe->valueToString() << endl;
        }

        // ### Only linear supported at the moment, add support for EaseInOut and Bezier

        output << QSSGQmlUtilities::insertTabs(tabLevel + 1) << QStringLiteral("}") << endl;
    }

    output << QSSGQmlUtilities::insertTabs(tabLevel) << QStringLiteral("}") << endl;
}

KeyframeGroupGenerator::KeyframeGroup::KeyFrame::ValueType
KeyframeGroupGenerator::KeyframeGroup::getPropertyValueType(GraphObject::Type type,
                                                            const QString &propertyName)
{
    PropertyMap *propertyMap = PropertyMap::instance();
    const auto properties = propertyMap->propertiesForType(type);
    if (properties->contains(propertyName)) {
        switch (properties->value(propertyName).type) {
        case Q3DS::PropertyType::FloatRange:
        case Q3DS::PropertyType::LongRange:
        case Q3DS::PropertyType::Float:
        case Q3DS::PropertyType::Long:
        case Q3DS::PropertyType::FontSize:
            return KeyFrame::ValueType::Float;
        case Q3DS::PropertyType::Float2:
            return KeyFrame::ValueType::Vector2D;
        case Q3DS::PropertyType::Vector:
        case Q3DS::PropertyType::Scale:
        case Q3DS::PropertyType::Rotation:
            return KeyFrame::ValueType::Vector3D;
        case Q3DS::PropertyType::Color:
            return KeyFrame::ValueType::Color;
        default:
            return KeyFrame::ValueType::Unhandled;
        }
    }
    return KeyFrame::ValueType::Unhandled;
}

QString KeyframeGroupGenerator::KeyframeGroup::getQmlPropertyName(const QString &propertyName)
{
    PropertyMap *propertyMap = PropertyMap::instance();
    const auto properties = propertyMap->propertiesForType(target->type());
    if (properties->contains(propertyName)) {
        return properties->value(propertyName).name;
    }

    return propertyName;
}

QT_END_NAMESPACE
