#pragma once
// mesh_builder.hpp
//
// Factory functions that build simple reference meshes for testing and examples.
// All functions return a ConformalMesh (CGAL::Surface_mesh<Point3>).
//
// Replaces Java mesh generators:
//   CoHDS generators (convex hull, hyper-ideal generator) come later (Phase 3c/4).
//   These builders cover the minimal meshes needed for functional unit tests.

#include "conformal_mesh.hpp"
#include "constants.hpp"
#include <cmath>
#include <vector>

namespace conformallab {

// ── Single triangle ──────────────────────────────────────────────────────────
//
//   v2
//   |  \
//   |    \
//   v0 ─ v1
//
// Returns a mesh with 1 face, 3 vertices, 3 edges.
// The triangle lies in the xy-plane with a right angle at v0.
inline ConformalMesh make_triangle(
    double x0=0, double y0=0,
    double x1=1, double y1=0,
    double x2=0, double y2=1)
{
    ConformalMesh mesh;
    auto v0 = mesh.add_vertex(Point3(x0, y0, 0));
    auto v1 = mesh.add_vertex(Point3(x1, y1, 0));
    auto v2 = mesh.add_vertex(Point3(x2, y2, 0));
    mesh.add_face(v0, v1, v2);
    return mesh;
}

// ── Regular tetrahedron ──────────────────────────────────────────────────────
//
// 4 vertices, 4 faces, 6 edges.
// Euler characteristic: V - E + F = 4 - 6 + 4 = 2  (sphere topology).
// Used to test closed-surface traversal.
inline ConformalMesh make_tetrahedron()
{
    ConformalMesh mesh;

    // Vertices of a regular tetrahedron centred at origin, edge length √2·2
    auto v0 = mesh.add_vertex(Point3( 1,  1,  1));
    auto v1 = mesh.add_vertex(Point3( 1, -1, -1));
    auto v2 = mesh.add_vertex(Point3(-1,  1, -1));
    auto v3 = mesh.add_vertex(Point3(-1, -1,  1));

    // 4 outward-facing triangles (consistent winding)
    mesh.add_face(v0, v2, v1);  // bottom (z=-1 side)
    mesh.add_face(v0, v1, v3);  // front  (y=-1 side)
    mesh.add_face(v0, v3, v2);  // left   (x=-1 side)
    mesh.add_face(v1, v2, v3);  // back

    return mesh;
}

// ── Two-triangle strip ───────────────────────────────────────────────────────
//
//   v2 ─ v3
//   |  \ |
//   v0 ─ v1
//
// 4 vertices, 2 faces, 5 edges (1 interior edge v1–v2 shared by both faces).
// Useful for testing edge-interior vs edge-boundary distinction.
inline ConformalMesh make_quad_strip()
{
    ConformalMesh mesh;
    auto v0 = mesh.add_vertex(Point3(0, 0, 0));
    auto v1 = mesh.add_vertex(Point3(1, 0, 0));
    auto v2 = mesh.add_vertex(Point3(0, 1, 0));
    auto v3 = mesh.add_vertex(Point3(1, 1, 0));

    mesh.add_face(v0, v1, v2);   // lower-left  triangle
    mesh.add_face(v1, v3, v2);   // upper-right triangle  (shares edge v1–v2)

    return mesh;
}

// ── Regular flat polygon fan ─────────────────────────────────────────────────
//
// n triangles sharing a central vertex; forms a disk topology (boundary).
// Used to verify valence-n vertex traversal.
inline ConformalMesh make_fan(int n)
{
    CGAL_precondition(n >= 3);
    ConformalMesh mesh;

    auto center = mesh.add_vertex(Point3(0, 0, 0));

    const double dtheta = TWO_PI / n;
    std::vector<Vertex_index> rim(n);
    for (int i = 0; i < n; ++i) {
        double a = i * dtheta;
        rim[i] = mesh.add_vertex(Point3(std::cos(a), std::sin(a), 0));
    }

    for (int i = 0; i < n; ++i)
        mesh.add_face(center, rim[i], rim[(i+1) % n]);

    return mesh;
}

// ── Spherical tetrahedron (vertices on the unit sphere) ───────────────────────
//
// The four vertices of a regular tetrahedron projected onto the unit sphere.
// Starting from (±1,±1,±1), dividing by √3 gives unit-length positions.
// All edge lengths equal arccos(−1/3) ≈ 1.9106 radians.
// Used for SphericalFunctional tests (all four faces are valid spherical triangles).
inline ConformalMesh make_spherical_tetrahedron()
{
    ConformalMesh mesh;
    const double s = 1.0 / std::sqrt(3.0);

    auto v0 = mesh.add_vertex(Point3( s,  s,  s));
    auto v1 = mesh.add_vertex(Point3( s, -s, -s));
    auto v2 = mesh.add_vertex(Point3(-s,  s, -s));
    auto v3 = mesh.add_vertex(Point3(-s, -s,  s));

    mesh.add_face(v0, v2, v1);
    mesh.add_face(v0, v1, v3);
    mesh.add_face(v0, v3, v2);
    mesh.add_face(v1, v2, v3);

    return mesh;
}

// ── Octahedron face triangle (vertices on the unit sphere) ────────────────────
//
// One face of a regular octahedron: the triangle (1,0,0)→(0,1,0)→(0,0,1).
// All edge lengths equal arccos(0) = π/2.
// The corner angles are all π/2 (right-angled spherical triangle).
// base log-length: λ° = 2·log(sin(π/4)) = 2·log(1/√2) = −log(2) ≈ −0.6931.
inline ConformalMesh make_octahedron_face()
{
    ConformalMesh mesh;
    auto v0 = mesh.add_vertex(Point3(1, 0, 0));
    auto v1 = mesh.add_vertex(Point3(0, 1, 0));
    auto v2 = mesh.add_vertex(Point3(0, 0, 1));
    mesh.add_face(v0, v1, v2);
    return mesh;
}

} // namespace conformallab
