/*
 * Copyright (C) 2021 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.example.testapp

import android.graphics.Bitmap
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.Script
import android.renderscript.ScriptIntrinsicHistogram
import android.renderscript.Type
import android.renderscript.toolkit.Range2d

/**
 * Does a Histogram operation using the RenderScript Intrinsics.
 */
fun intrinsicHistogram(
    context: RenderScript,
    inputArray: ByteArray,
    vectorSize: Int,
    sizeX: Int,
    sizeY: Int,
    restriction: Range2d?
): IntArray {
    val element = renderScriptVectorElementForU8(context, vectorSize)
    val scriptHistogram = ScriptIntrinsicHistogram.create(context, element)
    val builder = Type.Builder(context, element)
    builder.setX(sizeX)
    builder.setY(sizeY)
    val arrayType = builder.create()
    val inputAllocation = Allocation.createTyped(context, arrayType)
    val outAllocation =
        Allocation.createSized(
            context,
            renderScriptVectorElementForI32(context, vectorSize),
            256
        )
    inputAllocation.copyFrom(inputArray)
    scriptHistogram.setOutput(outAllocation)
    if (restriction != null) {
        val options = Script.LaunchOptions()
        options.setX(restriction.startX, restriction.endX)
        options.setY(restriction.startY, restriction.endY)
        scriptHistogram.forEach(inputAllocation, options)
    } else {
        scriptHistogram.forEach(inputAllocation)
    }

    val intrinsicOutArray = IntArray(256 * paddedSize(vectorSize))
    outAllocation.copyTo(intrinsicOutArray)
    inputAllocation.destroy()
    outAllocation.destroy()
    arrayType.destroy()
    scriptHistogram.destroy()
    return intrinsicOutArray
}

fun intrinsicHistogram(
    context: RenderScript,
    bitmap: Bitmap,
    restriction: Range2d?
): IntArray {
    val baseElement = renderScriptElementForBitmap(context, bitmap)
    val scriptHistogram = ScriptIntrinsicHistogram.create(context, baseElement)
    val inputAllocation = Allocation.createFromBitmap(context, bitmap)
    inputAllocation.copyFrom(bitmap)
    val vectorSize = vectorSizeOfBitmap(bitmap)
    val outAllocation =
        Allocation.createSized(
            context,
            renderScriptVectorElementForI32(context, vectorSize),
            256
        )
    scriptHistogram.setOutput(outAllocation)
    if (restriction != null) {
        val options = Script.LaunchOptions()
        options.setX(restriction.startX, restriction.endX)
        options.setY(restriction.startY, restriction.endY)
        scriptHistogram.forEach(inputAllocation, options)
    } else {
        scriptHistogram.forEach(inputAllocation)
    }

    val intrinsicOutArray = IntArray(256 * vectorSize)
    outAllocation.copyTo(intrinsicOutArray)
    inputAllocation.destroy()
    outAllocation.destroy()
    scriptHistogram.destroy()
    return intrinsicOutArray
}

fun intrinsicHistogramDot(
    context: RenderScript,
    inputArray: ByteArray,
    vectorSize: Int,
    sizeX: Int,
    sizeY: Int,
    coefficients: FloatArray?,
    restriction: Range2d?
): IntArray {
    val element = renderScriptVectorElementForU8(context, vectorSize)
    val scriptHistogram = ScriptIntrinsicHistogram.create(context, element)
    val builder = Type.Builder(context, element)
    builder.setX(sizeX)
    builder.setY(sizeY)
    val arrayType = builder.create()
    val inputAllocation = Allocation.createTyped(context, arrayType)
    val outAllocation =
        Allocation.createSized(context, Element.I32(context), 256)
    inputAllocation.copyFrom(inputArray)

    if (coefficients != null) {
        require(coefficients.size == vectorSize) {
            "RenderScriptToolkit tests. $vectorSize coefficients are required for histogram. " +
                "${coefficients.size} provided."
        }
        scriptHistogram.setDotCoefficients(
            coefficients[0],
            if (vectorSize > 1) coefficients[1] else 0f,
            if (vectorSize > 2) coefficients[2] else 0f,
            if (vectorSize > 3) coefficients[3] else 0f
        )
    }
    scriptHistogram.setOutput(outAllocation)
    if (restriction != null) {
        val options = Script.LaunchOptions()
        options.setX(restriction.startX, restriction.endX)
        options.setY(restriction.startY, restriction.endY)
        scriptHistogram.forEach_Dot(inputAllocation, options)
    } else {
        scriptHistogram.forEach_Dot(inputAllocation)
    }
    val intrinsicOutArray = IntArray(256)
    outAllocation.copyTo(intrinsicOutArray)
    inputAllocation.destroy()
    outAllocation.destroy()
    arrayType.destroy()
    scriptHistogram.destroy()
    return intrinsicOutArray
}

fun intrinsicHistogramDot(
    context: RenderScript,
    bitmap: Bitmap,
    coefficients: FloatArray?,
    restriction: Range2d?
): IntArray {
    val baseElement = renderScriptElementForBitmap(context, bitmap)
    val scriptHistogram = ScriptIntrinsicHistogram.create(context, baseElement)
    val inputAllocation = Allocation.createFromBitmap(context, bitmap)
    inputAllocation.copyFrom(bitmap)
    val outAllocation =
        Allocation.createSized(context, Element.I32(context), 256)

    if (coefficients != null) {
        require(coefficients.size == 4) {
            "RenderScriptToolkit tests. Four coefficients are required for histogram. " +
                "${coefficients.size} provided."
        }
        scriptHistogram.setDotCoefficients(
            coefficients[0],
            coefficients[1],
            coefficients[2],
            coefficients[3]
        )
    }
    scriptHistogram.setOutput(outAllocation)
    if (restriction != null) {
        val options = Script.LaunchOptions()
        options.setX(restriction.startX, restriction.endX)
        options.setY(restriction.startY, restriction.endY)
        scriptHistogram.forEach_Dot(inputAllocation, options)
    } else {
        scriptHistogram.forEach_Dot(inputAllocation)
    }
    val intrinsicOutArray = IntArray(256)
    outAllocation.copyTo(intrinsicOutArray)
    inputAllocation.destroy()
    outAllocation.destroy()
    scriptHistogram.destroy()
    return intrinsicOutArray
}
