// Copyright (c) 2024-2026 Tarik Moussa.
// SPDX-License-Identifier: MIT
//
// Package: conformallab++ / Discrete_conformal_map (Phase 8 MVP, 2026-05-19)

/*!
\file CGAL/Conformal_map/internal/parameters.h
\internal
\ingroup PkgConformalMapRef

Named-parameter tag definitions specific to the Discrete_conformal_map
package.  These tags extend the CGAL named-parameter mechanism
(see `<CGAL/Named_function_parameters.h>`).

Usage from a user perspective is in `CGAL::parameters::*`; the tags
themselves live in `CGAL::Conformal_map::internal_np`.

This is an internal header — users should not include it directly.
*/

#ifndef CGAL_CONFORMAL_MAP_INTERNAL_PARAMETERS_H
#define CGAL_CONFORMAL_MAP_INTERNAL_PARAMETERS_H

#include <CGAL/Named_function_parameters.h>

namespace CGAL {
namespace Conformal_map {

/// \internal
/// Parameter tags for the conformal-map package.  Each tag is an
/// `enum` whose name ends in `_t` and a value whose name does not.
/// The pattern follows CGAL convention so that the existing
/// `choose_parameter` / `get_parameter` machinery works directly.
namespace internal_np {

// ─── Target curvature (Θᵥ) ──────────────────────────────────────────────────
/// Property-map: vertex_descriptor → FT (target cone angle Θᵥ in radians).
/// Default: 2π at every interior vertex, π at every boundary vertex.
enum vertex_curvature_map_t { vertex_curvature_map };

// ─── Newton solver tolerances ───────────────────────────────────────────────
/// Convergence threshold for the Newton solver: ‖G(u)‖∞ < tol.
/// Type: FT.  Default: 1e-10.
enum gradient_tolerance_t { gradient_tolerance };

/// Maximum number of Newton iterations.
/// Type: int.  Default: 200.
/// (Reuses the CGAL `number_of_iterations` tag where appropriate; this
/// alias is provided for vocabulary continuity within the package.)
enum max_iterations_t { max_iterations };

// ─── DOF / gauge fixing ─────────────────────────────────────────────────────
/// Property-map: vertex_descriptor → bool.  `true` ⇒ vertex is pinned
/// (u_v = 0, removed from the Newton DOF vector).
/// Default: first vertex is pinned, all others are variable.
enum fixed_vertex_map_t { fixed_vertex_map };

// ─── Layout output (Phase 8b-Lite extension) ────────────────────────────────
/// Property-map: vertex_descriptor → 2-D / 3-D coordinate.  If provided,
/// the entry function calls the appropriate `*_layout()` after Newton
/// convergence and writes the per-vertex coordinates into this map:
///   - Euclidean / Hyper-ideal / Inversive-Distance: `Point_2` (UV in ℝ²)
///   - Spherical: `Point_3` (point on S² ⊂ ℝ³)
/// If the parameter is absent, no layout step is performed.  Callers
/// who need finer control should run `*_layout()` directly on
/// `result.x` plus the maps from `setup_*_maps()`.
enum output_uv_map_t { output_uv_map };

/// Boolean flag: if `true`, apply the canonical post-layout
/// normalisation (`normalise_euclidean` PCA centroid + axis,
/// `normalise_spherical` Rodrigues to north pole, …) before writing
/// into `output_uv_map`.  Default: `false`.
enum normalise_layout_t { normalise_layout };

}  // namespace internal_np
}  // namespace Conformal_map

namespace parameters {

/*!
\addtogroup PkgConformalMapNamedParameters
\{
*/

/// \name Discrete conformal map — package-specific named parameters
/// \{

/// `vertex_curvature_map(pmap)` — target cone angle Θᵥ per vertex.
/// Type: model of `ReadablePropertyMap` with key = `vertex_descriptor`,
/// value = `FT`.  If omitted, the package uses 2π at interior vertices
/// and π at boundary vertices (the natural Gauss–Bonnet target for an
/// open disk or closed flat surface).
template <typename PropertyMap>
auto vertex_curvature_map(const PropertyMap& pmap)
{
    return CGAL::Named_function_parameters<
        PropertyMap,
        Conformal_map::internal_np::vertex_curvature_map_t,
        CGAL::internal_np::No_property
    >(pmap);
}

/// `gradient_tolerance(eps)` — Newton stopping criterion ‖G‖∞ < eps.
template <typename FT>
auto gradient_tolerance(FT eps)
{
    return CGAL::Named_function_parameters<
        FT,
        Conformal_map::internal_np::gradient_tolerance_t,
        CGAL::internal_np::No_property
    >(eps);
}

/// `max_iterations(n)` — Newton iteration limit.
inline auto max_iterations(int n)
{
    return CGAL::Named_function_parameters<
        int,
        Conformal_map::internal_np::max_iterations_t,
        CGAL::internal_np::No_property
    >(n);
}

/// `fixed_vertex_map(pmap)` — which vertices are pinned for gauge-fixing.
/// Type: model of `ReadablePropertyMap` with key = `vertex_descriptor`,
/// value = `bool`.  If omitted, the first vertex in the mesh is pinned
/// (compatible with the existing legacy API).
template <typename PropertyMap>
auto fixed_vertex_map(const PropertyMap& pmap)
{
    return CGAL::Named_function_parameters<
        PropertyMap,
        Conformal_map::internal_np::fixed_vertex_map_t,
        CGAL::internal_np::No_property
    >(pmap);
}

/// `output_uv_map(pmap)` — write the per-vertex layout coordinates
/// into `pmap` after Newton converges.
///
/// Type: model of `WritablePropertyMap` with key = `vertex_descriptor`
/// and value either `Point_2` (Euclidean / Hyper-ideal / Inversive-
/// Distance entries) or `Point_3` (Spherical entry).
///
/// Implementation: the entry function runs the appropriate
/// `*_layout()` from `code/include/layout.hpp` after Newton, then
/// writes one coordinate per vertex into `pmap`.  If omitted, no
/// layout is performed.
template <typename PropertyMap>
auto output_uv_map(const PropertyMap& pmap)
{
    return CGAL::Named_function_parameters<
        PropertyMap,
        Conformal_map::internal_np::output_uv_map_t,
        CGAL::internal_np::No_property
    >(pmap);
}

/// `normalise_layout(flag)` — apply the canonical post-layout
/// normalisation (PCA centroid for Euclidean; north-pole alignment
/// for Spherical; Möbius centring for Hyper-ideal).  Default: `false`.
/// Only meaningful in combination with `output_uv_map`.
inline auto normalise_layout(bool flag)
{
    return CGAL::Named_function_parameters<
        bool,
        Conformal_map::internal_np::normalise_layout_t,
        CGAL::internal_np::No_property
    >(flag);
}

/// \}
/// \}

}  // namespace parameters
}  // namespace CGAL

#endif  // CGAL_CONFORMAL_MAP_INTERNAL_PARAMETERS_H
