/*
 * Copyright (C) 2013 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;

/**
 * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link
 * android.renderscript.Allocation} or a parallel operation. Types are created through {@link
 * android.renderscript.Type.Builder}.</p>
 *
 * <p>A Type always includes an {@link android.renderscript.Element} and an X
 * dimension. A Type may be multidimensional, up to three dimensions. A nonzero
 * value in the Y or Z dimensions indicates that the dimension is present. Note
 * that a Type with only a given X dimension and a Type with the same X
 * dimension but Y = 1 are not equivalent.</p>
 *
 * <p>A Type also supports inclusion of level of detail (LOD) or cube map
 * faces. LOD and cube map faces are booleans to indicate present or not
 * present. </p>
 *
 * <p>A Type also supports YUV format information to support an
 * {@link android.renderscript.Allocation} in a YUV format. The YUV formats
 * supported are {@link android.graphics.ImageFormat#YV12},
 * {@link android.graphics.ImageFormat#NV21}, and
 * {@link android.graphics.ImageFormat#YUV_420_888}</p>
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For more information about creating an application that uses RenderScript, read the
 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
 * </div>
 **/
public class Type extends BaseObj {
    int mDimX;
    int mDimY;
    int mDimZ;
    boolean mDimMipmaps;
    boolean mDimFaces;
    int mDimYuv;
    int mElementCount;
    Element mElement;
    int mArrays[];

    static final int mMaxArrays = 4;

    public enum CubemapFace {
        POSITIVE_X (0),
        NEGATIVE_X (1),
        POSITIVE_Y (2),
        NEGATIVE_Y (3),
        POSITIVE_Z (4),
        NEGATIVE_Z (5),
        @Deprecated
        POSITVE_X (0),
        @Deprecated
        POSITVE_Y (2),
        @Deprecated
        POSITVE_Z (4);

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

    /**
     * Return the element associated with this Type.
     *
     * @return Element
     */
    public Element getElement() {
        return mElement;
    }

    /**
     * Return the value of the X dimension.
     *
     * @return int
     */
    public int getX() {
        return mDimX;
    }

    /**
     * Return the value of the Y dimension or 0 for a 1D allocation.
     *
     * @return int
     */
    public int getY() {
        return mDimY;
    }

    /**
     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
     *
     * @return int
     */
    public int getZ() {
        return mDimZ;
    }

    /**
     * Get the YUV format
     *
     *
     * @return int
     */
    public int getYuv() {
        return mDimYuv;
    }

    /**
     * Return if the Type has a mipmap chain.
     *
     * @return boolean
     */
    public boolean hasMipmaps() {
        return mDimMipmaps;
    }

    /**
     * Return if the Type is a cube map.
     *
     * @return boolean
     */
    public boolean hasFaces() {
        return mDimFaces;
    }

    /**
     * Return the total number of accessable cells in the Type.
     *
     * @return int
     */
    public int getCount() {
        return mElementCount;
    }

    /**
     * @hide
      * Return the dimension of the specified array.
      *
      * @param arrayNum  The array dimension to query
      * @return int
      */
    public int getArray(int arrayNum) {
        if ((arrayNum < 0) || (arrayNum >= mMaxArrays)) {
            throw new RSIllegalArgumentException("Array dimension out of range.");
        }

        if (mArrays == null || arrayNum >= mArrays.length) {
            // Dimension in range but no array for that dimension allocated
            return 0;
        }

        return mArrays[arrayNum];
    }

    /**
     * @hide
      * Return the number of array dimensions.
      *
      * @return int
      */
    public int getArrayCount() {
        if (mArrays != null) return mArrays.length;
        return 0;
    }

    void calcElementCount() {
        boolean hasLod = hasMipmaps();
        int x = getX();
        int y = getY();
        int z = getZ();
        int faces = 1;
        if (hasFaces()) {
            faces = 6;
        }
        if (x == 0) {
            x = 1;
        }
        if (y == 0) {
            y = 1;
        }
        if (z == 0) {
            z = 1;
        }

        int count = x * y * z * faces;

        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
            if(x > 1) {
                x >>= 1;
            }
            if(y > 1) {
                y >>= 1;
            }
            if(z > 1) {
                z >>= 1;
            }

            count += x * y * z * faces;
        }

        if (mArrays != null) {
            for (int ct = 0; ct < mArrays.length; ct++) {
                count *= mArrays[ct];
            }
        }

        mElementCount = count;
    }


    Type(long id, RenderScript rs) {
        super(id, rs);
    }

    @Override
    void updateFromNative() {
        // We have 6 integer/long to obtain mDimX; mDimY; mDimZ;
        // mDimLOD; mDimFaces; mElement;
        long[] dataBuffer = new long[6];
        mRS.nTypeGetNativeData(getID(mRS), dataBuffer);

        mDimX = (int)dataBuffer[0];
        mDimY = (int)dataBuffer[1];
        mDimZ = (int)dataBuffer[2];
        mDimMipmaps = dataBuffer[3] == 1 ? true : false;
        mDimFaces = dataBuffer[4] == 1 ? true : false;

        long elementID = dataBuffer[5];
        if(elementID != 0) {
            mElement = new Element(elementID, mRS);
            mElement.updateFromNative();
        }
        calcElementCount();
    }

