// 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>.
//

#include <iostream>

#include "nlagrange.h"
#include "nspline.h"
#include "nbeziercurve.h"
#include "ncoons.h"
#include "nbspline.h"
#include "nbsplinesurface.h"
#include "nbeziertriangle.h"
#include "ndisplay.h"
#include "gnurbscallbacks.h"



void initsurface_crack(nbsplinesurface &surf,double DX,double DY,double DZ)
{

  for (int i=0;i<surf.nb_CP_u();++i)
  {
    for (int j=0;j<surf.nb_CP_v();++j)
    {
      double x=i*2/ ((double) surf.nb_CP_u()-1)-1;
      double y=j*2/ ((double) surf.nb_CP_v()-1)-1;
      double z=0;
      npoint p(x+DX,y+DY,z+DZ,1.0);
      surf.CP(i,j) =p;
    }
  }
   
  // CPs on the 4 sides
    
  for (int i=0;i<surf.nb_CP_u();++i)
  {
    double x=i*2/ ((double) surf.nb_CP_u()-1)-1;
    double y=(i*2/ ((double) surf.nb_CP_u()-1)-1+1)/2.0;
    double z=0;
    npoint p1(x+DX,y+DY,z+DZ,1.0);
    npoint p2(x+DX,-y+DY,z+DZ,1.0);
    surf.CP(i,surf.nb_CP_v()-1) =p1;
    surf.CP(i,0) =p2;
  }
  
  for (int j=0;j<surf.nb_CP_v();++j)
  {
    double x=1.0;
    double y=j*2/ ((double) surf.nb_CP_v()-1)-1;
    double z=0;
    npoint p1(x+DX,y+DY,z+DZ,1.0);
    x=j*2/ ((double) surf.nb_CP_v()-1)-1;
    x=-x*x;
    y=0;
    npoint p2(x+DX,y+DY,z+DZ,1.0);
    surf.CP(surf.nb_CP_u()-1,j) =p1;
    surf.CP(0,j) =p2;
  }

  // inner CPs
  for (int i=1;i<surf.nb_CP_u()-1;++i)
  {
    for (int j=1;j<surf.nb_CP_v()-1;++j)
    {
      double u=i*2/ ((double) surf.nb_CP_u()-1)-1;
      npoint p=surf.CP(0,j)*(1.0-u)/2.0+surf.CP(surf.nb_CP_u()-1,j)*(1.0+u)/2.0;
      surf.CP(i,j) =p;
    }
  }
  
  
// nodal sequences  
  int endsu=surf.degree_u() +1;
  int du=surf.degree_u();
  int cpsu=surf.nb_CP_u()-1;
  for (int i=0;i<endsu;++i)
  {
    surf.u(i) =0.0;
    surf.u(cpsu+du+1-i) = (cpsu+du+2-2*endsu+1);     //1.0;
  }
  for (int i=1;i<= (cpsu+du+2-2*endsu);++i)
  {
    surf.u(i+endsu-1) =i;   //(1.0*i)/(cpsu+du+3-2*endsu);
  }

  int endsv=surf.degree_v() +1;
  int dv=surf.degree_v();
  int cpsv=surf.nb_CP_v()-1;

  for (int i=0;i<endsv;++i)
  {
    surf.v(i) =0.0;
    surf.v(cpsv+dv+1-i) = (cpsv+dv+2-2*endsv+1);     //1.0;
  }
  for (int i=1;i<= (cpsv+dv+2-2*endsv);++i)
  {
    surf.v(i+endsv-1) =i;   //(1.0*i)/(cpsv+dv+3-2*endsv);
  }
  
  std::cout << "[";
  for (int i=0;i<surf.nb_knots_u();++i) std::cout << surf.u(i) << " " ;
  std::cout << "]" << std::endl ;
  std::cout << "[";
  for (int i=0;i<surf.nb_knots_v();++i) std::cout << surf.v(i) << " " ;
  std::cout << "]" << std::endl;
  
}


int main(void)
{
//  data_container data;
  ndisplay display;
  gnurbscallbacks CB;
  display.setcallbacks(&CB);


  properties p;

  p.pointsize=3;
  p.c=color(255,255,255,128);
  

  nbsplinesurface bssurface_crack(5,3,5,3);
 
  initsurface_crack(bssurface_crack,0,0,0);
  
  double SF,dSFdu,dSFdv;
  double u=0.0;
  double v=1.0;
  int indexSF_u=0;
  int indexSF_v=bssurface_crack.nb_CP_v()-2;
  int indexSF=indexSF_u+bssurface_crack.nb_CP_u()*indexSF_v; // absulute index
  bssurface_crack.SF(u,v,indexSF,SF,dSFdu,dSFdv);
  std::cout << SF << " " << dSFdu << " " << dSFdv << std::endl;


  CB.add_entity(&bssurface_crack,p);

  

  display.display();
  return 0;
}
