package p5;
import anar.*;



import processing.core.PApplet;

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

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


  Obj     towerCore     = new Obj();
  Obj     contourLines  = new Obj();
  Obj     verticalLines = new Obj();
  Obj     windows       = new Obj();
  Obj     structure     = new Obj();

  Obj     allObjects    = new Obj();

  Sliders mySliders;


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

    // Setup DEFAULT rendering of our scene
    Pts.globalRender = new RenderPtsLine();
    Anar.drawAxis(true);
    // Scene.lights = false;
    // Anar.defaultScene = false;

    initForm();
  }


  void initForm(){

    // //////////////////////////////////////////
    // //////////////////////////////////////////
    // Initial SHAPE

    // Here, we create an arbitrary shape
    Face iShape;
    iShape = new Star(100,50,5);


    // //////////////////////////////////////////
    // //////////////////////////////////////////
    // LEVEL

    // The initial shape is duplicated Applying always the same predefined
    // Transformation

    Param numOfSubDivisionsOnEachSides = new Param(10);

    Transform combo = new Transform();
    combo.translate(0,0,5);
    combo.scale(0.95f,0.985f,1.02f);
    combo.rotateZ(.06f);

    for (int i = 0; i<40; i++){
      Face floorShape = new Face(iShape,combo);
      towerCore.add(floorShape);
      iShape = floorShape;
    }

    // //////////////////////////////////////////
    // //////////////////////////////////////////
    // VERTICALES

    for (int i = 0; i<40; i++){
      Face shape = towerCore.face(i);

      Pts contour;
      Pts tmpPtList = new Pts();

      for (int j = 0; j<shape.size(); j++){
        int jj = (j+1)%shape.size();
        contour = new PtsMid(shape.pt(j),shape.pt(jj),numOfSubDivisionsOnEachSides);
        contour.remove(contour.size()-1); // Remove the last one from the set
        tmpPtList.addPointsFrom(contour);
      }

      contourLines.add(tmpPtList);
    }


    int nodesPerLevel = contourLines.line(0).size();

    for (int j = 0; j<nodesPerLevel; j++){
      if(j%3!=0){
        Pts tmpPtList = new Pts();
        for (int i = 0; i<contourLines.numOfLines(); i++){
          Pts a = contourLines.getLine(i);
          tmpPtList.add(a.pt( (j+1*i)%nodesPerLevel));
        }
        verticalLines.add(tmpPtList);
      }
    }

    // //////////////////////////////////////////
    // //////////////////////////////////////////
    // WINDOWS

    Param offset1 = new Param(1);
    Param offset2 = new Param(2);
    Param ratioI = new Param(6);

    for (int i = 1; i<verticalLines.numOfLines(); i += 2){
      Pts a = verticalLines.line(i);
      Pts b = verticalLines.line( (i+1)%verticalLines.numOfLines());

      for (int j = 0; j<a.size()-1; j++){
        Pts k = new PtsMid(a.pt(j),a.pt(j+1),ratioI);
        Pts l = new PtsMid(b.pt(j),b.pt(j+1),ratioI);

        Pt aa = k.pt(1);
        Pt bb = a.pt(j+1);
        Pt cc = b.pt(j+1);
        Pt dd = l.pt(1);

        PtNormal nn = new PtNormal(aa,bb,cc,offset1);
        PtNormal kk = new PtNormal(bb,cc,dd,offset2);
        PtNormal mm = new PtNormal(cc,dd,aa,offset2);
        PtNormal ll = new PtNormal(dd,aa,bb,offset1);

        Pts c;

        c = new Pts();
        c.add(bb);
        c.add(nn);
        windows.add(c);

        c = new Pts();
        c.add(dd);
        c.add(mm);
        windows.add(c);

        Face f = new Face();
        f.add(nn);
        f.add(kk);
        f.add(mm);
        f.add(ll);
        windows.add(f);
      }
    }


    // //////////////////////////////////////////
    // //////////////////////////////////////////
    // STRUCTURE
    RenderPtsLine blueLines = new RenderPtsLine(new AColor(255,155,125));

    Obj pointsOnFloors = new Obj();

    for (int i = 0; i<towerCore.numOfFaces(); i++){
      Pts structurePts = new Pts();
      Face shape = towerCore.face(i);
      PtBary p = new PtBary(shape);
      p.normalizeWeight();
      structurePts.add(p);

      for (int j = 0; j<shape.numOfPts(); j++){
        float[] w = new float[shape.size()];
        w[j] = 2.5f;
        PtBary q = new PtBary(shape,w);
        q.normalizeWeight();
        structurePts.add(q);
      }
      pointsOnFloors.add(structurePts);
    }

    for (int i = 0; i<pointsOnFloors.numOfLines()-1; i++){
      Pts q = pointsOnFloors.line(i);
      Pts r = pointsOnFloors.line(i+1);
      for (int j = 0; j<q.size(); j++){
        Pts p = new Pts();
        p.add(q.pt(j));
        p.add(r.pt(j));
        p.render = blueLines;
        structure.add(p);
      }
    }


    // //////////////////////////////////////////
    // HIRARCHY

    Anar.camTarget(towerCore);
    mySliders = new Sliders(windows);

    // Store All objects in one group
    allObjects.add(towerCore);
    allObjects.add(verticalLines);
    allObjects.add(windows);
    allObjects.add(structure);

  }


  public void draw(){
    background(200);

    towerCore.draw();
    // verticales.draw();
    // contourLines.draw();
    windows.draw();
    structure.draw();
    mySliders.draw();
  }


  public void keyPressed(){

    switch(key){
      case 'a':
        Autolisp.export(allObjects,this);
      break;
      case 'r':
        RhinoScript.export(allObjects,this);
      break;
      case 's':
        SketchUpRuby.export(allObjects,this);
      break;
      case 'm':
        // PovRay.export(allObjects,this);
      break;
    }
  }


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

}

