/*
 * Copyright (C) 2009 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.
 */

#include "rsContext.h"
#include "rsProgramFragment.h"

#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

using namespace android;
using namespace android::renderscript;


ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
                                 uint32_t paramLength) :
    Program(rsc)
{
    mAllocFile = __FILE__;
    mAllocLine = __LINE__;
    rsAssert(paramLength = 5);

    mEnvModes[0] = (RsTexEnvMode)params[0];
    mTextureFormats[0] = params[1];
    mEnvModes[1] = (RsTexEnvMode)params[2];
    mTextureFormats[1] = params[3];
    mPointSpriteEnable = params[4] != 0;

    mTextureEnableMask = 0;
    if (mEnvModes[0]) {
        mTextureEnableMask |= 1;
    }
    if (mEnvModes[1]) {
        mTextureEnableMask |= 2;
    }
    init(rsc);
}

ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
                                 uint32_t shaderLength, const uint32_t * params,
                                 uint32_t paramLength) :
    Program(rsc, shaderText, shaderLength, params, paramLength)
{
    mAllocFile = __FILE__;
    mAllocLine = __LINE__;

    init(rsc);
    mTextureEnableMask = (1 << mTextureCount) -1;
}


ProgramFragment::~ProgramFragment()
{
}

void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
{
    if ((state->mLast.get() == this) && !mDirty) {
        return;
    }
    state->mLast.set(this);

    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
        glActiveTexture(GL_TEXTURE0 + ct);
        if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
            glDisable(GL_TEXTURE_2D);
            continue;
        }

        glEnable(GL_TEXTURE_2D);
        if (rsc->checkVersion1_1()) {
            if (mPointSpriteEnable) {
                glEnable(GL_POINT_SPRITE_OES);
            } else {
                glDisable(GL_POINT_SPRITE_OES);
            }
            glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
        }
        mTextures[ct]->uploadCheck(rsc);
        glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());

        switch(mEnvModes[ct]) {
        case RS_TEX_ENV_MODE_NONE:
            rsAssert(0);
            break;
        case RS_TEX_ENV_MODE_REPLACE:
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
            break;
        case RS_TEX_ENV_MODE_MODULATE:
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
            break;
        case RS_TEX_ENV_MODE_DECAL:
            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
            break;
        }

        if (mSamplers[ct].get()) {
            mSamplers[ct]->setupGL(rsc);
        } else {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        }

        // Gross hack.
        if (ct == 2) {
            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

            glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
            glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
            glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

            glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
            glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
            glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
        }
    }
    glActiveTexture(GL_TEXTURE0);
    mDirty = false;
    rsc->checkError("ProgramFragment::setupGL");
}

void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
{

    //LOGE("sgl2 frag1 %x", glGetError());
    if ((state->mLast.get() == this) && !mDirty) {
        //return;
    }
    state->mLast.set(this);

    rsc->checkError("ProgramFragment::setupGL2 start");
    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
        glActiveTexture(GL_TEXTURE0 + ct);
        if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
            continue;
        }

        mTextures[ct]->uploadCheck(rsc);
        glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
        rsc->checkError("ProgramFragment::setupGL2 tex bind");
        if (mSamplers[ct].get()) {
            mSamplers[ct]->setupGL(rsc);
        } else {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            rsc->checkError("ProgramFragment::setupGL2 tex env");
        }

        glUniform1i(sc->fragUniformSlot(ct), ct);
        rsc->checkError("ProgramFragment::setupGL2 uniforms");
    }

    glActiveTexture(GL_TEXTURE0);
    mDirty = false;
    rsc->checkError("ProgramFragment::setupGL2");
}

void ProgramFragment::loadShader(Context *rsc) {
    Program::loadShader(rsc, GL_FRAGMENT_SHADER);
}

void ProgramFragment::createShader()
{
    mShader.setTo("precision mediump float;\n");
    mShader.append("varying vec4 varColor;\n");
    mShader.append("varying vec4 varTex0;\n");

    if (mUserShader.length() > 1) {
        for (uint32_t ct=0; ct < mTextureCount; ct++) {
            char buf[256];
            sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
            mShader.append(buf);
        }

        mShader.append(mUserShader);
    } else {
        uint32_t mask = mTextureEnableMask;
        uint32_t texNum = 0;
        while (mask) {
            if (mask & 1) {
                char buf[64];
                mShader.append("uniform sampler2D uni_Tex");
                sprintf(buf, "%i", texNum);
                mShader.append(buf);
                mShader.append(";\n");
            }
            mask >>= 1;
            texNum++;
        }


        mShader.append("void main() {\n");
        mShader.append("  vec4 col = varColor;\n");

        if (mTextureEnableMask) {
            if (mPointSpriteEnable) {
                mShader.append("  vec2 t0 = gl_PointCoord;\n");
            } else {
                mShader.append("  vec2 t0 = varTex0.xy;\n");
            }
        }

        mask = mTextureEnableMask;
        texNum = 0;
        while (mask) {
            if (mask & 1) {
                switch(mEnvModes[texNum]) {
                case RS_TEX_ENV_MODE_NONE:
                    rsAssert(0);
                    break;
                case RS_TEX_ENV_MODE_REPLACE:
                    switch(mTextureFormats[texNum]) {
                    case 1:
                        mShader.append("  col.a = texture2D(uni_Tex0, t0).a;\n");
                        break;
                    case 2:
                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
                        break;
                    case 3:
                        mShader.append("  col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
                        break;
                    case 4:
                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
                        break;
                    }
                    break;
                case RS_TEX_ENV_MODE_MODULATE:
                    switch(mTextureFormats[texNum]) {
                    case 1:
                        mShader.append("  col.a *= texture2D(uni_Tex0, t0).a;\n");
                        break;
                    case 2:
                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
                        break;
                    case 3:
                        mShader.append("  col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
                        break;
                    case 4:
                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
                        break;
                    }
                    break;
                case RS_TEX_ENV_MODE_DECAL:
                    mShader.append("  col = texture2D(uni_Tex0, t0);\n");
                    break;
                }

            }
            mask >>= 1;
            texNum++;
        }

        //mShader.append("  col.a = 1.0;\n");
        //mShader.append("  col.r = 0.5;\n");

        mShader.append("  gl_FragColor = col;\n");
        mShader.append("}\n");
    }
}

void ProgramFragment::init(Context *rsc)
{
    mUniformCount = 2;
    mUniformNames[0].setTo("uni_Tex0");
    mUniformNames[1].setTo("uni_Tex1");

    createShader();
}

ProgramFragmentState::ProgramFragmentState()
{
    mPF = NULL;
}

ProgramFragmentState::~ProgramFragmentState()
{
    delete mPF;

}

void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
{
    uint32_t tmp[5] = {
        RS_TEX_ENV_MODE_NONE, 0,
        RS_TEX_ENV_MODE_NONE, 0,
        0
    };
    ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
    mDefault.set(pf);
    pf->init(rsc);
}

void ProgramFragmentState::deinit(Context *rsc)
{
    mDefault.clear();
    mLast.clear();
}


namespace android {
namespace renderscript {

RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
                                            const uint32_t * params,
                                            uint32_t paramLength)
{
    ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
    pf->incUserRef();
    return pf;
}

RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
                             uint32_t shaderLength, const uint32_t * params,
                             uint32_t paramLength)
{
    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
    pf->incUserRef();
    return pf;
}

}
}

