/*
 * Copyright (C) 2008-2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.renderscript;

import android.annotation.UnsupportedAppUsage;
import java.util.Vector;

/**
 * @hide
 * @deprecated in API 16
 * <p>This class is a container for geometric data displayed with
 * RenderScript. Internally, a mesh is a collection of allocations that
 * represent vertex data (positions, normals, texture
 * coordinates) and index data such as triangles and lines. </p>
 * <p>
 * Vertex data could either be interleaved within one
 * allocation that is provided separately, as multiple allocation
 * objects, or done as a combination of both. When a
 * vertex channel name matches an input in the vertex program,
 * RenderScript automatically connects the two together.
 * </p>
 * <p>
 *  Parts of the mesh can be rendered with either explicit
 *  index sets or primitive types.
 * </p>
 **/
public class Mesh extends BaseObj {

    /**
    * @deprecated in API 16
    * Describes the way mesh vertex data is interpreted when rendering
    *
    **/
    public enum Primitive {
        /**
        * @deprecated in API 16
        * Vertex data will be rendered as a series of points
        */
        @UnsupportedAppUsage
        POINT (0),
        /**
        * @deprecated in API 16
        * Vertex pairs will be rendered as lines
        */
        LINE (1),
        /**
        * @deprecated in API 16
        * Vertex data will be rendered as a connected line strip
        */
        LINE_STRIP (2),
        /**
        * @deprecated in API 16
        * Vertices will be rendered as individual triangles
        */
        @UnsupportedAppUsage
        TRIANGLE (3),
        /**
        * @deprecated in API 16
        * Vertices will be rendered as a connected triangle strip
        * defined by the first three vertices with each additional
        * triangle defined by a new vertex
        */
        TRIANGLE_STRIP (4),
        /**
        * @deprecated in API 16
        * Vertices will be rendered as a sequence of triangles that all
        * share first vertex as the origin
        */
        TRIANGLE_FAN (5);

        int mID;
        Primitive(int id) {
            mID = id;
        }
    }

    Allocation[] mVertexBuffers;
    Allocation[] mIndexBuffers;
    Primitive[] mPrimitives;

    Mesh(long id, RenderScript rs) {
        super(id, rs);
        guard.open("destroy");
    }

    /**
    * @deprecated in API 16
    * @return number of allocations containing vertex data
    *
    **/
    public int getVertexAllocationCount() {
        if(mVertexBuffers == null) {
            return 0;
        }
        return mVertexBuffers.length;
    }
    /**
    * @deprecated in API 16
    * @param slot index in the list of allocations to return
    * @return vertex data allocation at the given index
    *
    **/
    @UnsupportedAppUsage
    public Allocation getVertexAllocation(int slot) {
        return mVertexBuffers[slot];
    }

    /**
    * @deprecated in API 16
    * @return number of primitives or index sets in the mesh
    *
    **/
    public int getPrimitiveCount() {
        if(mIndexBuffers == null) {
            return 0;
        }
        return mIndexBuffers.length;
    }

    /**
    * @deprecated in API 16
    * @param slot locaton within the list of index set allocation
    * @return allocation containing primtive index data or null if
    *         the index data is not specified explicitly
    *
    **/
    public Allocation getIndexSetAllocation(int slot) {
        return mIndexBuffers[slot];
    }
    /**
    * @deprecated in API 16
    * @param slot locaiton within the list of index set primitives
    * @return index set primitive type
    *
    **/
    public Primitive getPrimitive(int slot) {
        return mPrimitives[slot];
    }

