/*
 * 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.renderscript.toolkit.Range2d
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sqrt

/**
 * Reference implementation of a Blur operation.
 */
@ExperimentalUnsignedTypes
fun referenceBlur(inputArray: ByteArray,
                  vectorSize: Int,
                  sizeX: Int,
                  sizeY: Int,
                  radius: Int = 5, restriction: Range2d?): ByteArray {
    val maxRadius = 25
    require (radius in 1..maxRadius) {
        "RenderScriptToolkit blur. Radius should be between 1 and $maxRadius. $radius provided."
    }
    val gaussian = buildGaussian(radius)

    // Convert input data to float so that the blurring goes faster.
    val inputValues = FloatArray(inputArray.size) { byteToUnitFloat(inputArray[it].toUByte()) }
    val inputInFloat = FloatVector2dArray(inputValues, vectorSize, sizeX, sizeY)

    val scratch = horizontalBlur(inputInFloat, gaussian, radius, restriction)
    val outInFloat = verticalBlur(scratch, gaussian, radius, restriction)

    // Convert the results back to bytes.
    return ByteArray(outInFloat.values.size) { unitFloatClampedToUByte(outInFloat.values[it]).toByte() }
}

/**
 * Blurs along the horizontal direction using the specified gaussian weights.
 */
private fun horizontalBlur(
    input: FloatVector2dArray,
    gaussian: FloatArray,
    radius: Int,
    restriction: Range2d?
): FloatVector2dArray {
    var expandedRestriction: Range2d? = null
    if (restriction != null) {
        // Expand the restriction in the vertical direction so that the vertical pass
        // will have all the data it needs.
        expandedRestriction = Range2d(
            restriction.startX,
            restriction.endX,
            max(restriction.startY - radius, 0),
            min(restriction.endY + radius, input.sizeY)
        )
    }

    input.clipAccessToRange = true
    val out = input.createSameSized()
    out.forEach(expandedRestriction) { x, y ->
        for ((gaussianIndex, delta: Int) in (-radius..radius).withIndex()) {
            val v = input[x + delta, y] * gaussian[gaussianIndex]
            out[x, y] += v
        }
    }
    return out
}

/**
 * Blurs along the horizontal direction using the specified gaussian weights.
 */
private fun verticalBlur(
    input: FloatVector2dArray,
    gaussian: FloatArray,
    radius: Int,
    restriction: Range2d?
): FloatVector2dArray {
    input.clipAccessToRange = true
    val out = input.createSameSized()
    out.forEach(restriction) { x, y ->
        for ((gaussianIndex, delta: Int) in (-radius..radius).withIndex()) {
            val v = input[x, y + delta] * gaussian[gaussianIndex]
            out[x, y] += v
        }
    }
    return out
}

/**
 * Builds an array of gaussian weights that will be used for doing the horizontal and vertical
 * blur.
 *
 * @return An array of (2 * radius + 1) floats.
 */
private fun buildGaussian(radius: Int): FloatArray {
    val e: Float = kotlin.math.E.toFloat()
    val pi: Float = kotlin.math.PI.toFloat()
    val sigma: Float = 0.4f * radius.toFloat() + 0.6f
    val coefficient1: Float = 1.0f / (sqrt(2.0f * pi) * sigma)
    val coefficient2: Float = -1.0f / (2.0f * sigma * sigma)

    var sum = 0.0f
    val gaussian = FloatArray(radius * 2 + 1)
    for (r in -radius..radius) {
        val floatR: Float = r.toFloat()
        val v: Float = coefficient1 * e.pow(floatR * floatR * coefficient2)
        gaussian[r + radius] = v
        sum += v
    }

    // Normalize so that the sum of the weights equal 1f.
    val normalizeFactor: Float = 1.0f / sum
    for (r in -radius..radius) {
        gaussian[r + radius] *= normalizeFactor
    }
    return gaussian
}
