package p5;
import anar.*;



import processing.core.PApplet;


public class Test02jBSplineDebug3DSurfaceCSurface extends PApplet {

  /*
   * Example for Anar library by Guillaume LaBelle + Julien Nembrini
   * http://anar.ch
   */


  Pts   bsp1;
  Pts   bsp2;
  // ParametricValue pv;
  Param pv = new Param(1/.15f);

  Pts   baseLine;              // = new Pts();
  Pts   baseLine2;             // = new Pts();

  Obj   obj;

  public void setup(){
    size(800,400,OPENGL);
    frameRate(200);

    Anar.init(this);
    Anar.drawAxis(true);
    initShape();

    Pts.globalRender = new RenderPtsAll();
    Pt.globalRender = new RenderPtShapeOriented(new AColor(100),new AColor(255,0,0,150),Anar.scene);
  }


  void initShape(){
    baseLine = new Pts();
    baseLine2 = new Pts();

    baseLine.add(Anar.Pt(0,0,100));
    baseLine.add(Anar.Pt(25,130,0));
    baseLine.add(Anar.Pt(50,0,50));
    baseLine.add(Anar.Pt(75, -30,0));
    baseLine.add(Anar.Pt(100,0,0));


    baseLine2.add(Anar.Pt(0,0,0));
    baseLine2.add(Anar.Pt(0,25,0));
    baseLine2.add(Anar.Pt(100,50,50));
    baseLine2.add(Anar.Pt(0,75,0));
    baseLine2.add(Anar.Pt(100,100,0));


    // pv = new ParametricValue(.3f);
    // pn = new ParametricValue(6);

    bsp1 = new CSpline(baseLine,pv);
    bsp2 = new CSpline(baseLine2,pv);


    obj = new Obj();
    obj.add(bsp1);
    obj.add(bsp2);
    
    Pts discret1 = bsp1.discretization(50);
    Pts discret2 = bsp2.discretization(50);    



    Pts[] gridU = new Pts[discret2.numOfPts()];

    for (int i = 0; i<discret1.numOfPts(); i++){
      gridU[i] = new Pts();

      for (int j = 0; j<discret2.numOfPts(); j++){
        Pt a = discret1.pt(i);
        Pt b = discret2.pt(j);
        gridU[i].add(Anar.Pt( (a.x()+b.x()), (a.y()+b.y()), (a.z()+b.z())));
      }
    }


    for (int i = 0; i<discret1.numOfPts()-1; i++)
      for (int j = 0; j<discret2.numOfPts()-1; j++){
        Face fce = new Face();
        fce.add((Pt)gridU[i].pt(j));
        fce.add((Pt)gridU[i+1].pt(j));
        fce.add((Pt)gridU[i+1].pt(j+1));
        fce.add((Pt)gridU[i].pt(j+1));
        obj.add(fce);
      }

    Anar.camTarget(obj);
  }


  public void draw(){
    background(190);

    // baseLine.draw();
    // if(frameCount%2==0)
    obj.draw();

    if(frameCount%2==0)
      if(drawConstruction){
        bsp1.draw();
        bsp2.draw();
      }
      else{
        ((CSpline)bsp1).drawConstructionLines();
        ((CSpline)bsp2).drawConstructionLines();
      }

    if(key=='k'){
      pv.set(mouseX/(float)width/2f);
      CSpline.globalRender.splineRes.set(mouseY/(float)height*60+1);
      initShape();
      key = 'h';
    }
  }


  private boolean drawConstruction = true;

  public void keyPressed(){
    switch(key){
      case ' ':
        if(drawConstruction)
          drawConstruction = false;
        else
          drawConstruction = true;
      break;
      case 'a':
        Autolisp.export(obj,this);
      break;
      case 'r':
        RhinoScript.export(obj,this);
      break;
      case 's':
        SketchUpRuby.export(obj,this);
      break;
    }
  }


  void prnt(Object s){
    super.println(s);
    super.println("-----------------------------");
  }


  public static void main(String[] args){
    PApplet.main(new String[]{Test02jBSplineDebug3DSurfaceCSurface.class.getName()});
  }
}

