/****************************************************************************
**
** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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 <QtTest/QTest>
#include <QObject>
#include <Qt3DExtras/qtorusgeometry.h>
#include <Qt3DRender/qattribute.h>
#include <Qt3DRender/qbuffer.h>
#include <Qt3DRender/qbufferdatagenerator.h>
#include <qopenglcontext.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qvector4d.h>
#include <QtCore/qdebug.h>
#include <QtCore/qsharedpointer.h>
#include <QSignalSpy>
#include <qmath.h>

#include "geometrytesthelper.h"

class tst_QTorusGeometry : public QObject
{
    Q_OBJECT
private Q_SLOTS:
    void defaultConstruction()
    {
        // WHEN
        Qt3DExtras::QTorusGeometry geometry;

        // THEN
        QCOMPARE(geometry.rings(), 16);
        QCOMPARE(geometry.slices(), 16);
        QCOMPARE(geometry.radius(), 1.0f);
        QCOMPARE(geometry.minorRadius(), 1.0f);
        QVERIFY(geometry.positionAttribute() != nullptr);
        QCOMPARE(geometry.positionAttribute()->name(), Qt3DRender::QAttribute::defaultPositionAttributeName());
        QVERIFY(geometry.normalAttribute() != nullptr);
        QCOMPARE(geometry.normalAttribute()->name(), Qt3DRender::QAttribute::defaultNormalAttributeName());
        QVERIFY(geometry.texCoordAttribute() != nullptr);
        QCOMPARE(geometry.texCoordAttribute()->name(), Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName());
        // TODO: Expose tangent attribute in Qt 5.8 and see below
//        QVERIFY(geometry.tangentAttribute() != nullptr);
//        QCOMPARE(geometry.tangentAttribute()->name(), Qt3DRender::QAttribute::defaultTangentAttributeName());
        QVERIFY(geometry.indexAttribute() != nullptr);
    }

    void properties()
    {
        // GIVEN
        Qt3DExtras::QTorusGeometry geometry;

        {
            // WHEN
            QSignalSpy spy(&geometry, SIGNAL(ringsChanged(int)));
            const int newValue = 20;
            geometry.setRings(newValue);

            // THEN
            QCOMPARE(geometry.rings(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            geometry.setRings(newValue);

            // THEN
            QCOMPARE(geometry.rings(), newValue);
            QCOMPARE(spy.count(), 0);
        }

        {
            // WHEN
            QSignalSpy spy(&geometry, SIGNAL(slicesChanged(int)));
            const int newValue = 2.0f;
            geometry.setSlices(newValue);

            // THEN
            QCOMPARE(geometry.slices(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            geometry.setSlices(newValue);

            // THEN
            QCOMPARE(geometry.slices(), newValue);
            QCOMPARE(spy.count(), 0);
        }

        {
            // WHEN
            QSignalSpy spy(&geometry, SIGNAL(radiusChanged(float)));
            const float newValue = 2.0f;
            geometry.setRadius(newValue);

            // THEN
            QCOMPARE(geometry.radius(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            geometry.setRadius(newValue);

            // THEN
            QCOMPARE(geometry.radius(), newValue);
            QCOMPARE(spy.count(), 0);
        }

        {
            // WHEN
            QSignalSpy spy(&geometry, SIGNAL(minorRadiusChanged(float)));
            const float newValue = 0.25f;
            geometry.setMinorRadius(newValue);

            // THEN
            QCOMPARE(geometry.minorRadius(), newValue);
            QCOMPARE(spy.count(), 1);

            // WHEN
            spy.clear();
            geometry.setMinorRadius(newValue);

            // THEN
            QCOMPARE(geometry.minorRadius(), newValue);
            QCOMPARE(spy.count(), 0);
        }
    }

    void generatedGeometryShouldBeConsistent_data()
    {
        QTest::addColumn<int>("rings");
        QTest::addColumn<int>("slices");
        QTest::addColumn<float>("radius");
        QTest::addColumn<float>("minorRadius");
        QTest::addColumn<int>("triangleIndex");
        QTest::addColumn<QVector<quint16>>("indices");
        QTest::addColumn<QVector<QVector3D>>("positions");
        QTest::addColumn<QVector<QVector3D>>("normals");
        QTest::addColumn<QVector<QVector2D>>("texCoords");
        QTest::addColumn<QVector<QVector4D>>("tangents");

        {
            // Torus properties
            const int rings = 8;
            const int slices = 8;
            const float radius = 2.0f;
            const float minorRadius = 0.5f;

            // Angular factors for the vertices:
            // u iterates around the major radius
            // v iterates around the minor radius (around each ring)
            const float du = float(2.0 * M_PI / rings);
            const float dv = float(2.0 * M_PI / slices);
            const float u0 = 0.0f;
            const float u1 = du;
            const float v0 = 0.0f;
            const float v1 = dv;

            const float cosu0 = float(qCos(u0));
            const float sinu0 = float(qSin(u0));
            const float cosu1 = float(qCos(u1));
            const float sinu1 = float(qSin(u1));

            const float cosv0 = float(qCos(v0 + M_PI)); // Seam is on inner edge
            const float sinv0 = float(qSin(v0));
            const float cosv1 = float(qCos(v1 + M_PI));
            const float sinv1 = float(qSin(v1));

            // The triangle and indices
            const int triangleIndex = 0;
            const auto indices = (QVector<quint16>() << 0 << 1 << 9);

            // Calculate attributes for vertices A, B, and C of the triangle
            const float rA = radius + minorRadius * cosv0;
            const float rB = radius + minorRadius * cosv1;
            const float rC = radius + minorRadius * cosv0;

            const auto posA = QVector3D(rA * cosu0, rA * sinu0, minorRadius * sinv0);
            const auto posB = QVector3D(rB * cosu0, rB * sinu0, minorRadius * sinv1);
            const auto posC = QVector3D(rC * cosu1, rC * sinu1, minorRadius * sinv0);
            const auto positions = (QVector<QVector3D>() << posA << posB << posC);

            const auto nA = QVector3D(cosv0 * cosu0, cosv0 * sinu0, sinv0).normalized();
            const auto nB = QVector3D(cosv1 * cosu0, cosv1 * sinu0, sinv1).normalized();
            const auto nC = QVector3D(cosv0 * cosu1, cosv0 * sinu1, sinv0).normalized();
            const auto normals = (QVector<QVector3D>() << nA << nB << nC);

            const auto tcA = QVector2D(u0, v0) / float(2.0 * M_PI);
            const auto tcB = QVector2D(u0, v1) / float(2.0 * M_PI);
            const auto tcC = QVector2D(u1, v0) / float(2.0 * M_PI);
            const auto texCoords = (QVector<QVector2D>() << tcA << tcB << tcC);

            const auto tA = QVector4D(-sinu0, cosu0, 0.0f, 1.0f);
            const auto tB = QVector4D(-sinu0, cosu0, 0.0f, 1.0f);
            const auto tC = QVector4D(-sinu1, cosu1, 0.0f, 1.0f);
            const auto tangents = (QVector<QVector4D>() << tA << tB << tC);

            // Add the row
            QTest::newRow("8rings_8slices_firstTriangle")
                    << rings << slices << radius << minorRadius
                    << triangleIndex
                    << indices << positions << normals << texCoords << tangents;
        }

        {
            // Note: The vertices used in this test case are different than the
            // ones above. So, we cannot abstract this into a function easily.
            // Here we use the 2nd triangle in a rectangular face, the test above
            // uses the first triangle in the rectangular face.

            // Torus properties
            const int rings = 8;
            const int slices = 8;
            const float radius = 2.0f;
            const float minorRadius = 0.5f;

            // Angular factors for the vertices:
            // u iterates around the major radius
            // v iterates around the minor radius (around each ring)
            const float du = float(2.0 * M_PI / rings);
            const float dv = float(2.0 * M_PI / slices);
            const float u0 = 7.0f * du;
            const float u1 = float(2.0 * M_PI);
            const float v0 = 7.0f * dv;
            const float v1 = float(2.0 * M_PI);

            const float cosu0 = float(qCos(u0));
            const float sinu0 = float(qSin(u0));
            const float cosu1 = float(qCos(u1));
            const float sinu1 = float(qSin(u1));

            const float cosv0 = float(qCos(v0 + M_PI)); // Seam is on inner edge
            const float sinv0 = float(qSin(v0));
            const float cosv1 = float(qCos(v1 + M_PI));
            const float sinv1 = float(qSin(v1));

            // The triangle and indices
            const int triangleIndex = 127;
            const auto indices = (QVector<quint16>() << 71 << 80 << 79);

            // Calculate attributes for vertices A, B, and C of the triangle
            const float rA = radius + minorRadius * cosv1;
            const float rB = radius + minorRadius * cosv1;
            const float rC = radius + minorRadius * cosv0;

            const auto posA = QVector3D(rA * cosu0, rA * sinu0, minorRadius * sinv1);
            const auto posB = QVector3D(rB * cosu1, rB * sinu1, minorRadius * sinv1);
            const auto posC = QVector3D(rC * cosu1, rC * sinu1, minorRadius * sinv0);
            const auto positions = (QVector<QVector3D>() << posA << posB << posC);

            const auto nA = QVector3D(cosv1 * cosu0, cosv1 * sinu0, sinv1).normalized();
            const auto nB = QVector3D(cosv1 * cosu1, cosv1 * sinu1, sinv1).normalized();
            const auto nC = QVector3D(cosv0 * cosu1, cosv0 * sinu1, sinv0).normalized();
            const auto normals = (QVector<QVector3D>() << nA << nB << nC);

            const auto tcA = QVector2D(u0, v1) / float(2.0 * M_PI);
            const auto tcB = QVector2D(u1, v1) / float(2.0 * M_PI);
            const auto tcC = QVector2D(u1, v0) / float(2.0 * M_PI);
            const auto texCoords = (QVector<QVector2D>() << tcA << tcB << tcC);

            const auto tA = QVector4D(-sinu0, cosu1, 0.0f, 1.0f);
            const auto tB = QVector4D(-sinu1, cosu1, 0.0f, 1.0f);
            const auto tC = QVector4D(-sinu1, cosu1, 0.0f, 1.0f);
            const auto tangents = (QVector<QVector4D>() << tA << tB << tC);

            // Add the row
            QTest::newRow("8rings_8slices_lastTriangle")
                    << rings << slices << radius << minorRadius
                    << triangleIndex
                    << indices << positions << normals << texCoords << tangents;
        }
    }

    void generatedGeometryShouldBeConsistent()
    {
        // GIVEN
        Qt3DExtras::QTorusGeometry geometry;
        const QVector<Qt3DRender::QAttribute *> attributes = geometry.attributes();
        Qt3DRender::QAttribute *positionAttribute = geometry.positionAttribute();
        Qt3DRender::QAttribute *normalAttribute = geometry.normalAttribute();
        Qt3DRender::QAttribute *texCoordAttribute = geometry.texCoordAttribute();
//        Qt3DRender::QAttribute *tangentAttribute = geometry.tangentAttribute();
        Qt3DRender::QAttribute *indexAttribute = geometry.indexAttribute();

        // WHEN
        QFETCH(int, rings);
        QFETCH(int, slices);
        QFETCH(float, radius);
        QFETCH(float, minorRadius);
        geometry.setRings(rings);
        geometry.setSlices(slices);
        geometry.setRadius(radius);
        geometry.setMinorRadius(minorRadius);

        generateGeometry(geometry);

        // THEN

        // Check buffer of each attribute is valid and actually has some data
        for (const auto &attribute : attributes) {
            Qt3DRender::QBuffer *buffer = attribute->buffer();
            QVERIFY(buffer != nullptr);
            QVERIFY(buffer->data().size() != 0);
        }

        // Check some data in the buffers

        // Check specific indices and vertex attributes of triangle under test
        QFETCH(int, triangleIndex);
        QFETCH(QVector<quint16>, indices);
        QFETCH(QVector<QVector3D>, positions);
        QFETCH(QVector<QVector3D>, normals);
        QFETCH(QVector<QVector2D>, texCoords);
//        QFETCH(QVector<QVector4D>, tangents);

        int i = 0;
        for (auto index : indices) {
            const auto testIndex = extractIndexData<quint16>(indexAttribute, 3 * triangleIndex + i);
            QCOMPARE(testIndex, indices.at(i));

            const auto position = extractVertexData<QVector3D, quint32>(positionAttribute, index);
            QVERIFY(qFuzzyCompare(position, positions.at(i)));

            const auto normal = extractVertexData<QVector3D, quint32>(normalAttribute, index);
            QVERIFY(qFuzzyCompare(normal, normals.at(i)));

            const auto texCoord = extractVertexData<QVector2D, quint32>(texCoordAttribute, index);
            QVERIFY(qFuzzyCompare(texCoord, texCoords.at(i)));

//            const auto tangent = extractVertexData<QVector4D, quint32>(tangentAttribute, index);
//            QVERIFY(qFuzzyCompare(tangent, tangents.at(i)));

            ++i;
        }
    }
};


QTEST_APPLESS_MAIN(tst_QTorusGeometry)

#include "tst_qtorusgeometry.moc"
