/*
 * Copyright (C) 2019 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.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_GESTURE
import android.os.SystemClock
import android.view.MotionEvent
import android.view.ViewConfiguration

import com.android.systemui.Gefingerpoken
import com.android.systemui.Interpolators
import com.android.systemui.R
import com.android.systemui.classifier.FalsingManagerFactory
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.phone.ShadeController

import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max

/**
 * A utility class to enable the downward swipe on when pulsing.
 */
@Singleton
class PulseExpansionHandler @Inject
constructor(context: Context,
            private val mWakeUpCoordinator: NotificationWakeUpCoordinator) : Gefingerpoken {
    companion object {
        private val RUBBERBAND_FACTOR_STATIC = 0.25f
        private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
    }
    private val mPowerManager: PowerManager?
    private var mShadeController: ShadeController? = null

    private val mMinDragDistance: Int
    private var mInitialTouchX: Float = 0.0f
    private var mInitialTouchY: Float = 0.0f
    var isExpanding: Boolean = false
        private set
    private val mTouchSlop: Float
    private var mExpansionCallback: ExpansionCallback? = null
    private lateinit var mStackScroller: NotificationStackScrollLayout
    private val mTemp2 = IntArray(2)
    private var mDraggedFarEnough: Boolean = false
    private var mStartingChild: ExpandableView? = null
    private val mFalsingManager: FalsingManager
    private var mPulsing: Boolean = false
    var isWakingToShadeLocked: Boolean = false
        private set
    private var mEmptyDragAmount: Float = 0.0f
    private var mWakeUpHeight: Float = 0.0f
    private var mReachedWakeUpHeight: Boolean = false

    private val isFalseTouch: Boolean
        get() = mFalsingManager.isFalseTouch

    init {
        mMinDragDistance = context.resources.getDimensionPixelSize(
                R.dimen.keyguard_drag_down_min_distance)
        mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
        mFalsingManager = FalsingManagerFactory.getInstance(context)
        mPowerManager = context.getSystemService(PowerManager::class.java)
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return maybeStartExpansion(event)
    }

    private fun maybeStartExpansion(event: MotionEvent): Boolean {
        if (!mPulsing) {
            return false
        }
        val x = event.x
        val y = event.y

        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                mDraggedFarEnough = false
                isExpanding = false
                mStartingChild = null
                mInitialTouchY = y
                mInitialTouchX = x
            }

            MotionEvent.ACTION_MOVE -> {
                val h = y - mInitialTouchY
                if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) {
                    mFalsingManager.onStartExpandingFromPulse()
                    isExpanding = true
                    captureStartingChild(mInitialTouchX, mInitialTouchY)
                    mInitialTouchY = y
                    mInitialTouchX = x
                    mWakeUpHeight = mWakeUpCoordinator.getWakeUpHeight()
                    mReachedWakeUpHeight = false
                    return true
                }
            }
        }
        return false
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (!isExpanding) {
            return maybeStartExpansion(event)
        }
        val y = event.y

        when (event.actionMasked) {
            MotionEvent.ACTION_MOVE -> updateExpansionHeight(y - mInitialTouchY)
            MotionEvent.ACTION_UP -> if (!mFalsingManager.isUnlockingDisabled && !isFalseTouch) {
                finishExpansion()
            } else {
                cancelExpansion()
            }
            MotionEvent.ACTION_CANCEL -> cancelExpansion()
        }
        return isExpanding
    }

    private fun finishExpansion() {
        resetClock()
        if (mStartingChild != null) {
            setUserLocked(mStartingChild!!, false)
            mStartingChild = null
        }
        isExpanding = false
        isWakingToShadeLocked = true
        mWakeUpCoordinator.willWakeUp = true
        mPowerManager!!.wakeUp(SystemClock.uptimeMillis(), WAKE_REASON_GESTURE,
                "com.android.systemui:PULSEDRAG")
        mShadeController!!.goToLockedShade(mStartingChild)
        if (mStartingChild is ExpandableNotificationRow) {
            val row = mStartingChild as ExpandableNotificationRow?
            row!!.onExpandedByGesture(true /* userExpanded */)
        }
    }

    private fun updateExpansionHeight(height: Float) {
        var expansionHeight = max(height, 0.0f)
        if (!mReachedWakeUpHeight && height > mWakeUpHeight) {
            mReachedWakeUpHeight = true;
        }
        if (mStartingChild != null) {
            val child = mStartingChild!!
            val newHeight = Math.min((child.collapsedHeight + expansionHeight).toInt(),
                    child.maxContentHeight)
            child.actualHeight = newHeight
            expansionHeight = max(newHeight.toFloat(), expansionHeight)
        } else {
            val target = if (mReachedWakeUpHeight) mWakeUpHeight else 0.0f
            mWakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
                    true /* animate */,
                    true /* increaseSpeed */)
            expansionHeight = max(mWakeUpHeight, expansionHeight)
        }
        val emptyDragAmount = mWakeUpCoordinator.setPulseHeight(expansionHeight)
        setEmptyDragAmount(emptyDragAmount * RUBBERBAND_FACTOR_STATIC)
    }

    private fun captureStartingChild(x: Float, y: Float) {
        if (mStartingChild == null) {
            mStartingChild = findView(x, y)
            if (mStartingChild != null) {
                setUserLocked(mStartingChild!!, true)
            }
        }
    }

    private fun setEmptyDragAmount(amount: Float) {
        mEmptyDragAmount = amount
        mExpansionCallback!!.setEmptyDragAmount(amount)
    }

    private fun reset(child: ExpandableView) {
        if (child.actualHeight == child.collapsedHeight) {
            setUserLocked(child, false)
            return
        }
        val anim = ObjectAnimator.ofInt(child, "actualHeight",
                child.actualHeight, child.collapsedHeight)
        anim.interpolator = Interpolators.FAST_OUT_SLOW_IN
        anim.duration = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
        anim.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                setUserLocked(child, false)
            }
        })
        anim.start()
    }

    private fun setUserLocked(child: ExpandableView, userLocked: Boolean) {
        if (child is ExpandableNotificationRow) {
            child.isUserLocked = userLocked
        }
    }

    private fun resetClock() {
        val anim = ValueAnimator.ofFloat(mEmptyDragAmount, 0f)
        anim.interpolator = Interpolators.FAST_OUT_SLOW_IN
        anim.duration = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
        anim.addUpdateListener { animation -> setEmptyDragAmount(animation.animatedValue as Float) }
        anim.start()
    }

    private fun cancelExpansion() {
        mFalsingManager.onExpansionFromPulseStopped()
        if (mStartingChild != null) {
            reset(mStartingChild!!)
            mStartingChild = null
        } else {
            resetClock()
        }
        mWakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
                true /* animate */,
                false /* increaseSpeed */)
        isExpanding = false
    }

    private fun findView(x: Float, y: Float): ExpandableView? {
        var totalX = x
        var totalY = y
        mStackScroller.getLocationOnScreen(mTemp2)
        totalX += mTemp2[0].toFloat()
        totalY += mTemp2[1].toFloat()
        val childAtRawPosition = mStackScroller.getChildAtRawPosition(totalX, totalY)
        return if (childAtRawPosition != null && childAtRawPosition.isContentExpandable) {
            childAtRawPosition
        } else null
    }

    fun setUp(notificationStackScroller: NotificationStackScrollLayout,
             expansionCallback: ExpansionCallback,
             shadeController: ShadeController) {
        mExpansionCallback = expansionCallback
        mShadeController = shadeController
        mStackScroller = notificationStackScroller
    }

    fun setPulsing(pulsing: Boolean) {
        mPulsing = pulsing
    }

    fun onStartedWakingUp() {
        isWakingToShadeLocked = false
    }

    interface ExpansionCallback {
        fun setEmptyDragAmount(amount: Float)
    }
}