    @Override
    void updateFromNative() {
        super.updateFromNative();
        int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS));
        int idxCount = mRS.nMeshGetIndexCount(getID(mRS));

        long[] vtxIDs = new long[vtxCount];
        long[] idxIDs = new long[idxCount];
        int[] primitives = new int[idxCount];

        mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount);
        mRS.nMeshGetIndices(getID(mRS), idxIDs, primitives, idxCount);

        mVertexBuffers = new Allocation[vtxCount];
        mIndexBuffers = new Allocation[idxCount];
        mPrimitives = new Primitive[idxCount];

        for(int i = 0; i < vtxCount; i ++) {
            if(vtxIDs[i] != 0) {
                mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
                mVertexBuffers[i].updateFromNative();
            }
        }

        for(int i = 0; i < idxCount; i ++) {
            if(idxIDs[i] != 0) {
                mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
                mIndexBuffers[i].updateFromNative();
            }
            mPrimitives[i] = Primitive.values()[primitives[i]];
        }
    }

    /**
    * @deprecated in API 16
    * Mesh builder object. It starts empty and requires you to
    * add the types necessary to create vertex and index
    * allocations.
    *
    */
    public static class Builder {
        RenderScript mRS;
        int mUsage;

        class Entry {
            Type t;
            Element e;
            int size;
            Primitive prim;
            int usage;
        }

        int mVertexTypeCount;
        Entry[] mVertexTypes;
        Vector mIndexTypes;

        /**
        * @deprecated in API 16
        * Creates builder object
        * @param rs Context to which the mesh will belong.
        * @param usage specifies how the mesh allocations are to be
        *              handled, whether they need to be uploaded to a
        *              buffer on the gpu, maintain a cpu copy, etc
        */
        public Builder(RenderScript rs, int usage) {
            mRS = rs;
            mUsage = usage;
            mVertexTypeCount = 0;
            mVertexTypes = new Entry[16];
            mIndexTypes = new Vector();
        }

        /**
        * @deprecated in API 16
        * @return internal index of the last vertex buffer type added to
        *         builder
        **/
        public int getCurrentVertexTypeIndex() {
            return mVertexTypeCount - 1;
        }

        /**
        * @deprecated in API 16
        * @return internal index of the last index set added to the
        *         builder
        **/
        public int getCurrentIndexSetIndex() {
            return mIndexTypes.size() - 1;
        }

        /**
        * @deprecated in API 16
        * Adds a vertex data type to the builder object
        *
        * @param t type of the vertex data allocation to be created
        *
        * @return this
        **/
        public Builder addVertexType(Type t) throws IllegalStateException {
            if (mVertexTypeCount >= mVertexTypes.length) {
                throw new IllegalStateException("Max vertex types exceeded.");
            }

            mVertexTypes[mVertexTypeCount] = new Entry();
            mVertexTypes[mVertexTypeCount].t = t;
            mVertexTypes[mVertexTypeCount].e = null;
            mVertexTypeCount++;
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds a vertex data type to the builder object
        *
        * @param e element describing the vertex data layout
        * @param size number of elements in the buffer
        *
        * @return this
        **/
        public Builder addVertexType(Element e, int size) throws IllegalStateException {
            if (mVertexTypeCount >= mVertexTypes.length) {
                throw new IllegalStateException("Max vertex types exceeded.");
            }

            mVertexTypes[mVertexTypeCount] = new Entry();
            mVertexTypes[mVertexTypeCount].t = null;
            mVertexTypes[mVertexTypeCount].e = e;
            mVertexTypes[mVertexTypeCount].size = size;
            mVertexTypeCount++;
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds an index set data type to the builder object
        *
        * @param t type of the index set data, could be null
        * @param p primitive type
        *
        * @return this
        **/
        public Builder addIndexSetType(Type t, Primitive p) {
            Entry indexType = new Entry();
            indexType.t = t;
            indexType.e = null;
            indexType.size = 0;
            indexType.prim = p;
            mIndexTypes.addElement(indexType);
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds an index set primitive type to the builder object
        *
        * @param p primitive type
        *
        * @return this
        **/
        public Builder addIndexSetType(Primitive p) {
            Entry indexType = new Entry();
            indexType.t = null;
            indexType.e = null;
            indexType.size = 0;
            indexType.prim = p;
            mIndexTypes.addElement(indexType);
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds an index set data type to the builder object
        *
        * @param e element describing the index set data layout
        * @param size number of elements in the buffer
        * @param p primitive type
        *
        * @return this
        **/
        public Builder addIndexSetType(Element e, int size, Primitive p) {
            Entry indexType = new Entry();
            indexType.t = null;
            indexType.e = e;
            indexType.size = size;
            indexType.prim = p;
            mIndexTypes.addElement(indexType);
            return this;
        }

        Type newType(Element e, int size) {
            Type.Builder tb = new Type.Builder(mRS, e);
            tb.setX(size);
            return tb.create();
        }

        /**
        * @deprecated in API 16
        * Create a Mesh object from the current state of the builder
        *
        **/
        public Mesh create() {
            mRS.validate();
            long[] vtx = new long[mVertexTypeCount];
            long[] idx = new long[mIndexTypes.size()];
            int[] prim = new int[mIndexTypes.size()];

            Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
            Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
            Primitive[] primitives = new Primitive[mIndexTypes.size()];

            for(int ct = 0; ct < mVertexTypeCount; ct ++) {
                Allocation alloc = null;
                Entry entry = mVertexTypes[ct];
                if (entry.t != null) {
                    alloc = Allocation.createTyped(mRS, entry.t, mUsage);
                } else if(entry.e != null) {
                    alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                } else {
                    // Should never happen because the builder will always set one
                    throw new IllegalStateException("Builder corrupt, no valid element in entry.");
                }
                vertexBuffers[ct] = alloc;
                vtx[ct] = alloc.getID(mRS);
            }

            for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
                Allocation alloc = null;
                Entry entry = (Entry)mIndexTypes.elementAt(ct);
                if (entry.t != null) {
                    alloc = Allocation.createTyped(mRS, entry.t, mUsage);
                } else if(entry.e != null) {
                    alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
                } else {
                    // Should never happen because the builder will always set one
                    throw new IllegalStateException("Builder corrupt, no valid element in entry.");
                }
                long allocID = (alloc == null) ? 0 : alloc.getID(mRS);
                indexBuffers[ct] = alloc;
                primitives[ct] = entry.prim;

                idx[ct] = allocID;
                prim[ct] = entry.prim.mID;
            }

            long id = mRS.nMeshCreate(vtx, idx, prim);
            Mesh newMesh = new Mesh(id, mRS);
            newMesh.mVertexBuffers = vertexBuffers;
            newMesh.mIndexBuffers = indexBuffers;
            newMesh.mPrimitives = primitives;

            return newMesh;
        }
    }

    /**
    * @deprecated in API 16
    * Mesh builder object. It starts empty and requires the user to
    * add all the vertex and index allocations that comprise the
    * mesh
    *
    */
    public static class AllocationBuilder {
        RenderScript mRS;

        class Entry {
            Allocation a;
            Primitive prim;
        }

        int mVertexTypeCount;
        Entry[] mVertexTypes;

        Vector mIndexTypes;

        /**
        * @deprecated in API 16
        **/
        @UnsupportedAppUsage
        public AllocationBuilder(RenderScript rs) {
            mRS = rs;
            mVertexTypeCount = 0;
            mVertexTypes = new Entry[16];
            mIndexTypes = new Vector();
        }

        /**
        * @deprecated in API 16
        * @return internal index of the last vertex buffer type added to
        *         builder
        **/
        public int getCurrentVertexTypeIndex() {
            return mVertexTypeCount - 1;
        }

        /**
        * @deprecated in API 16
        * @return internal index of the last index set added to the
        *         builder
        **/
        public int getCurrentIndexSetIndex() {
            return mIndexTypes.size() - 1;
        }

        /**
        * @deprecated in API 16
        * Adds an allocation containing vertex buffer data to the
        * builder
        *
        * @param a vertex data allocation
        *
        * @return this
        **/
        @UnsupportedAppUsage
        public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException {
            if (mVertexTypeCount >= mVertexTypes.length) {
                throw new IllegalStateException("Max vertex types exceeded.");
            }

            mVertexTypes[mVertexTypeCount] = new Entry();
            mVertexTypes[mVertexTypeCount].a = a;
            mVertexTypeCount++;
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds an allocation containing index buffer data and index type
        * to the builder
        *
        * @param a index set data allocation, could be null
        * @param p index set primitive type
        *
        * @return this
        **/
        @UnsupportedAppUsage
        public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) {
            Entry indexType = new Entry();
            indexType.a = a;
            indexType.prim = p;
            mIndexTypes.addElement(indexType);
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds an index set type to the builder
        *
        * @param p index set primitive type
        *
        * @return this
        **/
        @UnsupportedAppUsage
        public AllocationBuilder addIndexSetType(Primitive p) {
            Entry indexType = new Entry();
            indexType.a = null;
            indexType.prim = p;
            mIndexTypes.addElement(indexType);
            return this;
        }

        /**
        * @deprecated in API 16
        * Create a Mesh object from the current state of the builder
        *
        **/
        @UnsupportedAppUsage
        public Mesh create() {
            mRS.validate();

            long[] vtx = new long[mVertexTypeCount];
            long[] idx = new long[mIndexTypes.size()];
            int[] prim = new int[mIndexTypes.size()];

            Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
            Primitive[] primitives = new Primitive[mIndexTypes.size()];
            Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];

            for(int ct = 0; ct < mVertexTypeCount; ct ++) {
                Entry entry = mVertexTypes[ct];
                vertexBuffers[ct] = entry.a;
                vtx[ct] = entry.a.getID(mRS);
            }

            for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
                Entry entry = (Entry)mIndexTypes.elementAt(ct);
                long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
                indexBuffers[ct] = entry.a;
                primitives[ct] = entry.prim;

                idx[ct] = allocID;
                prim[ct] = entry.prim.mID;
            }

            long id = mRS.nMeshCreate(vtx, idx, prim);
            Mesh newMesh = new Mesh(id, mRS);
            newMesh.mVertexBuffers = vertexBuffers;
            newMesh.mIndexBuffers = indexBuffers;
            newMesh.mPrimitives = primitives;

            return newMesh;
        }
    }

    /**
    * @deprecated in API 16
    * Builder that allows creation of a mesh object point by point
    * and triangle by triangle
    *
    **/
    public static class TriangleMeshBuilder {
        float mVtxData[];
        int mVtxCount;
        int mMaxIndex;
        short mIndexData[];
        int mIndexCount;
        RenderScript mRS;
        Element mElement;

        float mNX = 0;
        float mNY = 0;
        float mNZ = -1;
        float mS0 = 0;
        float mT0 = 0;
        float mR = 1;
        float mG = 1;
        float mB = 1;
        float mA = 1;

        int mVtxSize;
        int mFlags;

        /**
        * @deprecated in API 16
        **/
        public static final int COLOR = 0x0001;
        /**
        * @deprecated in API 16
        **/
        public static final int NORMAL = 0x0002;
        /**
        * @deprecated in API 16
        **/
        public static final int TEXTURE_0 = 0x0100;

        /**
        * @deprecated in API 16
        * @param rs Context to which the mesh will belong.
        * @param vtxSize specifies whether the vertex is a float2 or
        *                float3
        * @param flags bitfield that is a combination of COLOR, NORMAL,
        *              and TEXTURE_0 that specifies what vertex data
        *              channels are present in the mesh
        *
        **/
        @UnsupportedAppUsage
        public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) {
            mRS = rs;
            mVtxCount = 0;
            mMaxIndex = 0;
            mIndexCount = 0;
            mVtxData = new float[128];
            mIndexData = new short[128];
            mVtxSize = vtxSize;
            mFlags = flags;

            if (vtxSize < 2 || vtxSize > 3) {
                throw new IllegalArgumentException("Vertex size out of range.");
            }
        }

        private void makeSpace(int count) {
            if ((mVtxCount + count) >= mVtxData.length) {
                float t[] = new float[mVtxData.length * 2];
                System.arraycopy(mVtxData, 0, t, 0, mVtxData.length);
                mVtxData = t;
            }
        }

        private void latch() {
            if ((mFlags & COLOR) != 0) {
                makeSpace(4);
                mVtxData[mVtxCount++] = mR;
                mVtxData[mVtxCount++] = mG;
                mVtxData[mVtxCount++] = mB;
                mVtxData[mVtxCount++] = mA;
            }
            if ((mFlags & TEXTURE_0) != 0) {
                makeSpace(2);
                mVtxData[mVtxCount++] = mS0;
                mVtxData[mVtxCount++] = mT0;
            }
            if ((mFlags & NORMAL) != 0) {
                makeSpace(4);
                mVtxData[mVtxCount++] = mNX;
                mVtxData[mVtxCount++] = mNY;
                mVtxData[mVtxCount++] = mNZ;
                mVtxData[mVtxCount++] = 0.0f;
            }
            mMaxIndex ++;
        }

        /**
        * @deprecated in API 16
        * Adds a float2 vertex to the mesh
        *
        * @param x position x
        * @param y position y
        *
        * @return this
        *
        **/
        @UnsupportedAppUsage
        public TriangleMeshBuilder addVertex(float x, float y) {
            if (mVtxSize != 2) {
                throw new IllegalStateException("add mistmatch with declared components.");
            }
            makeSpace(2);
            mVtxData[mVtxCount++] = x;
            mVtxData[mVtxCount++] = y;
            latch();
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds a float3 vertex to the mesh
        *
        * @param x position x
        * @param y position y
        * @param z position z
        *
        * @return this
        *
        **/
        public TriangleMeshBuilder addVertex(float x, float y, float z) {
            if (mVtxSize != 3) {
                throw new IllegalStateException("add mistmatch with declared components.");
            }
            makeSpace(4);
            mVtxData[mVtxCount++] = x;
            mVtxData[mVtxCount++] = y;
            mVtxData[mVtxCount++] = z;
            mVtxData[mVtxCount++] = 1.0f;
            latch();
            return this;
        }

        /**
        * @deprecated in API 16
        * Sets the texture coordinate for the vertices that are added after this method call.
        *
        * @param s texture coordinate s
        * @param t texture coordinate t
        *
        * @return this
        **/
        public TriangleMeshBuilder setTexture(float s, float t) {
            if ((mFlags & TEXTURE_0) == 0) {
                throw new IllegalStateException("add mistmatch with declared components.");
            }
            mS0 = s;
            mT0 = t;
            return this;
        }

        /**
        * @deprecated in API 16
        * Sets the normal vector for the vertices that are added after this method call.
        *
        * @param x normal vector x
        * @param y normal vector y
        * @param z normal vector z
        *
        * @return this
        **/
        public TriangleMeshBuilder setNormal(float x, float y, float z) {
            if ((mFlags & NORMAL) == 0) {
                throw new IllegalStateException("add mistmatch with declared components.");
            }
            mNX = x;
            mNY = y;
            mNZ = z;
            return this;
        }

        /**
        * @deprecated in API 16
        * Sets the color for the vertices that are added after this method call.
        *
        * @param r red component
        * @param g green component
        * @param b blue component
        * @param a alpha component
        *
        * @return this
        **/
        public TriangleMeshBuilder setColor(float r, float g, float b, float a) {
            if ((mFlags & COLOR) == 0) {
                throw new IllegalStateException("add mistmatch with declared components.");
            }
            mR = r;
            mG = g;
            mB = b;
            mA = a;
            return this;
        }

        /**
        * @deprecated in API 16
        * Adds a new triangle to the mesh builder
        *
        * @param idx1 index of the first vertex in the triangle
        * @param idx2 index of the second vertex in the triangle
        * @param idx3 index of the third vertex in the triangle
        *
        * @return this
        **/
        @UnsupportedAppUsage
        public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) {
            if((idx1 >= mMaxIndex) || (idx1 < 0) ||
               (idx2 >= mMaxIndex) || (idx2 < 0) ||
               (idx3 >= mMaxIndex) || (idx3 < 0)) {
               throw new IllegalStateException("Index provided greater than vertex count.");
            }
            if ((mIndexCount + 3) >= mIndexData.length) {
                short t[] = new short[mIndexData.length * 2];
                System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
                mIndexData = t;
            }
            mIndexData[mIndexCount++] = (short)idx1;
            mIndexData[mIndexCount++] = (short)idx2;
            mIndexData[mIndexCount++] = (short)idx3;
            return this;
        }

        /**
        * @deprecated in API 16
        * Creates the mesh object from the current state of the builder
        *
        * @param uploadToBufferObject specifies whether the vertex data
        *                             is to be uploaded into the buffer
        *                             object indicating that it's likely
        *                             not going to be modified and
        *                             rendered many times.
        *                             Alternatively, it indicates the
        *                             mesh data will be updated
        *                             frequently and remain in script
        *                             accessible memory
        *
        **/
        @UnsupportedAppUsage
        public Mesh create(boolean uploadToBufferObject) {
            Element.Builder b = new Element.Builder(mRS);
            b.add(Element.createVector(mRS,
                                       Element.DataType.FLOAT_32,
                                       mVtxSize), "position");
            if ((mFlags & COLOR) != 0) {
                b.add(Element.F32_4(mRS), "color");
            }
            if ((mFlags & TEXTURE_0) != 0) {
                b.add(Element.F32_2(mRS), "texture0");
            }
            if ((mFlags & NORMAL) != 0) {
                b.add(Element.F32_3(mRS), "normal");
            }
            mElement = b.create();

            int usage = Allocation.USAGE_SCRIPT;
            if (uploadToBufferObject) {
                usage |= Allocation.USAGE_GRAPHICS_VERTEX;
            }

            Builder smb = new Builder(mRS, usage);
            smb.addVertexType(mElement, mMaxIndex);
            smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);

            Mesh sm = smb.create();

            sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData);
            if(uploadToBufferObject) {
                sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
            }

            sm.getIndexSetAllocation(0).copy1DRangeFromUnchecked(0, mIndexCount, mIndexData);
            if (uploadToBufferObject) {
                sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
            }

            return sm;
        }
    }
}

