#pragma once

// bezier_editor — editor visual de una curva Bezier cubica (4 puntos de
// control) usado tipicamente como diseñador de easing custom.
//
// Estado puro (struct BezierCurve), evaluacion algebraica (bezier_eval),
// editor en canvas ImGui con 4 puntos draggable (p0/p3 fijos por defecto).
//
// Uso:
//   static fn::BezierCurve curve;  // identidad: linear
//   if (fn::bezier_editor("##my_ease", curve)) { /* curva cambio */ }
//   float y = fn::bezier_eval(curve, t);

#include <imgui.h>

namespace fn {

// Curva Bezier cubica: 4 puntos de control en espacio [0,1]x[0,1].
// Por convencion, para easing curves: p0 = (0,0) y p3 = (1,1) (fijos).
// p1, p2 son los handles que el usuario arrastra.
struct BezierCurve {
    ImVec2 p0 {0.0f, 0.0f};
    ImVec2 p1 {0.25f, 0.0f};
    ImVec2 p2 {0.75f, 1.0f};
    ImVec2 p3 {1.0f, 1.0f};
};

// Evaluacion puramente algebraica via De Casteljau de la coordenada Y de la
// curva en el parametro de curva u in [0,1].
//
// NOTA: esto NO es y(x). Para una curva tipo easing donde queremos y dado un
// x temporal usamos bezier_eval (ver mas abajo) que aproxima y al x deseado
// asumiendo que la curva es monotona en X (lo es si p1.x, p2.x in [0,1] y la
// curva no cruza x=0 o x=1 fuera de los extremos).
ImVec2 bezier_point(const BezierCurve& c, float u);

// y at x=t — aproximacion mediante sampling + interpolacion lineal entre
// muestras. Suficiente para easing curves (la curva es casi monotona en X
// por construccion). Pure.
float bezier_eval(const BezierCurve& c, float t);

// Editor visual: canvas con 4 puntos draggable. p0 y p3 estan fijos por
// defecto (lock_endpoints=true) para que la curva sirva como easing
// (f(0)=0, f(1)=1). p1 y p2 son draggable libremente.
//
// Devuelve true en el frame en que el usuario arrastro algun punto.
bool bezier_editor(const char* id, BezierCurve& curve, ImVec2 size = ImVec2(200, 200), bool lock_endpoints = true);

} // namespace fn
