/*
 * Copyright (C) 2020 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.statusbar

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.app.WallpaperManager
import android.util.Log
import android.view.Choreographer
import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.dynamicanimation.animation.FloatPropertyCompat
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.internal.util.IndentingPrintWriter
import com.android.systemui.Dumpable
import com.android.systemui.Interpolators
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
import com.android.systemui.statusbar.phone.NotificationShadeWindowController
import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.KeyguardStateController
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max

/**
 * Controller responsible for statusbar window blur.
 */
@Singleton
class NotificationShadeDepthController @Inject constructor(
    private val statusBarStateController: StatusBarStateController,
    private val blurUtils: BlurUtils,
    private val biometricUnlockController: BiometricUnlockController,
    private val keyguardStateController: KeyguardStateController,
    private val choreographer: Choreographer,
    private val wallpaperManager: WallpaperManager,
    private val notificationShadeWindowController: NotificationShadeWindowController,
    dumpManager: DumpManager
) : PanelExpansionListener, Dumpable {
    companion object {
        private const val WAKE_UP_ANIMATION_ENABLED = true
        private const val TAG = "DepthController"
    }

    lateinit var root: View
    private var blurRoot: View? = null
    private var keyguardAnimator: Animator? = null
    private var notificationAnimator: Animator? = null
    private var updateScheduled: Boolean = false
    private var shadeExpansion = 0f
    private var ignoreShadeBlurUntilHidden: Boolean = false
    @VisibleForTesting
    var shadeSpring = DepthAnimation()
    @VisibleForTesting
    var globalActionsSpring = DepthAnimation()
    var showingHomeControls: Boolean = false

    @VisibleForTesting
    var brightnessMirrorSpring = DepthAnimation()
    var brightnessMirrorVisible: Boolean = false
        set(value) {
            field = value
            brightnessMirrorSpring.animateTo(if (value) blurUtils.blurRadiusOfRatio(1f)
                else 0)
        }

    /**
     * When launching an app from the shade, the animations progress should affect how blurry the
     * shade is, overriding the expansion amount.
     */
    var notificationLaunchAnimationParams: ActivityLaunchAnimator.ExpandAnimationParameters? = null
        set(value) {
            field = value
            if (value != null) {
                scheduleUpdate()
                return
            }

            if (shadeSpring.radius == 0) {
                return
            }
            ignoreShadeBlurUntilHidden = true
            shadeSpring.animateTo(0)
            shadeSpring.finishIfRunning()
        }

    /**
     * Force stop blur effect when necessary.
     */
    private var scrimsVisible: Boolean = false
        set(value) {
            if (field == value) return
            field = value
            scheduleUpdate()
        }

    /**
     * Blur radius of the wake-up animation on this frame.
     */
    private var wakeAndUnlockBlurRadius = 0
        set(value) {
            if (field == value) return
            field = value
            scheduleUpdate()
        }

    /**
     * Callback that updates the window blur value and is called only once per frame.
     */
    @VisibleForTesting
    val updateBlurCallback = Choreographer.FrameCallback {
        updateScheduled = false

        var shadeRadius = max(shadeSpring.radius, wakeAndUnlockBlurRadius).toFloat()
        shadeRadius *= 1f - brightnessMirrorSpring.ratio
        val launchProgress = notificationLaunchAnimationParams?.linearProgress ?: 0f
        shadeRadius *= (1f - launchProgress) * (1f - launchProgress)

        if (ignoreShadeBlurUntilHidden) {
            if (shadeRadius == 0f) {
                ignoreShadeBlurUntilHidden = false
            } else {
                shadeRadius = 0f
            }
        }

        // Home controls have black background, this means that we should not have blur when they
        // are fully visible, otherwise we'll enter Client Composition unnecessarily.
        var globalActionsRadius = globalActionsSpring.radius
        if (showingHomeControls) {
            globalActionsRadius = 0
        }
        var blur = max(shadeRadius.toInt(), globalActionsRadius)

        // Make blur be 0 if it is necessary to stop blur effect.
        if (scrimsVisible) {
            blur = 0
        }

        blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur)
        try {
            wallpaperManager.setWallpaperZoomOut(root.windowToken,
                    blurUtils.ratioOfBlurRadius(blur))
        } catch (e: IllegalArgumentException) {
            Log.w(TAG, "Can't set zoom. Window is gone: ${root.windowToken}", e)
        }
        notificationShadeWindowController.setBackgroundBlurRadius(blur)
    }

    /**
     * Animate blurs when unlocking.
     */
    private val keyguardStateCallback = object : KeyguardStateController.Callback {
        override fun onKeyguardFadingAwayChanged() {
            if (!keyguardStateController.isKeyguardFadingAway ||
                    biometricUnlockController.mode != MODE_WAKE_AND_UNLOCK) {
                return
            }

            keyguardAnimator?.cancel()
            keyguardAnimator = ValueAnimator.ofFloat(1f, 0f).apply {
                duration = keyguardStateController.keyguardFadingAwayDuration
                startDelay = keyguardStateController.keyguardFadingAwayDelay
                interpolator = Interpolators.DECELERATE_QUINT
                addUpdateListener { animation: ValueAnimator ->
                    wakeAndUnlockBlurRadius =
                            blurUtils.blurRadiusOfRatio(animation.animatedValue as Float)
                }
                addListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationEnd(animation: Animator?) {
                        keyguardAnimator = null
                        scheduleUpdate()
                    }
                })
                start()
            }
        }

        override fun onKeyguardShowingChanged() {
            if (keyguardStateController.isShowing) {
                keyguardAnimator?.cancel()
                notificationAnimator?.cancel()
            }
        }
    }

    private val statusBarStateCallback = object : StatusBarStateController.StateListener {
        override fun onStateChanged(newState: Int) {
            updateShadeBlur()
        }

        override fun onDozingChanged(isDozing: Boolean) {
            if (isDozing) {
                shadeSpring.finishIfRunning()
                globalActionsSpring.finishIfRunning()
                brightnessMirrorSpring.finishIfRunning()
            }
        }

        override fun onDozeAmountChanged(linear: Float, eased: Float) {
            wakeAndUnlockBlurRadius = blurUtils.blurRadiusOfRatio(eased)
        }
    }

    init {
        dumpManager.registerDumpable(javaClass.name, this)
        if (WAKE_UP_ANIMATION_ENABLED) {
            keyguardStateController.addCallback(keyguardStateCallback)
        }
        statusBarStateController.addCallback(statusBarStateCallback)
        notificationShadeWindowController.setScrimsVisibilityListener {
            // Stop blur effect when scrims is opaque to avoid unnecessary GPU composition.
            visibility -> scrimsVisible = visibility == ScrimController.OPAQUE
        }
    }

    /**
     * Update blurs when pulling down the shade
     */
    override fun onPanelExpansionChanged(expansion: Float, tracking: Boolean) {
        if (expansion == shadeExpansion) {
            return
        }
        shadeExpansion = expansion
        updateShadeBlur()
    }

    private fun updateShadeBlur() {
        var newBlur = 0
        val state = statusBarStateController.state
        if ((state == StatusBarState.SHADE || state == StatusBarState.SHADE_LOCKED) &&
                !keyguardStateController.isKeyguardFadingAway) {
            newBlur = blurUtils.blurRadiusOfRatio(shadeExpansion)
        }
        shadeSpring.animateTo(newBlur)
    }

    private fun scheduleUpdate(viewToBlur: View? = null) {
        if (updateScheduled) {
            return
        }
        updateScheduled = true
        blurRoot = viewToBlur
        choreographer.postFrameCallback(updateBlurCallback)
    }

    fun updateGlobalDialogVisibility(visibility: Float, dialogView: View?) {
        globalActionsSpring.animateTo(blurUtils.blurRadiusOfRatio(visibility), dialogView)
    }

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        IndentingPrintWriter(pw, "  ").let {
            it.println("StatusBarWindowBlurController:")
            it.increaseIndent()
            it.println("shadeRadius: ${shadeSpring.radius}")
            it.println("globalActionsRadius: ${globalActionsSpring.radius}")
            it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
            it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
            it.println("notificationLaunchAnimationProgress: " +
                    "${notificationLaunchAnimationParams?.linearProgress}")
            it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden")
        }
    }

    /**
     * Animation helper that smoothly animates the depth using a spring and deals with frame
     * invalidation.
     */
    inner class DepthAnimation() {
        /**
         * Blur radius visible on the UI, in pixels.
         */
        var radius = 0

        /**
         * Depth ratio of the current blur radius.
         */
        val ratio
            get() = blurUtils.ratioOfBlurRadius(radius)

        /**
         * Radius that we're animating to.
         */
        private var pendingRadius = -1

        /**
         * View on {@link Surface} that wants depth.
         */
        private var view: View? = null

        private var springAnimation = SpringAnimation(this, object :
            FloatPropertyCompat<DepthAnimation>("blurRadius") {
            override fun setValue(rect: DepthAnimation?, value: Float) {
                radius = value.toInt()
                scheduleUpdate(view)
            }

            override fun getValue(rect: DepthAnimation?): Float {
                return radius.toFloat()
            }
        })

        init {
            springAnimation.spring = SpringForce(0.0f)
            springAnimation.spring.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
            springAnimation.spring.stiffness = SpringForce.STIFFNESS_HIGH
            springAnimation.addEndListener { _, _, _, _ -> pendingRadius = -1 }
        }

        fun animateTo(newRadius: Int, viewToBlur: View? = null) {
            if (pendingRadius == newRadius && view == viewToBlur) {
                return
            }
            view = viewToBlur
            pendingRadius = newRadius
            springAnimation.animateToFinalPosition(newRadius.toFloat())
        }

        fun finishIfRunning() {
            if (springAnimation.isRunning) {
                springAnimation.skipToEnd()
            }
        }
    }
}
