/*
 * 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 com.android.fountain;

import java.io.InputStream;
import java.io.IOException;

import android.os.Bundle;
import android.content.res.Resources;
import android.util.Log;
import android.util.Config;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.View;
import android.view.Surface;
import android.graphics.Bitmap;
import android.graphics.Color;

public class RenderScript {
    private static final String LOG_TAG = "libRS_jni";
    private static final boolean DEBUG  = false;
    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;



     /*
     * We use a class initializer to allow the native code to cache some
     * field offsets.
     */
    private static boolean sInitialized;
    native private static void _nInit();

    static {
        sInitialized = false;
        try {
            System.loadLibrary("RS_jni");
            _nInit();
            sInitialized = true;
        } catch (UnsatisfiedLinkError e) {
            Log.d(LOG_TAG, "RenderScript JNI library not found!");
        }
    }

    native private int  nDeviceCreate();
    native private void nDeviceDestroy(int dev);
    native private int  nContextCreate(int dev, Surface sur, int ver);
    native private void nContextDestroy(int con);

    //void rsContextBindSampler (uint32_t slot, RsSampler sampler);
    //void rsContextBindRootScript (RsScript sampler);
    native private void nContextBindRootScript(int script);
    native private void nContextBindSampler(int sampler, int slot);
    native private void nContextBindProgramFragmentStore(int pfs);
    native private void nContextBindProgramFragment(int pf);

    native private void nElementBegin();
    native private void nElementAddPredefined(int predef);
    native private void nElementAdd(int kind, int type, int norm, int bits);
    native private int  nElementCreate();
    native private int  nElementGetPredefined(int predef);
    native private void nElementDestroy(int obj);

    native private void nTypeBegin(int elementID);
    native private void nTypeAdd(int dim, int val);
    native private int  nTypeCreate();
    native private void nTypeDestroy(int id);

    native private int  nAllocationCreateTyped(int type);
    native private int  nAllocationCreatePredefSized(int predef, int count);
    native private int  nAllocationCreateSized(int elem, int count);
    native private int  nAllocationCreateFromBitmap(int w, int h, int dstFmt, int srcFmt, boolean genMips, int[] data);

    //native private int  nAllocationCreateFromBitmap(type.mID);
    native private void nAllocationUploadToTexture(int alloc, int baseMioLevel);
    native private void nAllocationDestroy(int alloc);
    native private void nAllocationData(int id, int[] d);
    native private void nAllocationData(int id, float[] d);
    native private void nAllocationSubData1D(int id, int off, int count, int[] d);
    native private void nAllocationSubData1D(int id, int off, int count, float[] d);
    native private void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d);
    native private void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d);

    native private void nTriangleMeshDestroy(int id);
    native private void nTriangleMeshBegin(int vertex, int index);
    native private void nTriangleMeshAddVertex_XY (float x, float y);
    native private void nTriangleMeshAddVertex_XYZ (float x, float y, float z);
    native private void nTriangleMeshAddVertex_XY_ST (float x, float y, float s, float t);
    native private void nTriangleMeshAddVertex_XYZ_ST (float x, float y, float z, float s, float t);
    native private void nTriangleMeshAddTriangle(int i1, int i2, int i3);
    native private int  nTriangleMeshCreate();

    native private void nAdapter1DDestroy(int id);
    native private void nAdapter1DBindAllocation(int ad, int alloc);
    native private void nAdapter1DSetConstraint(int ad, int dim, int value);
    native private void nAdapter1DData(int ad, int[] d);
    native private void nAdapter1DSubData(int ad, int off, int count, int[] d);
    native private void nAdapter1DData(int ad, float[] d);
    native private void nAdapter1DSubData(int ad, int off, int count, float[] d);
    native private int  nAdapter1DCreate();

    native private void nScriptDestroy(int script);
    native private void nScriptBindAllocation(int vtm, int alloc, int slot);
    native private void nScriptCBegin();
    native private void nScriptCSetClearColor(float r, float g, float b, float a);
    native private void nScriptCSetClearDepth(float depth);
    native private void nScriptCSetClearStencil(int stencil);
    native private void nScriptCAddType(int type);
    native private void nScriptCSetRoot(boolean isRoot);
    native private void nScriptCSetScript(byte[] script, int offset, int length);
    native private int  nScriptCCreate();

    native private void nSamplerDestroy(int sampler);
    native private void nSamplerBegin();
    native private void nSamplerSet(int param, int value);
    native private int  nSamplerCreate();

    native private void nProgramFragmentStoreBegin(int in, int out);
    native private void nProgramFragmentStoreDepthFunc(int func);
    native private void nProgramFragmentStoreDepthMask(boolean enable);
    native private void nProgramFragmentStoreColorMask(boolean r, boolean g, boolean b, boolean a);
    native private void nProgramFragmentStoreBlendFunc(int src, int dst);
    native private void nProgramFragmentStoreDither(boolean enable);
    native private int  nProgramFragmentStoreCreate();

    native private void nProgramFragmentBegin(int in, int out);
    native private void nProgramFragmentBindTexture(int vpf, int slot, int a);
    native private void nProgramFragmentBindSampler(int vpf, int slot, int s);
    native private void nProgramFragmentSetType(int slot, int vt);
    native private void nProgramFragmentSetEnvMode(int slot, int env);
    native private void nProgramFragmentSetTexEnable(int slot, boolean enable);
    native private int  nProgramFragmentCreate();


    private int     mDev;
    private int     mContext;
    private Surface mSurface;



    ///////////////////////////////////////////////////////////////////////////////////
    //

    RenderScript(Surface sur) {
        mSurface = sur;
        mDev = nDeviceCreate();
        mContext = nContextCreate(mDev, mSurface, 0);
    }

    private class BaseObj {
        BaseObj() {
            mID = 0;
        }

        int mID;
        protected void finalize() throws Throwable
        {
            if (mID != 0) {
                Log.v(LOG_TAG,
                      "Element finalized without having released the RS reference.");
            }
            super.finalize();
        }
    }


    //////////////////////////////////////////////////////////////////////////////////
    // Element

    public enum ElementPredefined {
        USER_U8 (0),
        USER_I8 (1),
        USER_U16 (2),
        USER_I16 (3),
        USER_U32 (4),
        USER_I32 (5),
        USER_FLOAT (6),

        A_8 (7),
        RGB_565 (8),
        RGBA_5551 (9),
        RGBA_4444 (10),
        RGB_888 (11),
        RGBA_8888 (12),

        INDEX_16 (13),
        INDEX_32 (14),
        XY_F32 (15),
        XYZ_F32 (16),
        ST_XY_F32 (17),
        ST_XYZ_F32 (18),
        NORM_XYZ_F32 (19),
        NORM_ST_XYZ_F32 (20);

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

    public enum DataType {
        FLOAT (0),
        UNSIGNED (1),
        SIGNED (2);

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

    public enum DataKind {
        USER (0),
        RED (1),
        GREEN (2),
        BLUE (3),
        ALPHA (4),
        LUMINANCE (5),
        INTENSITY (6),
        X (7),
        Y (8),
        Z (9),
        W (10),
        S (11),
        T (12),
        Q (13),
        R (14),
        NX (15),
        NY (16),
        NZ (17),
        INDEX (18);

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

    public enum DepthFunc {
        ALWAYS (0),
        LESS (1),
        LEQUAL (2),
        GREATER (3),
        GEQUAL (4),
        EQUAL (5),
        NOTEQUAL (6);

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

    public enum BlendSrcFunc {
        ZERO (0),
        ONE (1),
        DST_COLOR (2),
        ONE_MINUS_DST_COLOR (3),
        SRC_ALPHA (4),
        ONE_MINUS_SRC_ALPHA (5),
        DST_ALPHA (6),
        ONE_MINUS_DST_ALPA (7),
        SRC_ALPHA_SATURATE (8);

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

    public enum BlendDstFunc {
        ZERO (0),
        ONE (1),
        SRC_COLOR (2),
        ONE_MINUS_SRC_COLOR (3),
        SRC_ALPHA (4),
        ONE_MINUS_SRC_ALPHA (5),
        DST_ALPHA (6),
        ONE_MINUS_DST_ALPA (7);

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

    public enum EnvMode {
        REPLACE (0),
        MODULATE (1),
        DECAL (2);

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

    public enum SamplerParam {
        FILTER_MIN (0),
        FILTER_MAG (1),
        WRAP_MODE_S (2),
        WRAP_MODE_T (3),
        WRAP_MODE_R (4);

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

    public enum SamplerValue {
        NEAREST (0),
        LINEAR (1),
        LINEAR_MIP_LINEAR (2),
        WRAP (3),
        CLAMP (4);

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



    public class Element extends BaseObj {
        Element(int id) {
            mID = id;
        }

        public void estroy() {
            nElementDestroy(mID);
            mID = 0;
        }
    }

    public void elementBegin() {
        nElementBegin();
    }

    public void elementAddPredefined(ElementPredefined e) {
        nElementAddPredefined(e.mID);
    }

    public void elementAdd(DataType dt, DataKind dk, boolean isNormalized, int bits) {
        int norm = 0;
        if (isNormalized) {
            norm = 1;
        }
        nElementAdd(dt.mID, dk.mID, norm, bits);
    }

    public Element elementCreate() {
        int id = nElementCreate();
        return new Element(id);
    }

    public Element elementGetPredefined(ElementPredefined predef) {
        int id = nElementGetPredefined(predef.mID);
        return new Element(id);
    }


    //////////////////////////////////////////////////////////////////////////////////
    // Type

    public enum Dimension {
        X (0),
        Y (1),
        Z (2),
        LOD (3),
        FACE (4),
        ARRAY_0 (100);

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

    public class Type extends BaseObj {
        Type(int id) {
            mID = id;
        }

        public void destroy() {
            nTypeDestroy(mID);
            mID = 0;
        }
    }

    public void typeBegin(Element e) {
        nTypeBegin(e.mID);
    }

    public void typeAdd(Dimension d, int value) {
        nTypeAdd(d.mID, value);
    }

    public Type typeCreate() {
        int id = nTypeCreate();
        return new Type(id);
    }


    //////////////////////////////////////////////////////////////////////////////////
    // Allocation

    public class Allocation extends BaseObj {
        Allocation(int id) {
            mID = id;
        }

        public void uploadToTexture(int baseMipLevel) {
            nAllocationUploadToTexture(mID, baseMipLevel);
        }

        public void destroy() {
            nAllocationDestroy(mID);
            mID = 0;
        }

        public void data(int[] d) {
            nAllocationData(mID, d);
        }

        public void data(float[] d) {
            nAllocationData(mID, d);
        }

        public void subData1D(int off, int count, int[] d) {
            nAllocationSubData1D(mID, off, count, d);
        }

        public void subData1D(int off, int count, float[] d) {
            nAllocationSubData1D(mID, off, count, d);
        }

        public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
            nAllocationSubData2D(mID, xoff, yoff, w, h, d);
        }

        public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
            nAllocationSubData2D(mID, xoff, yoff, w, h, d);
        }
    }

    public Allocation allocationCreateTyped(Type type) {
        int id = nAllocationCreateTyped(type.mID);
        return new Allocation(id);
    }

    public Allocation allocationCreatePredefSized(ElementPredefined e, int count) {
        int id = nAllocationCreatePredefSized(e.mID, count);
        return new Allocation(id);
    }

    public Allocation allocationCreateSized(Element e, int count) {
        int id = nAllocationCreateSized(e.mID, count);
        return new Allocation(id);
    }

    public Allocation allocationCreateFromBitmap(Bitmap b, ElementPredefined dstFmt, boolean genMips) {
        int w = b.getWidth();
        int h = b.getHeight();
        int[] data = new int[w * h];

        int outPtr = 0;
        for(int y=0; y < h; y++) {
            for(int x=0; x < w; x++) {
                data[outPtr] = b.getPixel(x, y);
                outPtr++;
            }
        }

        int srcFmt = 0;
        /*
        switch(b.getConfig()) {
        case ALPHA_8:
            srcFmt = ElementPredefined.A_8.mID;
            break;
        case ARGB_4444:
            srcFmt = ElementPredefined.RGBA_4444.mID;
            break;
        case ARGB_8888:
            srcFmt = ElementPredefined.RGBA_8888.mID;
            break;
        case RGB_565:
            srcFmt = ElementPredefined.RGB_565.mID;
            break;
        default:
            Log.e(LOG_TAG, "allocationCreateFromBitmap, unknown bitmap format");
        }
        */

        srcFmt = ElementPredefined.RGBA_8888.mID;

        int id = nAllocationCreateFromBitmap(w, h, dstFmt.mID, srcFmt, genMips, data);
        return new Allocation(id);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Adapter1D

    public class Adapter1D extends BaseObj {
        Adapter1D(int id) {
            mID = id;
        }

        public void destroy() {
            nAdapter1DDestroy(mID);
            mID = 0;
        }

        public void bindAllocation(Allocation a) {
            nAdapter1DBindAllocation(mID, a.mID);
        }

        public void setConstraint(Dimension dim, int value) {
            nAdapter1DSetConstraint(mID, dim.mID, value);
        }

        public void data(int[] d) {
            nAdapter1DData(mID, d);
        }

        public void subData(int off, int count, int[] d) {
            nAdapter1DSubData(mID, off, count, d);
        }

        public void data(float[] d) {
            nAdapter1DData(mID, d);
        }

        public void subData(int off, int count, float[] d) {
            nAdapter1DSubData(mID, off, count, d);
        }
    }

    public Adapter1D adapter1DCreate() {
        int id = nAdapter1DCreate();
        return new Adapter1D(id);
    }


    //////////////////////////////////////////////////////////////////////////////////
    // Triangle Mesh

    public class TriangleMesh extends BaseObj {
        TriangleMesh(int id) {
            mID = id;
        }

        public void destroy() {
            nTriangleMeshDestroy(mID);
            mID = 0;
        }
    }

    public void triangleMeshBegin(Element vertex, Element index) {
        nTriangleMeshBegin(vertex.mID, index.mID);
    }

    public void triangleMeshAddVertex_XY(float x, float y) {
        nTriangleMeshAddVertex_XY(x, y);
    }

    public void triangleMeshAddVertex_XYZ(float x, float y, float z) {
        nTriangleMeshAddVertex_XYZ(x, y, z);
    }

    public void triangleMeshAddVertex_XY_ST(float x, float y, float s, float t) {
        nTriangleMeshAddVertex_XY_ST(x, y, s, t);
    }

    public void triangleMeshAddVertex_XYZ_ST(float x, float y, float z, float s, float t) {
        nTriangleMeshAddVertex_XYZ_ST(x, y, z, s, t);
    }

    public void triangleMeshAddTriangle(int i1, int i2, int i3) {
        nTriangleMeshAddTriangle(i1, i2, i3);
    }

    public TriangleMesh triangleMeshCreate() {
        int id = nTriangleMeshCreate();
        return new TriangleMesh(id);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Script

    public class Script extends BaseObj {
        Script(int id) {
            mID = id;
        }

        public void destroy() {
            nScriptDestroy(mID);
            mID = 0;
        }

        public void bindAllocation(Allocation va, int slot) {
            nScriptBindAllocation(mID, va.mID, slot);
        }
    }

    public void scriptCBegin() {
        nScriptCBegin();
    }

    public void scriptCSetClearColor(float r, float g, float b, float a) {
        nScriptCSetClearColor(r, g, b, a);
    }

    public void scriptCSetClearDepth(float d) {
        nScriptCSetClearDepth(d);
    }

    public void scriptCSetClearStencil(int stencil) {
        nScriptCSetClearStencil(stencil);
    }

    public void scriptCAddType(Type t) {
        nScriptCAddType(t.mID);
    }

    public void scriptCSetRoot(boolean r) {
        nScriptCSetRoot(r);
    }

    public void scriptCSetScript(String s) {
        try {
            byte[] bytes = s.getBytes("UTF-8");
            nScriptCSetScript(bytes, 0, bytes.length);
        } catch (java.io.UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public void scriptCSetScript(Resources resources, int id) {
        InputStream is = resources.openRawResource(id);
        try {
            try {
                scriptCSetScript(is);
            } finally {
                is.close();
            }
        } catch(IOException e) {
            throw new Resources.NotFoundException();
        }
    }

    public void  scriptCSetScript(InputStream is) throws IOException {
        byte[] buf = new byte[1024];
        int currentPos = 0;
        while(true) {
            int bytesLeft = buf.length - currentPos;
            if (bytesLeft == 0) {
                byte[] buf2 = new byte[buf.length * 2];
                System.arraycopy(buf, 0, buf2, 0, buf.length);
                buf = buf2;
                bytesLeft = buf.length - currentPos;
            }
            int bytesRead = is.read(buf, currentPos, bytesLeft);
            if (bytesRead <= 0) {
                break;
            }
            currentPos += bytesRead;
        }
        nScriptCSetScript(buf, 0, currentPos);
    }

    public Script scriptCCreate() {
        int id = nScriptCCreate();
        return new Script(id);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // ProgramFragmentStore

    public class ProgramFragmentStore extends BaseObj {
        ProgramFragmentStore(int id) {
            mID = id;
        }

        public void destroy() {
            nScriptDestroy(mID);
            mID = 0;
        }
    }

    public void programFragmentStoreBegin(Element in, Element out) {
        int inID = 0;
        int outID = 0;
        if (in != null) {
            inID = in.mID;
        }
        if (out != null) {
            outID = out.mID;
        }
        nProgramFragmentStoreBegin(inID, outID);
    }

    public void programFragmentStoreDepthFunc(DepthFunc func) {
        nProgramFragmentStoreDepthFunc(func.mID);
    }

    public void programFragmentStoreDepthMask(boolean enable) {
        nProgramFragmentStoreDepthMask(enable);
    }

    public void programFragmentStoreColorMask(boolean r, boolean g, boolean b, boolean a) {
        nProgramFragmentStoreColorMask(r,g,b,a);
    }

    public void programFragmentStoreBlendFunc(BlendSrcFunc src, BlendDstFunc dst) {
        nProgramFragmentStoreBlendFunc(src.mID, dst.mID);
    }

    public void programFragmentStoreDitherEnable(boolean enable) {
        nProgramFragmentStoreDither(enable);
    }

    public ProgramFragmentStore programFragmentStoreCreate() {
        int id = nProgramFragmentStoreCreate();
        return new ProgramFragmentStore(id);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // ProgramFragment

    public class ProgramFragment extends BaseObj {
        ProgramFragment(int id) {
            mID = id;
        }

        public void destroy() {
            nScriptDestroy(mID);
            mID = 0;
        }

        public void bindTexture(Allocation va, int slot) {
            nProgramFragmentBindTexture(mID, slot, va.mID);
        }

        public void bindSampler(Sampler vs, int slot) {
            nProgramFragmentBindSampler(mID, slot, vs.mID);
        }
    }

    public void programFragmentBegin(Element in, Element out) {
        int inID = 0;
        int outID = 0;
        if (in != null) {
            inID = in.mID;
        }
        if (out != null) {
            outID = out.mID;
        }
        nProgramFragmentBegin(inID, outID);
    }

    public void programFragmentSetType(int slot, Type t) {
        nProgramFragmentSetType(slot, t.mID);
    }

    public void programFragmentSetType(int slot, EnvMode t) {
        nProgramFragmentSetEnvMode(slot, t.mID);
    }

    public void programFragmentSetTexEnable(int slot, boolean enable) {
        nProgramFragmentSetTexEnable(slot, enable);
    }

    public ProgramFragment programFragmentCreate() {
        int id = nProgramFragmentCreate();
        return new ProgramFragment(id);
    }

    //////////////////////////////////////////////////////////////////////////////////
    // Sampler

    public class Sampler extends BaseObj {
        Sampler(int id) {
            mID = id;
        }

        public void destroy() {
            nSamplerDestroy(mID);
            mID = 0;
        }
    }

    public void samplerBegin() {
        nSamplerBegin();
    }

    public void samplerSet(SamplerParam p, SamplerValue v) {
        nSamplerSet(p.mID, v.mID);
    }

    public Sampler samplerCreate() {
        int id = nSamplerCreate();
        return new Sampler(id);
    }


    ///////////////////////////////////////////////////////////////////////////////////
    // Root state

    public void contextBindRootScript(Script s) {
        nContextBindRootScript(s.mID);
    }

    //public void contextBindSampler(Sampler s, int slot) {
        //nContextBindSampler(s.mID);
    //}

    public void contextBindProgramFragmentStore(ProgramFragmentStore pfs) {
        nContextBindProgramFragmentStore(pfs.mID);
    }

    public void contextBindProgramFragment(ProgramFragment pf) {
        nContextBindProgramFragment(pf.mID);
    }

/*
    RsAdapter2D rsAdapter2DCreate ();
    void rsAdapter2DBindAllocation (RsAdapter2D adapt, RsAllocation alloc);
    void rsAdapter2DDestroy (RsAdapter2D adapter);
    void rsAdapter2DSetConstraint (RsAdapter2D adapter, RsDimension dim, uint32_t value);
    void rsAdapter2DData (RsAdapter2D adapter, const void * data);
    void rsAdapter2DSubData (RsAdapter2D adapter, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void * data);
    void rsSamplerBegin ();
    void rsSamplerSet (RsSamplerParam p, RsSamplerValue value);
    RsSampler rsSamplerCreate ();
    void rsSamplerBind (RsSampler sampler, RsAllocation alloc);
*/

}

