// 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 __NCURVE_H
#define __NCURVE_H

#include "nutil.h"


class ncurve
{
public:
  virtual void Display(data_container& data) const = 0;  // discretizes the curve in line segments for display
  virtual void Discretize(nmesh &mesh, double du=0., double ds=0., double eps=0., double epsr=0., int n=0) const = 0;
  virtual void Discretize(nmesh &mesh,nmesh &bnd, double du=0., double ds=0., double eps=0., double epsr=0., int n=0) const = 0;
  virtual int nb_CP(void) const {return 0;}  // returns the number of control points (0 if none)
  virtual npoint CP(int which) const {return npoint();}  // returns a control point (const)
  virtual void set_CP(int which,const npoint& pt) {} ;    // sets a control point
  virtual ncurve* clone() const =0 ; 
  static double FPeps;
  static double FPeps2; // FPeps^1/2
  static double FPeps3; // FPeps^1/3
  static double FPeps4; // FPeps^1/4
  static void update_FPeps(bool mode=false);
};


class nparametriccurve : public ncurve
{
  friend class ntrimmedcurve;
public:
  virtual int degree(void) const {return 0;}    // returns the degree of the curve (if polynomial)
  virtual double min_u(void) const =0;    // minimum allowed value of the parameter
  virtual double max_u(void) const =0;    // maximum allowed value of the parameter
  virtual void P(double u,npoint& ret) const =0;    // point along the curve for parameter u
  virtual void dPdu(double u_,npoint& ret) const;  // first derivative - generic numerical implementation
  virtual void d2Pdu2(double u_,npoint& ret) const; // second derivative, generic numerical implementation
  virtual void Display(data_container& data) const;    // discretizes the curve in line segments for display
  virtual void Discretize(nmesh &mesh, double du=0., double ds=0., double eps=0., double epsr=0., int n=0) const ;
  virtual void Discretize(nmesh &mesh,nmesh &bnd, double du=0., double ds=0., double eps=0., double epsr=0., int n=0) const ;
  virtual ncurve* clone() const =0 ;
private:
  void _Discretize(std::vector< std::pair<npoint3,double> >& pts, double from, npoint3 Posf, double to, npoint3 Post, double du, double ds, double eps, double epsr,int n) const ;    // version par defaut
  void _Display(double from, double to, data_container &data) const ;
};

class nparametricsurface;

class nembeddedcurve : public nparametriccurve // a parametric curve embedded on a parametric surface
{
  const nparametriccurve &crv;
  const nparametricsurface &surf;
public:
  nembeddedcurve(const nparametriccurve &crv_,const nparametricsurface &surf_):crv(crv_),surf(surf_) {}
  virtual double min_u(void) const {return crv.min_u();}    // minimum allowed value of the parameter
  virtual double max_u(void) const {return crv.max_u();}    // maximum allowed value of the parameter
  virtual void P(double u,npoint& ret) const;     // point along the curve for parameter u
//  virtual void dPdu(double u_,npoint& ret) const;  // first derivative - generic numerical implementation
//  virtual void d2Pdu2(double u_,npoint& ret) const; // second derivative, generic numerical implementation
  virtual void relative_curvatures(double t,double kappa[2], double m1[2][2]=0, double m2[2][2]=0) const;  //Computes normal and geodesic curvatures of an embedded curve

  virtual ncurve* clone() const 
  {
    return new nembeddedcurve(*this);
  }
};

#endif //__NCURVE_H
