// Port of de.varylab.discreteconformal.plugin.HyperIdealVisualizationPluginTest (Java/JUnit).
//
// Tests the conversion from a hyperbolic circle (hyperboloid model)
// to its Euclidean representation (Poincaré disk model).
//
// Java test: static method HyperIdealVisualizationPlugin
//              .getEuclideanCircleFromHyperbolic(double[] center, double radius)
// C++ port:  conformallab::getEuclideanCircleFromHyperbolic(Vector4d, double)
//              in hyper_ideal_visualization_utility.hpp

#include "hyper_ideal_visualization_utility.hpp"
#include <gtest/gtest.h>
#include <cmath>

using namespace conformallab;

// Corresponds to Java testGetEuclideanCircleFromHyperbolic_Centered()
//
// A hyperbolic circle centered at the origin (0,0,0,1) with radius 1.
// In the Poincaré disk this maps to a Euclidean circle centered at (0,0)
// with radius  sinh(1) / (cosh(1) + 1).
TEST(HyperIdealVisualizationUtilityTest, EuclideanCircleFromHyperbolic_Centered)
{
    Eigen::Vector4d center(0.0, 0.0, 0.0, 1.0);
    const double radius = 1.0;

    auto result = getEuclideanCircleFromHyperbolic(center, radius);

    const double expected_r = std::sinh(1.0) / (std::cosh(1.0) + 1.0);
    EXPECT_NEAR(0.0,        result[0], 1E-12) << "Euclidean cx should be 0";
    EXPECT_NEAR(0.0,        result[1], 1E-12) << "Euclidean cy should be 0";
    EXPECT_NEAR(expected_r, result[2], 1E-12) << "Euclidean radius mismatch";
}

// Corresponds to Java testGetEuclideanCircleFromHyperbolic_OffCenter()
//
// A hyperbolic circle centered at (sinh(1),0,0,cosh(1)) with radius 1.
// By symmetry (center is on the x-axis, circle is symmetric about it):
//   • the Euclidean center lies on the x-axis  → cy = 0
//   • the Euclidean center equals the radius   → cx = r  (the circle passes through the Poincaré origin)
TEST(HyperIdealVisualizationUtilityTest, EuclideanCircleFromHyperbolic_OffCenter)
{
    Eigen::Vector4d center(std::sinh(1.0), 0.0, 0.0, std::cosh(1.0));
    const double radius = 1.0;

    auto result = getEuclideanCircleFromHyperbolic(center, radius);

    EXPECT_NEAR(result[0], result[2], 1E-12) << "cx should equal Euclidean radius";
    EXPECT_NEAR(0.0, result[1],       1E-12) << "cy should be 0 (x-axis symmetry)";
}
