/*
 * Copyright (C) 2008 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 java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import android.content.res.Resources;
import android.util.Log;


/**
 * @hide
 *
 * Program is a base class for all the objects that modify
 * various stages of the graphics pipeline
 *
 **/
public class Program extends BaseObj {
    static final int MAX_INPUT = 8;
    static final int MAX_OUTPUT = 8;
    static final int MAX_CONSTANT = 8;
    static final int MAX_TEXTURE = 8;

    /**
     *
     * TextureType specifies what textures are attached to Program
     * objects
     *
     **/
    public enum TextureType {
        TEXTURE_2D (0),
        TEXTURE_CUBE (1);

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

    enum ProgramParam {
        INPUT (0),
        OUTPUT (1),
        CONSTANT (2),
        TEXTURE_TYPE (3);

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

    Element mInputs[];
    Element mOutputs[];
    Type mConstants[];
    TextureType mTextures[];
    String mTextureNames[];
    int mTextureCount;
    String mShader;

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

    /**
     * Program object can have zero or more constant allocations
     * associated with it. This method returns the total count.
     * @return number of constant input types
     */
    public int getConstantCount() {
        return mConstants != null ? mConstants.length : 0;
    }

    /**
     * Returns the type of the constant buffer used in the program
     * object. It could be used to query internal elements or create
     * an allocation to store constant data.
     * @param slot index of the constant input type to return
     * @return constant input type
     */
    public Type getConstant(int slot) {
        if (slot < 0 || slot >= mConstants.length) {
            throw new IllegalArgumentException("Slot ID out of range.");
        }
        return mConstants[slot];
    }

    /**
     * Returns the number of textures used in this program object
     * @return number of texture inputs
     */
    public int getTextureCount() {
        return mTextureCount;
    }

    /**
     * Returns the type of texture at a given slot. e.g. 2D or Cube
     * @param slot index of the texture input
     * @return texture input type
     */
    public TextureType getTextureType(int slot) {
        if ((slot < 0) || (slot >= mTextureCount)) {
            throw new IllegalArgumentException("Slot ID out of range.");
        }
        return mTextures[slot];
    }

    /**
     * Returns the name of the texture input at a given slot. e.g.
     * tex0, diffuse, spec
     * @param slot index of the texture input
     * @return texture input name
     */
    public String getTextureName(int slot) {
        if ((slot < 0) || (slot >= mTextureCount)) {
            throw new IllegalArgumentException("Slot ID out of range.");
        }
        return mTextureNames[slot];
    }

    /**
     * Binds a constant buffer to be used as uniform inputs to the
     * program
     *
     * @param a allocation containing uniform data
     * @param slot index within the program's list of constant
     *             buffer allocations
     */
    public void bindConstants(Allocation a, int slot) {
        if (slot < 0 || slot >= mConstants.length) {
            throw new IllegalArgumentException("Slot ID out of range.");
        }
        if (a != null &&
            a.getType().getID(mRS) != mConstants[slot].getID(mRS)) {
            throw new IllegalArgumentException("Allocation type does not match slot type.");
        }
        long id = a != null ? a.getID(mRS) : 0;
        mRS.nProgramBindConstants(getID(mRS), slot, id);
    }

    /**
     * Binds a texture to be used in the program
     *
     * @param va allocation containing texture data
     * @param slot index within the program's list of textures
     *
     */
    public void bindTexture(Allocation va, int slot)
        throws IllegalArgumentException {
        mRS.validate();
        if ((slot < 0) || (slot >= mTextureCount)) {
            throw new IllegalArgumentException("Slot ID out of range.");
        }
        if (va != null && va.getType().hasFaces() &&
            mTextures[slot] != TextureType.TEXTURE_CUBE) {
            throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
        }

        long id = va != null ? va.getID(mRS) : 0;
        mRS.nProgramBindTexture(getID(mRS), slot, id);
    }

    /**
     * Binds an object that describes how a texture at the
     * corresponding location is sampled
     *
     * @param vs sampler for a corresponding texture
     * @param slot index within the program's list of textures to
     *             use the sampler on
     *
     */
    public void bindSampler(Sampler vs, int slot)
        throws IllegalArgumentException {
        mRS.validate();
        if ((slot < 0) || (slot >= mTextureCount)) {
            throw new IllegalArgumentException("Slot ID out of range.");
        }

        long id = vs != null ? vs.getID(mRS) : 0;
        mRS.nProgramBindSampler(getID(mRS), slot, id);
    }


