package p5;
import anar.*;



import java.util.ArrayList;

import processing.core.PApplet;

/**
 * @author goo
 */
public class Sierpinsky00dLoopBonBug extends PApplet {

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


  Sliders parameters;

  Pt      a, b, c;

  Obj     obj;

  int     nIteration = 0;

  public void setup(){
    size(800,400,OPENGL);
    Anar.init(this);

    Scene.autoSeek = false;

    obj = new Obj();

    initForm();

    Pts.globalRender = new RenderPtsAll();

  }


  void reset(){
    obj.faces.clear();
    obj.pts.ptList.clear();

    Pts facePts = new Pts();
    facePts.add(a);
    facePts.add(b);
    facePts.add(c);
    Face f = new Face(facePts);

    obj.add(f);

    nIteration = 0;

    addFourth = false;
  }

  void initForm(){

    a = Anar.Pt( -60, -30);
    b = Anar.Pt(60, -30);
    c = Anar.Pt(0,60);

    // obj.add(AB);
    // obj.add(BC);
    // obj.add(AC);


    Pts facePts = new Pts();
    facePts.add(a);
    facePts.add(b);
    facePts.add(c);
    Face f = new Face(facePts);

    obj.add(f);

    parameters = new Sliders(a);
    // println(parameters);
    Anar.camTarget(obj);
  }

  void loopSubdiv(){


    // use point of gravity of original point as anchor
    // Pt pp = Anar.Pt( .33f*a.x()+.33f*b.x()+.33f*c.x(),
    // .33f*a.y()+.33f*b.y()+.33f*c.y(),
    // .33f*a.z()+.33f*b.z()+.33f*c.z());

    Pt pp = Anar.Pt(.2f*a.x()+.3f*b.x()+.5f*c.x(),.2f*a.y()+.3f*b.y()+.5f*c.y(),.2f*a.z()+.3f*b.z()+.5f*c.z());

    ArrayList newFaces = new ArrayList();

    for (int k = 0; k<obj.numOfFaces(); k++){
      Face f = obj.face(k);

      // get the vertices of the triangle
      Pt aa = f.pt(0);
      Pt bb = f.pt(1);
      Pt cc = f.pt(2);

      // add first subdivision
      Pts f1Pts = new Pts();
      f1Pts.add(aa);
      f1Pts.add(bb);
      f1Pts.add(pp);
      Face f1 = new Face(f1Pts);

      // add second subdivision
      Pts f2Pts = new Pts();
      f2Pts.add(bb);
      f2Pts.add(cc);
      f2Pts.add(pp);
      Face f2 = new Face(f2Pts);

      // add third subdivision
      Pts f3Pts = new Pts();
      f3Pts.add(aa);
      f3Pts.add(pp);
      f3Pts.add(cc);
      Face f3 = new Face(f3Pts);

      newFaces.add(f1);
      newFaces.add(f2);
      newFaces.add(f3);
    }

    obj = new Obj();

    for (int i = 0; i<newFaces.size(); i++)
      obj.add((Face)newFaces.get(i));

    Anar.camTarget(obj);

  }


  void sierpinskyIteration(){

    nIteration++;
    println(nIteration);

    final float z = 20;

    ArrayList newFaces = new ArrayList();

    for (int k = 0; k<obj.numOfFaces(); k++){
      Face f = obj.face(k);

      // get the vertices of the triangle
      Pt aa = f.pt(0);
      Pt bb = f.pt(1);
      Pt cc = f.pt(2);


      // get the middle points
      Pts AB = new PtsMid(aa,bb,2);
      Pts BC = new PtsMid(bb,cc,2);
      Pts AC = new PtsMid(aa,cc,2);

      Pt ab = Anar.Pt(AB.pt(1));
      float param = z/ (nIteration*nIteration);
      float mult = .5f;

      ab.translate(mult* (random((float)param)-param/2),mult* (random((float)param)-param/2),param);
      // ab.translate(0, 0, z/(nIteration*nIteration));

      Pt bc = Anar.Pt(BC.pt(1));
      bc.translate(mult* (random((float)param)-param/2),mult* (random((float)param)-param/2),param);
      // bc.translate(0, 0, z/(nIteration*nIteration));

      Pt ac = Anar.Pt(AC.pt(1));
      ac.translate(mult* (random((float)param)-param/2),mult* (random((float)param)-param/2),param);
      // ac.translate(0, 0, z/(nIteration*nIteration));

      // add first subdivision
      Pts f1Pts = new Pts();
      f1Pts.add(aa);
      f1Pts.add(ab);
      f1Pts.add(ac);
      Face f1 = new Face(f1Pts);

      // add second subdivision
      Pts f2Pts = new Pts();
      f2Pts.add(ab);
      f2Pts.add(bb);
      f2Pts.add(bc);
      Face f2 = new Face(f2Pts);

      // add third subdivision
      Pts f3Pts = new Pts();
      f3Pts.add(ac);
      f3Pts.add(bc);
      f3Pts.add(cc);
      Face f3 = new Face(f3Pts);

      if(addFourth){
        // add fourth subdivision
        Pts f4Pts = new Pts();
        f4Pts.add(ab);
        f4Pts.add(bc);
        f4Pts.add(ac);
        Face f4 = new Face(f4Pts);
        newFaces.add(f4);
      }
      newFaces.add(f1);
      newFaces.add(f2);
      newFaces.add(f3);


    }

    obj.faces.clear();
    obj.faces = newFaces;

  }


  public void draw(){
    background(153);

    // ParametricValue v = parameters.get(0);
    // v.set(v.get()+ random(10)-5);

    obj.draw();
  }

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


  boolean addFourth = false;


  public void keyPressed(){

    switch(key){
      case 'q':
        sierpinskyIteration();
      break;
      case 'w':
        addFourth = !addFourth;
      break;
      case 'e':
        reset();
      break;
      case 'r':
        loopSubdiv();
      break;


    }


  }

}

