// Gnurbs - A curve and surface library
// Copyright (C) 2008-2026 Eric Bechet
//
// See the LICENSE file for contributions and license information.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//

#ifndef __NRSPLINE_H
#define __NRSPLINE_H
#include "gnurbsconfig.h"

#ifdef ENABLE_CLOTHOID

#include "nspline.h"
#include "nclothoid.h"
#include <vector>

/// Real Spline class (in 2D, 3D yet to design)
class nrspline : public nspline_like
{
protected:
    std::vector<nclothoid> segments;
    std::vector<double> th;
public:

  /// \brief Constructor.
  /// \param[in] nCP_ number of points to interpolate.
  /// \warning RSpline and interpolation points are unitialized.
  nrspline(int nCP_) : nspline_like(nCP_),segments(nCP_-1),th(nCP_) {}

  virtual int degree(void) const
  {
    return 3 ;
  }
  virtual void P(double u_,npoint& ret) const ;    // position along the curve
  virtual void set_CP(int which,const npoint& pt)  // sets a control point
  {
    val[which]=pt;
    update();
  }
  /// \brief Recomputes derivatives from point positions.
  virtual void update();
  
  /// \brief Computes the finite-difference rspline.
  virtual void compute_FD(void);

  /// \brief Computes the cardinal rspline.
  /// \param[in] c cardinal parameter in [0, 1].
  virtual void compute_cardinal(double c);

  /// \brief Computes the natural rspline.
  virtual void compute_natural(void);
  
  virtual nrspline* clone() const
  {
    return new nrspline(*this);
  }
  virtual void print();
  /// \brief Discretizes the curve in line segments for display.
  /// \param[in] data data container to fill with the line segments.
  virtual void Display(data_container& data) const;
  
private:
  void compute_segments();
  void set_slopes(std::vector<double> &slopes);
  void add_to_slopes(std::vector<double> &dslopes);
  double get_curvature_gaps(std::vector<double> &curv);
  void get_curvature_der(std::vector<double> &curv);
};
#endif //ENABLE_CLOTHOID

#endif // __NRSPLINE_H

