/*
 * 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) {
            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()
            }
        }
    }
}
