/****************************************************************************
**
** 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/QtTest>
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/qraycastingservice_p.h>
#include <Qt3DRender/private/sphere_p.h>
#include <Qt3DRender/private/entity_p.h>
#include <Qt3DRender/private/abstractpickingjob_p.h>
#include <Qt3DRender/private/qboundingvolumeprovider_p.h>
#include <Qt3DRender/private/qray3d_p.h>
#include <Qt3DRender/qcamera.h>

using namespace Qt3DCore;
using namespace Qt3DRender;
using namespace Qt3DRender::Render;
using namespace Qt3DRender::RayCasting;

class tst_RayCasting : public QObject
{
    Q_OBJECT
public:
    tst_RayCasting() {}
    ~tst_RayCasting() {}

private Q_SLOTS:
    void shouldReturnValidHandle();
    void shouldReturnResultForEachHandle();
    void shouldReturnAllResults();
    void shouldReturnHits();
    void shouldReturnHits_data();
    void shouldIntersect_data();
    void shouldIntersect();
    void shouldUseProvidedBoudingVolumes();
    void mousePicking();

    void cleanupTestCase();

private:
    Sphere *volumeAt(int index);
    QVector<Sphere> boundingVolumes;
};

void tst_RayCasting::shouldIntersect_data()
{
    QTest::addColumn<QRay3D>("ray");
    QTest::addColumn<Sphere>("sphere");
    QTest::addColumn<bool>("shouldIntersect");

    QRay3D ray(Vector3D(1, 1, 1), Vector3D(0, 0, 1));

    Sphere sphere1(Vector3D(1, 1, 1), 2);
    Sphere sphere2(Vector3D(0, 0, 0), 3);
    Sphere sphere3(Vector3D(0, 1, 3), 1);
    Sphere sphere4(Vector3D(4, 4, 5), 1);
    Sphere sphere5(Vector3D(2, 2, 11), 5);
    Sphere sphere6(Vector3D(2, 2, 13), 1);
    Sphere sphere7(Vector3D(2, 2, 15), 5);

    QTest::newRow("Ray starts inside sphere") << ray << sphere1 << true;
    QTest::newRow("Ray starts inside sphere") << ray << sphere2 << true;
    QTest::newRow("Ray intersects sphere tangentially") << ray << sphere3 << true;
    QTest::newRow("No intersection") << ray << sphere4 << false;
    QTest::newRow("Ray intersect sphere") << ray << sphere5 << true;
    QTest::newRow("No intersection") << ray << sphere6 << false;
    QTest::newRow("Ray intersect sphere") << ray << sphere7 << true;
}

void tst_RayCasting::shouldIntersect()
{
    QFETCH(QRay3D, ray);
    QFETCH(Sphere, sphere);
    QFETCH(bool, shouldIntersect);

    Vector3D intersectionPoint;

    QCOMPARE(sphere.intersects(ray, &intersectionPoint), shouldIntersect);
}

class MyBoudingVolumesProvider : public QBoundingVolumeProvider
{
public:
    MyBoudingVolumesProvider(QVector<QBoundingVolume *> volumes)
        : m_volumes(volumes)
    {}

    QVector<QBoundingVolume *> boundingVolumes() const
    {
        return m_volumes;
    }

private:
    QVector<QBoundingVolume *> m_volumes;
};

void tst_RayCasting::shouldReturnValidHandle()
{
    // GIVEN
    QRay3D ray;
    Sphere v1;
    MyBoudingVolumesProvider provider = QVector<QBoundingVolume *>() << &v1;

    QRayCastingService service;

    // WHEN
    QQueryHandle handle = service.query(ray,
                                        QAbstractCollisionQueryService::AllHits,
                                        &provider);

    // THEN
    QVERIFY(handle >= 0);

    // Wait the query to finish
    service.fetchResult(handle);
}

void tst_RayCasting::shouldReturnResultForEachHandle()
{
    // GIVEN
    QRay3D ray;
    QVector<QBoundingVolume *> volumes;
    MyBoudingVolumesProvider provider(volumes);

    QRayCastingService service;

    QQueryHandle handle1 = service.query(ray,
                                         QAbstractCollisionQueryService::AllHits,
                                         &provider);
    QQueryHandle handle2 = service.query(ray,
                                         QAbstractCollisionQueryService::FirstHit,
                                         &provider);

    // WHEN
    QCollisionQueryResult result2 = service.fetchResult(handle2);
    QCollisionQueryResult result1 = service.fetchResult(handle1);

    // THEN
    QCOMPARE(result1.handle(), handle1);
    QCOMPARE(result2.handle(), handle2);
}

void tst_RayCasting::shouldReturnAllResults()
{
    // GIVEN
    QRay3D ray;
    QVector<QBoundingVolume *> volumes;
    MyBoudingVolumesProvider provider(volumes);

    QRayCastingService service;

    QVector<QQueryHandle> handles;
    handles.append(service.query(ray,
                                 QAbstractCollisionQueryService::AllHits,
                                 &provider));
    handles.append(service.query(ray,
                                 QAbstractCollisionQueryService::FirstHit,
                                 &provider));

    // WHEN
    const QVector<QCollisionQueryResult> results = service.fetchAllResults();

    // THEN
    bool expectedHandlesFound = true;
    for (QQueryHandle expected : qAsConst(handles)) {
        bool found = false;
        for (QCollisionQueryResult result : results) {
            if (result.handle() == expected)
                found = true;
        }

        expectedHandlesFound &= found;
    }

    QVERIFY(expectedHandlesFound);
}

void tst_RayCasting::shouldReturnHits_data()
{
    QTest::addColumn<QRay3D>("ray");
    QTest::addColumn<QVector<QBoundingVolume *> >("volumes");
    QTest::addColumn<QVector<QNodeId> >("hits");
    QTest::addColumn<QAbstractCollisionQueryService::QueryMode >("queryMode");

    QRay3D ray(Vector3D(1, 1, 1), Vector3D(0, 0, 1));

    this->boundingVolumes.clear();
    this->boundingVolumes.append(QVector<Sphere>() << Sphere(Vector3D(1, 1, 1), 3, QNodeId::createId())
                                 << Sphere(Vector3D(0, 0, 0), 3, QNodeId::createId())
                                 << Sphere(Vector3D(0, 1, 3), 1, QNodeId::createId())
                                 << Sphere(Vector3D(4, 4, 5), 1, QNodeId::createId())
                                 << Sphere(Vector3D(2, 2, 11), 5, QNodeId::createId())
                                 << Sphere(Vector3D(2, 2, 13), 1, QNodeId::createId())
                                 << Sphere(Vector3D(2, 2, 15), 5, QNodeId::createId()));

    QTest::newRow("All hits, One sphere intersect") << ray
                                                    << (QVector<QBoundingVolume *> () << volumeAt(0) << volumeAt(3))
                                                    << (QVector<QNodeId>() << volumeAt(0)->id())
                                                    << QAbstractCollisionQueryService::AllHits;

    QTest::newRow("All hits, Three sphere intersect") << ray
                                                      << (QVector<QBoundingVolume *> () << volumeAt(0) << volumeAt(3) << volumeAt(6) << volumeAt(2))
                                                      << (QVector<QNodeId>() << volumeAt(0)->id() << volumeAt(2)->id() << volumeAt(6)->id())
                                                      << QAbstractCollisionQueryService::AllHits;

    QTest::newRow("All hits, No sphere intersect") << ray
                                                   << (QVector<QBoundingVolume *> () << volumeAt(3)  << volumeAt(5))
                                                   << (QVector<QNodeId>())
                                                   << QAbstractCollisionQueryService::AllHits;

    QTest::newRow("Sphere 1 intersect, returns First Hit") << ray
                                                           << (QVector<QBoundingVolume *> () << volumeAt(0) << volumeAt(3) << volumeAt(6))
                                                           << (QVector<QNodeId>() << volumeAt(0)->id())
                                                           << QAbstractCollisionQueryService::FirstHit;

    QTest::newRow("Sphere 3 and 5 intersects, returns First Hit") << ray
                                                                  << (QVector<QBoundingVolume *> () << volumeAt(3) << volumeAt(6) << volumeAt(4))
                                                                  << (QVector<QNodeId>() << volumeAt(4)->id())
                                                                  << QAbstractCollisionQueryService::FirstHit;

    QTest::newRow("Sphere 5 and 3 intersects, unordered list, returns First Hit") << ray
                                                                                  << (QVector<QBoundingVolume *> () << volumeAt(4) << volumeAt(3) << volumeAt(6))
                                                                                  << (QVector<QNodeId>() << volumeAt(4)->id())
                                                                                  << QAbstractCollisionQueryService::FirstHit;

    QTest::newRow("No sphere intersect, returns First Hit") << ray
                                                            << (QVector<QBoundingVolume *> () << volumeAt(3)  << volumeAt(5))
                                                            << (QVector<QNodeId>())
                                                            << QAbstractCollisionQueryService::FirstHit;
}

void tst_RayCasting::shouldReturnHits()
{
    // GIVEN
    QFETCH(QRay3D, ray);
    QFETCH(QVector<QBoundingVolume *>, volumes);
    QFETCH(QVector<QNodeId>, hits);
    QFETCH(QAbstractCollisionQueryService::QueryMode, queryMode);

    MyBoudingVolumesProvider provider(volumes);
    QRayCastingService service;

    // WHEN
    QQueryHandle handle = service.query(ray, queryMode, &provider);
    QCollisionQueryResult result = service.fetchResult(handle);

    // THEN
    QCOMPARE(result.entitiesHit().size(), hits.size());
    QCOMPARE(result.entitiesHit(), hits);
}

void tst_RayCasting::shouldUseProvidedBoudingVolumes()
{
    // GIVEN
    QRay3D ray(Vector3D(1, 1, 1), Vector3D(0, 0, 1));

    Sphere sphere1(Vector3D(1, 1, 1), 3);
    Sphere sphere3(Vector3D(0, 1, 3), 1);
    Sphere sphere4(Vector3D(4, 4, 5), 1);

    MyBoudingVolumesProvider provider(QVector<QBoundingVolume *>() << &sphere1 << &sphere4 << &sphere3);
    QVector<QNodeId> hits(QVector<QNodeId>() << sphere1.id() << sphere3.id());

    QRayCastingService service;

    // WHEN
    QQueryHandle handle = service.query(ray,
                                        QAbstractCollisionQueryService::AllHits,
                                        &provider);
    QCollisionQueryResult result = service.fetchResult(handle);

    // THEN
    QCOMPARE(result.entitiesHit().size(), hits.size());
    QCOMPARE(result.entitiesHit(), hits);
}

void tst_RayCasting::cleanupTestCase()
{
    this->boundingVolumes.clear();
}

Sphere *tst_RayCasting::volumeAt(int index)
{
    return &*(boundingVolumes.begin() + index);
}

void tst_RayCasting::mousePicking()
{
    // GIVEN
    Qt3DRender::QCamera camera;
    camera.setProjectionType(QCameraLens::PerspectiveProjection);
    camera.setFieldOfView(45.0f);
    camera.setAspectRatio(800.0f/600.0f);
    camera.setNearPlane(0.1f);
    camera.setFarPlane(1000.0f);
    camera.setPosition(QVector3D(0.0f, 0.0f, -40.0f));
    camera.setUpVector(QVector3D(0.0f, 1.0f, 0.0f));
    camera.setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));

    const QRectF viewport(0.0f, 0.0f, 800.0f, 600.0f);

    // Window center on near plane
    QRay3D ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.center().toPoint(),
                                                                         Matrix4x4(camera.viewMatrix()),
                                                                         Matrix4x4(camera.projectionMatrix()),
                                                                         viewport.toRect());
    Qt3DRender::Render::Sphere s(Vector3D(0.0f, 0.5f, 0.0f), 1.0f);

    // WHEN
    bool intersects = s.intersects(ray, nullptr);

    // THEN
    QVERIFY(intersects);

    // WHEN
    ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.topLeft().toPoint(),
                                                                  Matrix4x4(camera.viewMatrix()),
                                                                  Matrix4x4(camera.projectionMatrix()),
                                                                  viewport.toRect());
    intersects = s.intersects(ray, nullptr);

    // THEN
    QVERIFY(!intersects);

    // WHEN
    ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.topRight().toPoint(),
                                                                  Matrix4x4(camera.viewMatrix()),
                                                                  Matrix4x4(camera.projectionMatrix()),
                                                                  viewport.toRect());
    intersects = s.intersects(ray, nullptr);

    // THEN
    QVERIFY(!intersects);

    // WHEN
    ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.bottomLeft().toPoint(),
                                                                  Matrix4x4(camera.viewMatrix()),
                                                                  Matrix4x4(camera.projectionMatrix()),
                                                                  viewport.toRect());
    intersects = s.intersects(ray, nullptr);

    // THEN
    QVERIFY(!intersects);

    // WHEN
    ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.bottomRight().toPoint(),
                                                                  Matrix4x4(camera.viewMatrix()),
                                                                  Matrix4x4(camera.projectionMatrix()),
                                                                  viewport.toRect());
    intersects = s.intersects(ray, nullptr);

    // THEN
    QVERIFY(!intersects);
}

QTEST_APPLESS_MAIN(tst_RayCasting)

#include "tst_raycasting.moc"
