/*
 * 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.
 */

package com.android.rs.image;

import android.app.Activity;
import android.os.Bundle;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.renderscript.ScriptC;
import android.renderscript.RenderScript;
import android.renderscript.Type;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.Script;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.view.View;
import java.lang.Math;

public class ImageProcessingActivity extends Activity
                                       implements SurfaceHolder.Callback,
                                       SeekBar.OnSeekBarChangeListener {
    private Bitmap mBitmapIn;
    private Bitmap mBitmapOut;
    private Bitmap mBitmapScratch;
    private ScriptC_threshold mScript;
    private ScriptC_vertical_blur mScriptVBlur;
    private ScriptC_horizontal_blur mScriptHBlur;
    private int mRadius = 0;
    private SeekBar mRadiusSeekBar;

    private float mInBlack = 0.0f;
    private SeekBar mInBlackSeekBar;
    private float mOutBlack = 0.0f;
    private SeekBar mOutBlackSeekBar;
    private float mInWhite = 255.0f;
    private SeekBar mInWhiteSeekBar;
    private float mOutWhite = 255.0f;
    private SeekBar mOutWhiteSeekBar;
    private float mGamma = 1.0f;
    private SeekBar mGammaSeekBar;

    private float mSaturation = 1.0f;
    private SeekBar mSaturationSeekBar;

    private TextView mBenchmarkResult;

    @SuppressWarnings({"FieldCanBeLocal"})
    private RenderScript mRS;
    @SuppressWarnings({"FieldCanBeLocal"})
    private Type mPixelType;
    @SuppressWarnings({"FieldCanBeLocal"})
    private Allocation mInPixelsAllocation;
    @SuppressWarnings({"FieldCanBeLocal"})
    private Allocation mOutPixelsAllocation;
    @SuppressWarnings({"FieldCanBeLocal"})
    private Allocation mScratchPixelsAllocation1;
    private Allocation mScratchPixelsAllocation2;

    private SurfaceView mSurfaceView;
    private ImageView mDisplayView;

    class FilterCallback extends RenderScript.RSMessageHandler {
        private Runnable mAction = new Runnable() {
            public void run() {
                mDisplayView.invalidate();
            }
        };

        @Override
        public void run() {
            mSurfaceView.removeCallbacks(mAction);
            mSurfaceView.post(mAction);
        }
    }

    int in[];
    int interm[];
    int out[];
    int MAX_RADIUS = 25;
    // Store our coefficients here
    float gaussian[];

    private long javaFilter() {
        final int width = mBitmapIn.getWidth();
        final int height = mBitmapIn.getHeight();
        final int count = width * height;

        if (in == null) {
            in = new int[count];
            interm = new int[count];
            out = new int[count];
            gaussian = new float[MAX_RADIUS * 2 + 1];
            mBitmapIn.getPixels(in, 0, width, 0, 0, width, height);
        }

        long t = java.lang.System.currentTimeMillis();

        int w, h, r;

        float fRadius = (float)mRadius;
        int radius = (int)mRadius;

        // Compute gaussian weights for the blur
        // e is the euler's number
        float e = 2.718281828459045f;
        float pi = 3.1415926535897932f;
        // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
        // x is of the form [-radius .. 0 .. radius]
        // and sigma varies with radius.
        // Based on some experimental radius values and sigma's
        // we approximately fit sigma = f(radius) as
        // sigma = radius * 0.4  + 0.6
        // The larger the radius gets, the more our gaussian blur
        // will resemble a box blur since with large sigma
        // the gaussian curve begins to lose its shape
        float sigma = 0.4f * fRadius + 0.6f;
        // Now compute the coefficints
        // We will store some redundant values to save some math during
        // the blur calculations
        // precompute some values
        float coeff1 = 1.0f / (float)(Math.sqrt( 2.0f * pi ) * sigma);
        float coeff2 = - 1.0f / (2.0f * sigma * sigma);
        float normalizeFactor = 0.0f;
        float floatR = 0.0f;
        for (r = -radius; r <= radius; r ++) {
            floatR = (float)r;
            gaussian[r + radius] = coeff1 * (float)Math.pow(e, floatR * floatR * coeff2);
            normalizeFactor += gaussian[r + radius];
        }

        //Now we need to normalize the weights because all our coefficients need to add up to one
        normalizeFactor = 1.0f / normalizeFactor;
        for (r = -radius; r <= radius; r ++) {
            floatR = (float)r;
            gaussian[r + radius] *= normalizeFactor;
        }

        float blurredPixelR = 0.0f;
        float blurredPixelG = 0.0f;
        float blurredPixelB = 0.0f;
        float blurredPixelA = 0.0f;

        for (h = 0; h < height; h ++) {
            for (w = 0; w < width; w ++) {

                blurredPixelR = 0.0f;
                blurredPixelG = 0.0f;
                blurredPixelB = 0.0f;
                blurredPixelA = 0.0f;

                for (r = -radius; r <= radius; r ++) {
                    // Stepping left and right away from the pixel
                    int validW = w + r;
                    // Clamp to zero and width max() isn't exposed for ints yet
                    if (validW < 0) {
                        validW = 0;
                    }
                    if (validW > width - 1) {
                        validW = width - 1;
                    }

                    int input = in[h*width + validW];

                    int R = ((input >> 24) & 0xff);
                    int G = ((input >> 16) & 0xff);
                    int B = ((input >> 8) & 0xff);
                    int A = (input & 0xff);

                    float weight = gaussian[r + radius];

                    blurredPixelR += (float)(R)*weight;
                    blurredPixelG += (float)(G)*weight;
                    blurredPixelB += (float)(B)*weight;
                    blurredPixelA += (float)(A)*weight;
                }

                int R = (int)blurredPixelR;
                int G = (int)blurredPixelG;
                int B = (int)blurredPixelB;
                int A = (int)blurredPixelA;

                interm[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A);
            }
        }

        for (h = 0; h < height; h ++) {
            for (w = 0; w < width; w ++) {

                blurredPixelR = 0.0f;
                blurredPixelG = 0.0f;
                blurredPixelB = 0.0f;
                blurredPixelA = 0.0f;
                for (r = -radius; r <= radius; r ++) {
                    int validH = h + r;
                    // Clamp to zero and width
                    if (validH < 0) {
                        validH = 0;
                    }
                    if (validH > height - 1) {
                        validH = height - 1;
                    }

                    int input = interm[validH*width + w];

                    int R = ((input >> 24) & 0xff);
                    int G = ((input >> 16) & 0xff);
                    int B = ((input >> 8) & 0xff);
                    int A = (input & 0xff);

                    float weight = gaussian[r + radius];

                    blurredPixelR += (float)(R)*weight;
                    blurredPixelG += (float)(G)*weight;
                    blurredPixelB += (float)(B)*weight;
                    blurredPixelA += (float)(A)*weight;
                }

                int R = (int)blurredPixelR;
                int G = (int)blurredPixelG;
                int B = (int)blurredPixelB;
                int A = (int)blurredPixelA;

                out[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A);
            }
        }

        t = java.lang.System.currentTimeMillis() - t;
        android.util.Log.v("Img", "Java frame time ms " + t);
        mBitmapOut.setPixels(out, 0, width, 0, 0, width, height);
        return t;
    }

    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (fromUser) {

            if (seekBar == mRadiusSeekBar) {
                float fRadius = progress / 100.0f;
                fRadius *= (float)(MAX_RADIUS);
                mRadius = (int)fRadius;

                mScript.set_radius(mRadius);
            } else if (seekBar == mInBlackSeekBar) {
                mInBlack = (float)progress;
                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
            } else if (seekBar == mOutBlackSeekBar) {
                mOutBlack = (float)progress;
                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
            } else if (seekBar == mInWhiteSeekBar) {
                mInWhite = (float)progress + 127.0f;
                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
            } else if (seekBar == mOutWhiteSeekBar) {
                mOutWhite = (float)progress + 127.0f;
                mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
            } else if (seekBar == mGammaSeekBar) {
                mGamma = (float)progress/100.0f;
                mGamma = Math.max(mGamma, 0.1f);
                mGamma = 1.0f / mGamma;
                mScriptVBlur.invoke_setGamma(mGamma);
            } else if (seekBar == mSaturationSeekBar) {
                mSaturation = (float)progress / 50.0f;
                mScriptVBlur.invoke_setSaturation(mSaturation);
            }

            long t = java.lang.System.currentTimeMillis();
            if (true) {
                mScript.invoke_filter();
                mOutPixelsAllocation.copyTo(mBitmapOut);
            } else {
                javaFilter();
                mDisplayView.invalidate();
            }

            t = java.lang.System.currentTimeMillis() - t;
            android.util.Log.v("Img", "Renderscript frame time core ms " + t);
        }
    }

    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    public void onStopTrackingTouch(SeekBar seekBar) {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mBitmapIn = loadBitmap(R.drawable.data);
        mBitmapOut = loadBitmap(R.drawable.data);
        mBitmapScratch = loadBitmap(R.drawable.data);

        mSurfaceView = (SurfaceView) findViewById(R.id.surface);
        mSurfaceView.getHolder().addCallback(this);

        mDisplayView = (ImageView) findViewById(R.id.display);
        mDisplayView.setImageBitmap(mBitmapOut);

        mRadiusSeekBar = (SeekBar) findViewById(R.id.radius);
        mRadiusSeekBar.setOnSeekBarChangeListener(this);

        mInBlackSeekBar = (SeekBar)findViewById(R.id.inBlack);
        mInBlackSeekBar.setOnSeekBarChangeListener(this);
        mInBlackSeekBar.setMax(128);
        mInBlackSeekBar.setProgress(0);
        mOutBlackSeekBar = (SeekBar)findViewById(R.id.outBlack);
        mOutBlackSeekBar.setOnSeekBarChangeListener(this);
        mOutBlackSeekBar.setMax(128);
        mOutBlackSeekBar.setProgress(0);

        mInWhiteSeekBar = (SeekBar)findViewById(R.id.inWhite);
        mInWhiteSeekBar.setOnSeekBarChangeListener(this);
        mInWhiteSeekBar.setMax(128);
        mInWhiteSeekBar.setProgress(128);
        mOutWhiteSeekBar = (SeekBar)findViewById(R.id.outWhite);
        mOutWhiteSeekBar.setOnSeekBarChangeListener(this);
        mOutWhiteSeekBar.setMax(128);
        mOutWhiteSeekBar.setProgress(128);

        mGammaSeekBar = (SeekBar)findViewById(R.id.inGamma);
        mGammaSeekBar.setOnSeekBarChangeListener(this);
        mGammaSeekBar.setMax(150);
        mGammaSeekBar.setProgress(100);

        mSaturationSeekBar = (SeekBar)findViewById(R.id.inSaturation);
        mSaturationSeekBar.setOnSeekBarChangeListener(this);
        mSaturationSeekBar.setProgress(50);

        mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
        mBenchmarkResult.setText("Result: not run");
    }

    public void surfaceCreated(SurfaceHolder holder) {
        createScript();
        mScript.invoke_filter();
        mOutPixelsAllocation.copyTo(mBitmapOut);
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
    }

    private void createScript() {
        mRS = RenderScript.create(this);
        mRS.setMessageHandler(new FilterCallback());

        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
                                                          Allocation.MipmapControl.MIPMAP_NONE,
                                                          Allocation.USAGE_SCRIPT);
        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
                                                           Allocation.MipmapControl.MIPMAP_NONE,
                                                           Allocation.USAGE_SCRIPT);

        Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS));
        tb.setX(mBitmapIn.getWidth());
        tb.setY(mBitmapIn.getHeight());
        mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
        mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());

        mScriptVBlur = new ScriptC_vertical_blur(mRS, getResources(), R.raw.vertical_blur);
        mScriptHBlur = new ScriptC_horizontal_blur(mRS, getResources(), R.raw.horizontal_blur);

        mScript = new ScriptC_threshold(mRS, getResources(), R.raw.threshold);
        mScript.set_width(mBitmapIn.getWidth());
        mScript.set_height(mBitmapIn.getHeight());
        mScript.set_radius(mRadius);

        mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite);
        mScriptVBlur.invoke_setGamma(mGamma);
        mScriptVBlur.invoke_setSaturation(mSaturation);

        mScript.bind_InPixel(mInPixelsAllocation);
        mScript.bind_OutPixel(mOutPixelsAllocation);
        mScript.bind_ScratchPixel1(mScratchPixelsAllocation1);
        mScript.bind_ScratchPixel2(mScratchPixelsAllocation2);

        mScript.set_vBlurScript(mScriptVBlur);
        mScript.set_hBlurScript(mScriptHBlur);
    }

    private Bitmap loadBitmap(int resource) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options));
    }

    private static Bitmap copyBitmap(Bitmap source) {
        Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
        Canvas c = new Canvas(b);
        c.drawBitmap(source, 0, 0, null);
        source.recycle();
        return b;
    }

    // button hook
    public void benchmark(View v) {
        android.util.Log.v("Img", "Benchmarking");
        int oldRadius = mRadius;
        mRadius = MAX_RADIUS;
        mScript.set_radius(mRadius);

        long t = java.lang.System.currentTimeMillis();

        mScript.invoke_filter();
        mOutPixelsAllocation.copyTo(mBitmapOut);

        t = java.lang.System.currentTimeMillis() - t;
        android.util.Log.v("Img", "Renderscript frame time core ms " + t);

        //long javaTime = javaFilter();
        //mBenchmarkResult.setText("RS: " + t + " ms  Java: " + javaTime + " ms");
        mBenchmarkResult.setText("Result: " + t + " ms");

        mRadius = oldRadius;
        mScript.set_radius(mRadius);

        mScript.invoke_filter();
        mOutPixelsAllocation.copyTo(mBitmapOut);
    }
}