    /**
     * Utility function for creating basic 1D types. The type is
     * created without mipmaps enabled.
     *
     * @param rs The RenderScript context
     * @param e The Element for the Type
     * @param dimX The X dimension, must be > 0
     *
     * @return Type
     */
    static public Type createX(RenderScript rs, Element e, int dimX) {
        if (dimX < 1) {
            throw new RSInvalidStateException("Dimension must be >= 1.");
        }

        long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
        Type t = new Type(id, rs);
        t.mElement = e;
        t.mDimX = dimX;
        t.calcElementCount();
        return t;
    }

    /**
     * Utility function for creating basic 2D types. The type is
     * created without mipmaps or cubemaps.
     *
     * @param rs The RenderScript context
     * @param e The Element for the Type
     * @param dimX The X dimension, must be > 0
     * @param dimY The Y dimension, must be > 0
     *
     * @return Type
     */
    static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
        if ((dimX < 1) || (dimY < 1)) {
            throw new RSInvalidStateException("Dimension must be >= 1.");
        }

        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
        Type t = new Type(id, rs);
        t.mElement = e;
        t.mDimX = dimX;
        t.mDimY = dimY;
        t.calcElementCount();
        return t;
    }

    /**
     * Utility function for creating basic 3D types. The type is
     * created without mipmaps.
     *
     * @param rs The RenderScript context
     * @param e The Element for the Type
     * @param dimX The X dimension, must be > 0
     * @param dimY The Y dimension, must be > 0
     * @param dimZ The Z dimension, must be > 0
     *
     * @return Type
     */
    static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
        if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
            throw new RSInvalidStateException("Dimension must be >= 1.");
        }

        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
        Type t = new Type(id, rs);
        t.mElement = e;
        t.mDimX = dimX;
        t.mDimY = dimY;
        t.mDimZ = dimZ;
        t.calcElementCount();
        return t;
    }

    /**
     * Builder class for Type.
     *
     */
    public static class Builder {
        RenderScript mRS;
        int mDimX = 1;
        int mDimY;
        int mDimZ;
        boolean mDimMipmaps;
        boolean mDimFaces;
        int mYuv;
        int[] mArray = new int[mMaxArrays];

        Element mElement;

        /**
         * Create a new builder object.
         *
         * @param rs
         * @param e The element for the type to be created.
         */
        public Builder(RenderScript rs, Element e) {
            e.checkValid();
            mRS = rs;
            mElement = e;
        }

        /**
         * Add a dimension to the Type.
         *
         *
         * @param value
         */
        public Builder setX(int value) {
            if(value < 1) {
                throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
            }
            mDimX = value;
            return this;
        }

        public Builder setY(int value) {
            if(value < 1) {
                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
            }
            mDimY = value;
            return this;
        }

        public Builder setZ(int value) {
            if(value < 1) {
                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
            }
            mDimZ = value;
            return this;
        }

        /**
         * @hide
         * Adds an array dimension to the builder
         *
         * @param dim
         * @param value
         *
         * @return Builder
         */
        public Builder setArray(int dim, int value) {
            if(dim < 0 || dim >= mMaxArrays) {
                throw new RSIllegalArgumentException("Array dimension out of range.");
            }
            mArray[dim] = value;
            return this;
        }

        public Builder setMipmaps(boolean value) {
            mDimMipmaps = value;
            return this;
        }

        public Builder setFaces(boolean value) {
            mDimFaces = value;
            return this;
        }

        /**
         * Set the YUV layout for a Type.
         *
         * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or
         * {@link android.graphics.ImageFormat#YUV_420_888}.
         */
        public Builder setYuvFormat(int yuvFormat) {
            switch (yuvFormat) {
            case android.graphics.ImageFormat.NV21:
            case android.graphics.ImageFormat.YV12:
            case android.graphics.ImageFormat.YUV_420_888:
                break;

            default:
                throw new RSIllegalArgumentException(
                    "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported..");
            }

            mYuv = yuvFormat;
            return this;
        }


        /**
         * Validate structure and create a new Type.
         *
         * @return Type
         */
        public Type create() {
            if (mDimZ > 0) {
                if ((mDimX < 1) || (mDimY < 1)) {
                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
                }
                if (mDimFaces) {
                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
                }
            }
            if (mDimY > 0) {
                if (mDimX < 1) {
                    throw new RSInvalidStateException("X dimension required when Y is present.");
                }
            }
            if (mDimFaces) {
                if (mDimY < 1) {
                    throw new RSInvalidStateException("Cube maps require 2D Types.");
                }
            }

            if (mYuv != 0) {
                if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
                    throw new RSInvalidStateException("YUV only supports basic 2D.");
                }
            }

            int[] arrays = null;
            for (int ct = mMaxArrays - 1; ct >= 0; ct--) {
                if (mArray[ct] != 0 && arrays == null) {
                    arrays = new int[ct];
                }
                if ((mArray[ct] == 0) && (arrays != null)) {
                    throw new RSInvalidStateException("Array dimensions must be contigous from 0.");
                }
            }

            long id = mRS.nTypeCreate(mElement.getID(mRS),
                                     mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
            Type t = new Type(id, mRS);
            t.mElement = mElement;
            t.mDimX = mDimX;
            t.mDimY = mDimY;
            t.mDimZ = mDimZ;
            t.mDimMipmaps = mDimMipmaps;
            t.mDimFaces = mDimFaces;
            t.mDimYuv = mYuv;
            t.mArrays = arrays;

            t.calcElementCount();
            return t;
        }
    }

}
