/*
 * Copyright (C) 2012 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.test.hwuicompare;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.util.Log;

public class ErrorCalculator {
    private static final String LOG_TAG = "ErrorCalculator";
    private static final int REGION_SIZE = 8;

    private static final boolean LOG_TIMING = false;
    private static final boolean LOG_CALC = false;

    private RenderScript mRS;
    private Allocation mIdealPixelsAllocation;
    private Allocation mGivenPixelsAllocation;
    private Allocation mOutputPixelsAllocation;

    private Allocation mInputRowsAllocation;
    private Allocation mOutputRegionsAllocation;

    private ScriptC_errorCalculator mScript;

    private int[] mOutputRowRegions;

    public ErrorCalculator(Context c, Resources resources) {
        int width = resources.getDimensionPixelSize(R.dimen.layer_width);
        int height = resources.getDimensionPixelSize(R.dimen.layer_height);
        mOutputRowRegions = new int[height / REGION_SIZE];

        mRS = RenderScript.create(c);
        int[] rowIndices = new int[height / REGION_SIZE];
        for (int i = 0; i < rowIndices.length; i++)
            rowIndices[i] = i * REGION_SIZE;

        mScript = new ScriptC_errorCalculator(mRS);
        mScript.set_HEIGHT(height);
        mScript.set_WIDTH(width);
        mScript.set_REGION_SIZE(REGION_SIZE);

        mInputRowsAllocation = Allocation.createSized(mRS, Element.I32(mRS), rowIndices.length,
                Allocation.USAGE_SCRIPT);
        mInputRowsAllocation.copyFrom(rowIndices);
        mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
                mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
    }


    private static long startMillis, middleMillis;

    public float calcErrorRS(Bitmap ideal, Bitmap given) {
        if (LOG_TIMING) {
            startMillis = System.currentTimeMillis();
        }

        mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
        mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);

        mScript.set_ideal(mIdealPixelsAllocation);
        mScript.set_given(mGivenPixelsAllocation);

        mScript.forEach_countInterestingRegions(mInputRowsAllocation, mOutputRegionsAllocation);
        mOutputRegionsAllocation.copyTo(mOutputRowRegions);

        int regionCount = 0;
        for (int region : mOutputRowRegions) {
            regionCount += region;
        }
        int interestingPixels = Math.max(1, regionCount) * REGION_SIZE * REGION_SIZE;

        if (LOG_TIMING) {
            long startMillis2 = System.currentTimeMillis();
        }

        mScript.forEach_accumulateError(mInputRowsAllocation, mOutputRegionsAllocation);
        mOutputRegionsAllocation.copyTo(mOutputRowRegions);
        float totalError = 0;
        for (int row : mOutputRowRegions) {
            totalError += row;
        }
        totalError /= 1024.0f;

        if (LOG_TIMING) {
            long finalMillis = System.currentTimeMillis();
            Log.d(LOG_TAG, "rs: first part took " + (middleMillis - startMillis) + "ms");
            Log.d(LOG_TAG, "rs: last part took " + (finalMillis - middleMillis) + "ms");
        }
        if (LOG_CALC) {
            Log.d(LOG_TAG, "rs: error " + totalError + ", pixels " + interestingPixels);
        }
        return totalError / interestingPixels;
    }

    public void calcErrorHeatmapRS(Bitmap ideal, Bitmap given, Bitmap output) {
        mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
        mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);

        mScript.set_ideal(mIdealPixelsAllocation);
        mScript.set_given(mGivenPixelsAllocation);

        mOutputPixelsAllocation = Allocation.createFromBitmap(mRS, output,
                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
        mScript.forEach_displayDifference(mOutputPixelsAllocation, mOutputPixelsAllocation);
        mOutputPixelsAllocation.copyTo(output);
    }

    public static float calcError(Bitmap ideal, Bitmap given) {
        if (LOG_TIMING) {
            startMillis = System.currentTimeMillis();
        }

        int interestingRegions = 0;
        for (int x = 0; x < ideal.getWidth(); x += REGION_SIZE) {
            for (int y = 0; y < ideal.getWidth(); y += REGION_SIZE) {
                if (inspectRegion(ideal, x, y)) {
                    interestingRegions++;
                }
            }
        }

        int interestingPixels = Math.max(1, interestingRegions) * REGION_SIZE * REGION_SIZE;

        if (LOG_TIMING) {
            long startMillis2 = System.currentTimeMillis();
        }

        float totalError = 0;
        for (int x = 0; x < ideal.getWidth(); x++) {
            for (int y = 0; y < ideal.getHeight(); y++) {
                int idealColor = ideal.getPixel(x, y);
                int givenColor = given.getPixel(x, y);
                if (idealColor == givenColor)
                    continue;
                totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
                totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
                totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
                totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
            }
        }
        totalError /= 1024.0f;
        if (LOG_TIMING) {
            long finalMillis = System.currentTimeMillis();
            Log.d(LOG_TAG, "dvk: first part took " + (middleMillis - startMillis) + "ms");
            Log.d(LOG_TAG, "dvk: last part took " + (finalMillis - middleMillis) + "ms");
        }
        if (LOG_CALC) {
            Log.d(LOG_TAG, "dvk: error " + totalError + ", pixels " + interestingPixels);
        }
        return totalError / interestingPixels;
    }

    private static boolean inspectRegion(Bitmap ideal, int x, int y) {
        int regionColor = ideal.getPixel(x, y);
        for (int i = 0; i < REGION_SIZE; i++) {
            for (int j = 0; j < REGION_SIZE; j++) {
                if (ideal.getPixel(x + i, y + j) != regionColor)
                    return true;
            }
        }
        return false;
    }
}