    public static class BaseProgramBuilder {
        RenderScript mRS;
        Element mInputs[];
        Element mOutputs[];
        Type mConstants[];
        Type mTextures[];
        TextureType mTextureTypes[];
        String mTextureNames[];
        int mInputCount;
        int mOutputCount;
        int mConstantCount;
        int mTextureCount;
        String mShader;


        protected BaseProgramBuilder(RenderScript rs) {
            mRS = rs;
            mInputs = new Element[MAX_INPUT];
            mOutputs = new Element[MAX_OUTPUT];
            mConstants = new Type[MAX_CONSTANT];
            mInputCount = 0;
            mOutputCount = 0;
            mConstantCount = 0;
            mTextureCount = 0;
            mTextureTypes = new TextureType[MAX_TEXTURE];
            mTextureNames = new String[MAX_TEXTURE];
        }

        /**
         * Sets the GLSL shader code to be used in the program
         *
         * @param s GLSL shader string
         * @return  self
         */
        public BaseProgramBuilder setShader(String s) {
            mShader = s;
            return this;
        }

        /**
         * Sets the GLSL shader code to be used in the program
         *
         * @param resources application resources
         * @param resourceID id of the file containing GLSL shader code
         *
         * @return  self
         */
        public BaseProgramBuilder setShader(Resources resources, int resourceID) {
            byte[] str;
            int strLength;
            InputStream is = resources.openRawResource(resourceID);
            try {
                try {
                    str = new byte[1024];
                    strLength = 0;
                    while(true) {
                        int bytesLeft = str.length - strLength;
                        if (bytesLeft == 0) {
                            byte[] buf2 = new byte[str.length * 2];
                            System.arraycopy(str, 0, buf2, 0, str.length);
                            str = buf2;
                            bytesLeft = str.length - strLength;
                        }
                        int bytesRead = is.read(str, strLength, bytesLeft);
                        if (bytesRead <= 0) {
                            break;
                        }
                        strLength += bytesRead;
                    }
                } finally {
                    is.close();
                }
            } catch(IOException e) {
                throw new Resources.NotFoundException();
            }

            try {
                mShader = new String(str, 0, strLength, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                Log.e("RenderScript shader creation", "Could not decode shader string");
            }

            return this;
        }

        /**
         * Queries the index of the last added constant buffer type
         *
         */
        public int getCurrentConstantIndex() {
            return mConstantCount - 1;
        }

        /**
         * Queries the index of the last added texture type
         *
         */
        public int getCurrentTextureIndex() {
            return mTextureCount - 1;
        }

        /**
         * Adds constant (uniform) inputs to the program
         *
         * @param t Type that describes the layout of the Allocation
         *          object to be used as constant inputs to the Program
         * @return  self
         */
        public BaseProgramBuilder addConstant(Type t) throws IllegalStateException {
            // Should check for consistant and non-conflicting names...
            if(mConstantCount >= MAX_CONSTANT) {
                throw new RSIllegalArgumentException("Max input count exceeded.");
            }
            if (t.getElement().isComplex()) {
                throw new RSIllegalArgumentException("Complex elements not allowed.");
            }
            mConstants[mConstantCount] = t;
            mConstantCount++;
            return this;
        }

        /**
         * Adds a texture input to the Program
         *
         * @param texType describes that the texture to append it (2D,
         *                Cubemap, etc.)
         * @return  self
         */
        public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
            addTexture(texType, "Tex" + mTextureCount);
            return this;
        }

        /**
         * Adds a texture input to the Program
         *
         * @param texType describes that the texture to append it (2D,
         *                Cubemap, etc.)
         * @param texName what the texture should be called in the
         *                shader
         * @return  self
         */
        public BaseProgramBuilder addTexture(TextureType texType, String texName)
            throws IllegalArgumentException {
            if(mTextureCount >= MAX_TEXTURE) {
                throw new IllegalArgumentException("Max texture count exceeded.");
            }
            mTextureTypes[mTextureCount] = texType;
            mTextureNames[mTextureCount] = texName;
            mTextureCount ++;
            return this;
        }

        protected void initProgram(Program p) {
            p.mInputs = new Element[mInputCount];
            System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
            p.mOutputs = new Element[mOutputCount];
            System.arraycopy(mOutputs, 0, p.mOutputs, 0, mOutputCount);
            p.mConstants = new Type[mConstantCount];
            System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
            p.mTextureCount = mTextureCount;
            p.mTextures = new TextureType[mTextureCount];
            System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
            p.mTextureNames = new String[mTextureCount];
            System.arraycopy(mTextureNames, 0, p.mTextureNames, 0, mTextureCount);
        }
    }

}


