package com.adealink.weparty.commonui.widget.slide

import android.animation.Animator
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.util.Log

class AnimationProcessor(
    private val mBuilder: SlideBuilder,
    val onAnimationUpdate: (animation: ValueAnimator) -> Unit,
    val onAnimationEnd: (slidToEnd: Boolean) -> Unit
) {
    private var mValueAnimator: ValueAnimator? = null
    private var slideAnimationTo: Float = 0f
    private var mSlideToEnd = false

    private val animatorUpdateListener = object : AnimatorUpdateListener {
        override fun onAnimationUpdate(animation: ValueAnimator) {
            onAnimationUpdate.invoke(animation)
        }
    }

    private val animatorListener = object : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator) {
        }

        override fun onAnimationEnd(animation: Animator) {
            onAnimationEnd.invoke(mSlideToEnd)
        }

        override fun onAnimationCancel(animation: Animator) {
        }

        override fun onAnimationRepeat(animation: Animator) {
        }

    }

    init {
        createAnimation(animatorUpdateListener, animatorListener)
    }

    fun endAnimation() {
        mValueAnimator?.let {
            if (it.values != null && it.isRunning) {
                it.end()
            }
        } ?: let {
            Log.w(TAG_SLIDE_ANIMATION, "endAnimation fail, for mValueAnimator is null")
        }
    }

    fun paramsChanged() {
        mValueAnimator?.let {
            it.setDuration(mBuilder.mAutoSlideDuration.toLong())
            it.interpolator = mBuilder.mInterpolator
        } ?: let {
            Log.w(TAG_SLIDE_ANIMATION, "paramsChanged fail, for mValueAnimator is null")
        }
    }

    val isAnimationRunning: Boolean
        get() = mValueAnimator != null && mValueAnimator?.isRunning == true

    fun setValuesAndStart(from: Float, to: Float, slideToEnd: Boolean = false) {
        Log.d(TAG_SLIDE_ANIMATION, "setValuesAndStart, from:$from, to:$to")
        slideAnimationTo = to
        mSlideToEnd = slideToEnd
        mValueAnimator?.let {
            it.setFloatValues(from, to)
            it.start()
        } ?: let {
            Log.w(TAG_SLIDE_ANIMATION, "setValuesAndStart fail, for mValueAnimator is null")
        }
    }

    private fun createAnimation(updateListener: AnimatorUpdateListener, listener: Animator.AnimatorListener) {
        mValueAnimator = ValueAnimator.ofFloat().apply {
            setDuration(mBuilder.mAutoSlideDuration.toLong())
            interpolator = mBuilder.mInterpolator
            addUpdateListener(updateListener)
            addListener(listener)
        }
    }
}
