package com.zepp.www.openglespractice.objects;

import com.zepp.www.openglespractice.data.GeneratedData;
import com.zepp.www.openglespractice.util.Geometry;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by xubinggui on 5/4/16.
 * //                            _ooOoo_
 * //                           o8888888o
 * //                           88" . "88
 * //                           (| -_- |)
 * //                            O\ = /O
 * //                        ____/`---'\____
 * //                      .   ' \\| |// `.
 * //                       / \\||| : |||// \
 * //                     / _||||| -:- |||||- \
 * //                       | | \\\ - /// | |
 * //                     | \_| ''\---/'' | |
 * //                      \ .-\__ `-` ___/-. /
 * //                   ___`. .' /--.--\ `. . __
 * //                ."" '< `.___\_<|>_/___.' >'"".
 * //               | | : `- \`.;`\ _ /`;.`/ - ` : | |
 * //                 \ \ `-. \_ __\ /__ _/ .-` / /
 * //         ======`-.____`-.___\_____/___.-`____.-'======
 * //                            `=---='
 * //
 * //         .............................................
 * //                  佛祖镇楼                  BUG辟易
 */
public class ObjectBuilder {
    private static final int FLOATS_PER_VERTEX = 3;
    private final float[] vertexData;
    private int offset = 0;

    private final List<DrawCommand> drawList = new ArrayList<>();

    private ObjectBuilder(int sizeInVertices) {
        vertexData = new float[sizeInVertices * FLOATS_PER_VERTEX];
    }

    //计算圆柱顶部顶点数量，圆心，围着圆心的点，围着圆心的第一个顶点要重复两次才能闭合
    private static int sizeOfCircleInVertices(int numPoints) {
        return 1 + (numPoints + 1);
    }

    //计算圆柱侧面顶点的数量，上下两个圆
    private static int sizeOfOpenCylinderInVertices(int numPoints) {
        return (numPoints + 1) * 2;
    }

    public static GeneratedData createPuck(Geometry.Cylinder puck, int numPoints) {
        int size = sizeOfCircleInVertices(numPoints) + sizeOfOpenCylinderInVertices(numPoints);

        ObjectBuilder builder = new ObjectBuilder(size);

        Geometry.Circle puckTop =
                new Geometry.Circle(puck.center.translateY(puck.height / 2f), puck.radius);

        builder.appendCircle(puckTop, numPoints);
        builder.appendOpenCylinder(puck, numPoints);

        return builder.build();
    }

    private GeneratedData build() {
        return null;
    }

    private void appendOpenCylinder(Geometry.Cylinder puck, int numPoints) {

    }

    private void appendCircle(Geometry.Circle circle, int numPoints) {
        //Center point of fan
        vertexData[offset++] = circle.center.x;
        vertexData[offset++] = circle.center.y;
        vertexData[offset++] = circle.center.z;

        //Fan around center point. <= is used because we ant to generate
        //the point at the starting angle twice to complete the fan
        for (int i = 0; i <= numPoints; i++) {
            float angleInRadius = ((float) i / (float) numPoints) * ((float) Math.PI * 2f);

            vertexData[offset++] =
                    (float) (circle.center.x + circle.radius * Math.cos(angleInRadius));
            vertexData[offset++] = circle.center.y;
            vertexData[offset++] =
                    (float) (circle.center.z + circle.radius * Math.sin(angleInRadius));
        }
    }

    static interface DrawCommand {
        void draw();
    }
}

@@ -202,16 +202,56 @@
 .List;%0A%0A
+import static android.opengl.GLES20.*;%0A%0A
 /**%0A * C
@@ -2500,109 +2500,1368 @@
 der 
-puck, int numPoints) %7B%0A%0A    %7D%0A%0A    private void appendCircle(Geometry.Circle circle, int numPoints) %7B
+cylinder, int numPoints) %7B%0A        final int startVertex = offset / FLOATS_PER_VERTEX;%0A        final int numVertices = sizeOfOpenCylinderInVertices(numPoints);%0A        final float yStart = cylinder.center.y - (cylinder.height / 2f);%0A        final float yEnd = cylinder.center.y + (cylinder.height / 2f);%0A%0A        for (int i = 0; i%3C=numPoints; i++) %7B%0A            float angleInRadians = ((float)i / (float)numPoints) * ((float) Math.PI * 2f);%0A%0A            float xPosition =%0A                    (float) (cylinder.center.x + cylinder.radius * Math.cos(angleInRadians));%0A            float zPosition =%0A                    (float) (cylinder.center.z + cylinder.radius * Math.sin(angleInRadians));%0A%0A            vertexData%5Boffset++%5D = xPosition;%0A            vertexData%5Boffset++%5D = yStart;%0A            vertexData%5Boffset++%5D = zPosition;%0A            vertexData%5Boffset++%5D = xPosition;%0A            vertexData%5Boffset++%5D = yEnd;%0A            vertexData%5Boffset++%5D = zPosition;%0A        %7D%0A        drawList.add(new DrawCommand() %7B%0A            @Override public void draw() %7B%0A                glDrawArrays(GL_TRIANGLE_STRIP, startVertex, numVertices);%0A            %7D%0A        %7D)%0A    %7D%0A%0A    private void appendCircle(Geometry.Circle circle, int numPoints) %7B%0A%0A        final int startVertex = offset / FLOATS_PER_VERTEX;%0A%0A        final int numVertices = sizeOfCircleInVertices(numPoints);%0A
 %0A   
@@ -4618,24 +4618,208 @@
 );%0A        %7D
+%0A%0A        drawList.add(new DrawCommand() %7B%0A            @Override public void draw() %7B%0A                glDrawArrays(GL_TRIANGLE_FAN, startVertex, numVertices);%0A            %7D%0A        %7D);
 %0A    %7D%0A%0A    

Update ObjectBuilder