/*
 * 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.android.systemui.biometrics

import android.graphics.PointF
import android.graphics.RuntimeShader
import android.util.MathUtils

/**
 * Shader class that renders a distorted ripple for the UDFPS dwell effect.
 * Adjustable shader parameters:
 *   - progress
 *   - origin
 *   - color
 *   - time
 *   - maxRadius
 *   - distortionStrength.
 * See per field documentation for more details.
 *
 * Modeled after frameworks/base/graphics/java/android/graphics/drawable/RippleShader.java.
 */
class DwellRippleShader internal constructor() : RuntimeShader(SHADER) {
    companion object {
        private const val SHADER_UNIFORMS = """uniform vec2 in_origin;
                uniform float in_time;
                uniform float in_radius;
                uniform float in_blur;
                layout(color) uniform vec4 in_color;
                uniform float in_phase1;
                uniform float in_phase2;
                uniform float in_distortion_strength;"""
        private const val SHADER_LIB = """
                float softCircle(vec2 uv, vec2 xy, float radius, float blur) {
                  float blurHalf = blur * 0.5;
                  float d = distance(uv, xy);
                  return 1. - smoothstep(1. - blurHalf, 1. + blurHalf, d / radius);
                }

                float softRing(vec2 uv, vec2 xy, float radius, float blur) {
                  float thickness_half = radius * 0.25;
                  float circle_outer = softCircle(uv, xy, radius + thickness_half, blur);
                  float circle_inner = softCircle(uv, xy, radius - thickness_half, blur);
                  return circle_outer - circle_inner;
                }

                vec2 distort(vec2 p, float time, float distort_amount_xy, float frequency) {
                    return p + vec2(sin(p.y * frequency + in_phase1),
                                    cos(p.x * frequency * -1.23 + in_phase2)) * distort_amount_xy;
                }

                vec4 ripple(vec2 p, float distort_xy, float frequency) {
                    vec2 p_distorted = distort(p, in_time, distort_xy, frequency);
                    float circle = softCircle(p_distorted, in_origin, in_radius * 1.2, in_blur);
                    float rippleAlpha = max(circle,
                        softRing(p_distorted, in_origin, in_radius, in_blur)) * 0.25;
                    return in_color * rippleAlpha;
                }
                """
        private const val SHADER_MAIN = """vec4 main(vec2 p) {
                    vec4 color1 = ripple(p,
                        34 * in_distortion_strength, // distort_xy
                        0.012 // frequency
                    );
                    vec4 color2 = ripple(p,
                        49 * in_distortion_strength, // distort_xy
                        0.018 // frequency
                    );
                    // Alpha blend between two layers.
                    return vec4(color1.xyz + color2.xyz
                        * (1 - color1.w), color1.w + color2.w * (1-color1.w));
                }"""
        private const val SHADER = SHADER_UNIFORMS + SHADER_LIB + SHADER_MAIN
    }

    /**
     * Maximum radius of the ripple.
     */
    var maxRadius: Float = 0.0f

    /**
     * Origin coordinate of the ripple.
     */
    var origin: PointF = PointF()
        set(value) {
            field = value
            setFloatUniform("in_origin", value.x, value.y)
        }

    /**
     * Progress of the ripple. Float value between [0, 1].
     */
    var progress: Float = 0.0f
        set(value) {
            field = value
            setFloatUniform("in_radius",
                    (1 - (1 - value) * (1 - value) * (1 - value))* maxRadius)
            setFloatUniform("in_blur", MathUtils.lerp(1f, 0.7f, value))
        }

    /**
     * Distortion strength between [0, 1], with 0 being no distortion and 1 being full distortion.
     */
    var distortionStrength: Float = 0.0f
        set(value) {
            field = value
            setFloatUniform("in_distortion_strength", value)
        }

    /**
     * Play time since the start of the effect in seconds.
     */
    var time: Float = 0.0f
        set(value) {
            field = value * 0.001f
            setFloatUniform("in_time", field)
            setFloatUniform("in_phase1", field * 3f + 0.367f)
            setFloatUniform("in_phase2", field * 7.2f * 1.531f)
        }

    /**
     * A hex value representing the ripple color, in the format of ARGB
     */
    var color: Int = 0xffffff.toInt()
        set(value) {
            field = value
            setColorUniform("in_color", value)
        }
}
