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


#include "ncurve.h"
#include <vector>
#include <list>

class nbspline : public nparametriccurve
{
protected:
  std::vector<npoint> val; // control points
  int nCP; // number of control points
  std::vector<double> knots; // nodal sequence
  int nknots; // number of knots
  int deg;
public:
  nbspline() : nCP(1),nknots(2),deg(0),knots(2),val(1)
  {
    knots[0]=0;
    knots[1]=1;
    val[0]=npoint();
  }
  nbspline(int nCP_,int degree_) : val(nCP_),nCP(nCP_),deg(degree_),nknots(nCP_+degree_+1),knots(nCP_+degree_+1) {}
  void reset(int nCP_,int degree_)
  {
    val.resize(nCP_);
    nCP=nCP_,deg=degree_,nknots= (nCP_+degree_+1);
    knots.resize(nCP_+degree_+1);
  }
  virtual int degree(void) const
  {
    return deg ;
  }
  virtual int nb_CP(void) const
  {
    return nCP ;
  }
  virtual int nb_knots(void) const
  {
    return nknots ;
  }
  virtual double min_u(void) const
  {
    return knots[deg];
  }
  virtual double max_u(void) const
  {
    return knots[nknots-deg-1];
  }
  double Basis(int which,double u) const;    // basis functions
  virtual void P(double u_,npoint& ret) const ;    // position of a point on the curve
  virtual void dPdu(double u_,npoint& ret) const ;    // derivative of a point on the curve
  virtual void d2Pdu2(double u_,npoint& ret) const ;    // second derivative of a point on the curve
  virtual npoint CP(int which) const
  {
    return val[which];
  }
  virtual npoint& CP(int which)
  {
    return val[which];
  }
  virtual void set_CP(int which,const npoint& pt)
  {
    val[which]=pt;
  } ;
  virtual double u(int which) const
  {
    return knots[which];
  }
  virtual double& u(int which)
  {
    return knots[which];
  }
  void insertknot(double u,int r);
  int deleteknot(int r,int s=1,double TOL=-1); // tolerance < 0 means always delete, returns number of deletions
  int clean(double TOL=1e-9); // removes unnecessary knots
  void extend(double u);
  void saturate();
  void degree_elevation();
  virtual nbspline* clone() const
  {
    return new nbspline(*this);
  }

  int findspan(double u) const ;
  void basisfuns(int i, double u, std::vector<double> &N) const ;
  void gradbasisfuns(int i, double u,int n,std::vector<std::vector<double> > &N) const ;
  double Nip(int p,int m,std::vector<double> &knots, int i, double u);

private:
  void insertknot_(double u,int k,int s,int r);
  void curvepoint(double u,npoint &C) const ;
  void dercurvepoint(double u,int nu,npoint &C) const ;
    void findspanmult(double u,int &k,int &s);
  void recursivedivide(nbspline &bs,int deep) const;
  friend class nbsplinesurface;
};

#endif // __NBSPLINE_H

