/*
 * 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 android.util.Log;


/**
 * <p>ProgramFragmentFixedFunction is a helper class that provides
 * a way to make a simple fragment shader without writing any
 * GLSL code. This class allows for display of constant color, interpolated
 * color from the vertex shader, or combinations of the both
 * blended with results of up to two texture lookups.</p
 *
 **/
public class ProgramFragmentFixedFunction extends ProgramFragment {
    ProgramFragmentFixedFunction(int id, RenderScript rs) {
        super(id, rs);
    }

    static class InternalBuilder extends BaseProgramBuilder {
        public InternalBuilder(RenderScript rs) {
            super(rs);
        }

        /**
         * Creates ProgramFragmentFixedFunction from the current state
         * of the builder
         *
         * @return  ProgramFragmentFixedFunction
         */
        public ProgramFragmentFixedFunction create() {
            mRS.validate();
            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
            int idx = 0;

            for (int i=0; i < mInputCount; i++) {
                tmp[idx++] = ProgramParam.INPUT.mID;
                tmp[idx++] = mInputs[i].getID();
            }
            for (int i=0; i < mOutputCount; i++) {
                tmp[idx++] = ProgramParam.OUTPUT.mID;
                tmp[idx++] = mOutputs[i].getID();
            }
            for (int i=0; i < mConstantCount; i++) {
                tmp[idx++] = ProgramParam.CONSTANT.mID;
                tmp[idx++] = mConstants[i].getID();
            }
            for (int i=0; i < mTextureCount; i++) {
                tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
                tmp[idx++] = mTextureTypes[i].mID;
            }

            int id = mRS.nProgramFragmentCreate(mShader, tmp);
            ProgramFragmentFixedFunction pf = new ProgramFragmentFixedFunction(id, mRS);
            initProgram(pf);
            return pf;
        }
    }

    public static class Builder {
        public static final int MAX_TEXTURE = 2;
        int mNumTextures;
        boolean mPointSpriteEnable;
        boolean mVaryingColorEnable;
        String mShader;
        RenderScript mRS;

        /**
         * EnvMode describes how textures are combined with the existing
         * color in the fixed function fragment shader
         *
         **/
        public enum EnvMode {
            REPLACE (1),
            MODULATE (2),
            DECAL (3);

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

        /**
         * Format describes the pixel format of textures in the fixed
         * function fragment shader and how they are sampled
         *
         **/
        public enum Format {
            ALPHA (1),
            LUMINANCE_ALPHA (2),
            RGB (3),
            RGBA (4);

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

        private class Slot {
            EnvMode env;
            Format format;
            Slot(EnvMode _env, Format _fmt) {
                env = _env;
                format = _fmt;
            }
        }
        Slot[] mSlots;

        private void buildShaderString() {
            mShader  = "//rs_shader_internal\n";
            mShader += "varying lowp vec4 varColor;\n";
            mShader += "varying vec2 varTex0;\n";

            mShader += "void main() {\n";
            if (mVaryingColorEnable) {
                mShader += "  lowp vec4 col = varColor;\n";
            } else {
                mShader += "  lowp vec4 col = UNI_Color;\n";
            }

            if (mNumTextures != 0) {
                if (mPointSpriteEnable) {
                    mShader += "  vec2 t0 = gl_PointCoord;\n";
                } else {
                    mShader += "  vec2 t0 = varTex0.xy;\n";
                }
            }

            for(int i = 0; i < mNumTextures; i ++) {
                switch(mSlots[i].env) {
                case REPLACE:
                    switch (mSlots[i].format) {
                    case ALPHA:
                        mShader += "  col.a = texture2D(UNI_Tex0, t0).a;\n";
                        break;
                    case LUMINANCE_ALPHA:
                        mShader += "  col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
                        break;
                    case RGB:
                        mShader += "  col.rgb = texture2D(UNI_Tex0, t0).rgb;\n";
                        break;
                    case RGBA:
                        mShader += "  col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
                        break;
                    }
                    break;
                case MODULATE:
                    switch (mSlots[i].format) {
                    case ALPHA:
                        mShader += "  col.a *= texture2D(UNI_Tex0, t0).a;\n";
                        break;
                    case LUMINANCE_ALPHA:
                        mShader += "  col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
                        break;
                    case RGB:
                        mShader += "  col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n";
                        break;
                    case RGBA:
                        mShader += "  col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
                        break;
                    }
                    break;
                case DECAL:
                    mShader += "  col = texture2D(UNI_Tex0, t0);\n";
                    break;
                }
            }

            mShader += "  gl_FragColor = col;\n";
            mShader += "}\n";
        }

        /**
         * Creates a builder for fixed function fragment program
         *
         * @param rs Context to which the program will belong.
         */
        public Builder(RenderScript rs) {
            mRS = rs;
            mSlots = new Slot[MAX_TEXTURE];
            mPointSpriteEnable = false;
        }

        /**
         * Adds a texture to be fetched as part of the fixed function
         * fragment program
         *
         * @param env specifies how the texture is combined with the
         *            current color
         * @param fmt specifies the format of the texture and how its
         *            components will be used to combine with the
         *            current color
         * @param slot index of the texture to apply the operations on
         *
         * @return this
         */
        public Builder setTexture(EnvMode env, Format fmt, int slot)
            throws IllegalArgumentException {
            if((slot < 0) || (slot >= MAX_TEXTURE)) {
                throw new IllegalArgumentException("MAX_TEXTURE exceeded.");
            }
            mSlots[slot] = new Slot(env, fmt);
            return this;
        }

        /**
         * Specifies whether the texture coordinate passed from the
         * vertex program is replaced with an openGL internal point
         * sprite texture coordinate
         *
         **/
        public Builder setPointSpriteTexCoordinateReplacement(boolean enable) {
            mPointSpriteEnable = enable;
            return this;
        }

        /**
         * Specifies whether the varying color passed from the vertex
         * program or the constant color set on the fragment program is
         * used in the final color calculation in the fixed function
         * fragment shader
         *
         **/
        public Builder setVaryingColor(boolean enable) {
            mVaryingColorEnable = enable;
            return this;
        }

        /**
        * Creates the fixed function fragment program from the current
        * state of the builder.
        *
        */
        public ProgramFragmentFixedFunction create() {
            InternalBuilder sb = new InternalBuilder(mRS);
            mNumTextures = 0;
            for(int i = 0; i < MAX_TEXTURE; i ++) {
                if(mSlots[i] != null) {
                    mNumTextures ++;
                }
            }
            buildShaderString();
            sb.setShader(mShader);

            Type constType = null;
            if (!mVaryingColorEnable) {
                Element.Builder b = new Element.Builder(mRS);
                b.add(Element.F32_4(mRS), "Color");
                Type.Builder typeBuilder = new Type.Builder(mRS, b.create());
                typeBuilder.setX(1);
                constType = typeBuilder.create();
                sb.addConstant(constType);
            }
            for (int i = 0; i < mNumTextures; i ++) {
                sb.addTexture(TextureType.TEXTURE_2D);
            }

            ProgramFragmentFixedFunction pf = sb.create();
            pf.mTextureCount = MAX_TEXTURE;
            if (!mVaryingColorEnable) {
                Allocation constantData = Allocation.createTyped(mRS,constType);
                FieldPacker fp = new FieldPacker(16);
                Float4 f4 = new Float4(1.f, 1.f, 1.f, 1.f);
                fp.addF32(f4);
                constantData.setFromFieldPacker(0, fp);
                pf.bindConstants(constantData, 0);
            }
            return pf;
        }
    }
}




