/**
 * @file rrts02-nearestNeighbors.cpp
 * @author Can Erdogan
 * @date Feb 04, 2013
 * @brief Checks if the nearest neighbor computation done by flann is correct.
 */

#include <iostream>
#include <gtest/gtest.h>
#include <Eigen/Core>
#include <dart/dart.hpp>
#if HAVE_FLANN
#include <flann/flann.hpp>
#endif // HAVE_FLANN
#include "TestHelpers.hpp"

/* ********************************************************************************************* */
#if HAVE_FLANN
TEST(NEAREST_NEIGHBOR, 2D) {

    // Build the index with the first node
    flann::Index<flann::L2<double> > index (flann::KDTreeSingleIndexParams(10, true));
    Eigen::VectorXd p1 (2);
    p1 << -3.04159, -3.04159;
    index.buildIndex(flann::Matrix<double>((double*)p1.data(), 1, p1.size()));

    // Add two more points
    Eigen::Vector2d p2 (-2.96751, -2.97443), p3 (-2.91946, -2.88672);
    index.addPoints(flann::Matrix<double>((double*)p2.data(), 1, p2.size()));
    index.addPoints(flann::Matrix<double>((double*)p3.data(), 1, p3.size()));

    // Check the size of the tree
    EXPECT_EQ(3, (int)index.size());

    // Get the nearest neighbor index for a sample point
    Eigen::Vector2d sample (-2.26654, 2.2874);
    int nearest;
    double distance;
    const flann::Matrix<double> queryMatrix((double*)sample.data(), 1, sample.size());
    flann::Matrix<int> nearestMatrix(&nearest, 1, 1);
    flann::Matrix<double> distanceMatrix(flann::Matrix<double>(&distance, 1, 1));
    index.knnSearch(queryMatrix, nearestMatrix, distanceMatrix, 1,
        flann::SearchParams(flann::FLANN_CHECKS_UNLIMITED));
    EXPECT_EQ(2, nearest);

    // Get the nearest neighbor
    double* point = index.getPoint(nearest);
    bool equality = equals(Vector2d(point[0], point[1]), p3, 1e-3);
    EXPECT_TRUE(equality);
}
#endif // HAVE_FLANN
