package com.seatel.mobilehall.util

import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.graphics.drawable.TransitionDrawable
import android.view.View
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Transformation
import android.widget.ImageView
import android.widget.LinearLayout

class AnimationUtil {

    private var mOnAnimationFinish: OnAnimationFinish? = null
    private var mTargetHeight = 0

    fun setAnimationFinish(onAnimationFinish: OnAnimationFinish?) {
        mOnAnimationFinish = onAnimationFinish
    }

    fun expand(v: View) {
        if (v.visibility == View.VISIBLE) return
        v.clearAnimation()
        v.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
        val targetHeight = v.measuredHeight
        v.layoutParams.height = 0
        v.visibility = View.VISIBLE
        val a: Animation = object : Animation() {
            override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
                v.layoutParams.height =
                    if (interpolatedTime == 1f) LinearLayout.LayoutParams.WRAP_CONTENT else (targetHeight * interpolatedTime).toInt()
                v.requestLayout()
            }

            override fun willChangeBounds(): Boolean {
                return true
            }
        }
        a.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                a.setAnimationListener(null)
                if (mOnAnimationFinish != null) mOnAnimationFinish!!.onAnimationFinishExpand()
            }

            override fun onAnimationRepeat(animation: Animation) {}
        })
        a.duration = ((targetHeight / v.context.resources.displayMetrics.density)).toLong()
        v.startAnimation(a)
    }

    fun collapse(v: View) {
        if (v.visibility == View.GONE) return
        v.clearAnimation()
        val targetHeight = v.measuredHeight
        val a: Animation = object : Animation() {
            override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
                v.layoutParams.height = targetHeight - (targetHeight * interpolatedTime).toInt()
                v.requestLayout()
            }

            override fun willChangeBounds(): Boolean {
                return true
            }
        }
        a.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                v.visibility = View.GONE
                a.setAnimationListener(null)
                if (mOnAnimationFinish != null) mOnAnimationFinish!!.onAnimationFinishCollapse()
            }

            override fun onAnimationRepeat(animation: Animation) {}
        })
        a.duration = ((targetHeight / v.context.resources.displayMetrics.density).toInt()).toLong()
        v.startAnimation(a)
    }

    fun startTransactionDrawable(view: ImageView) {
        val transition = view.drawable as TransitionDrawable
        transition.startTransition(0)
    }

    fun resetTransactionDrawable(view: ImageView) {
        val transition = view.drawable as TransitionDrawable
        transition.resetTransition()
    }

    fun reverseTransactionDrawable(view: ImageView) {
        val transition = view.drawable as TransitionDrawable
        transition.reverseTransition(0)
    }

    @SuppressLint("ObjectAnimatorBinding")
    fun startAnimateProgress(value: Int, arcProgress: View?) {
        val progressAnimator = ObjectAnimator.ofFloat(arcProgress, "progress", 0f, value.toFloat())
        progressAnimator.duration = 1500
        progressAnimator.interpolator = DecelerateInterpolator()
        progressAnimator.start()
    }

    fun expand(v: View, speed: Int) {
        if (v.visibility == View.VISIBLE) return
        v.clearAnimation()
        v.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
        mTargetHeight = v.measuredHeight
        v.layoutParams.height = 0
        v.visibility = View.VISIBLE
        val a: Animation = object : Animation() {
            override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
                mTargetHeight += 6
                v.layoutParams.height =
                    if (interpolatedTime == 1f) LinearLayout.LayoutParams.WRAP_CONTENT else (mTargetHeight * interpolatedTime).toInt()
                v.requestLayout()
            }

            override fun willChangeBounds(): Boolean {
                return true
            }
        }
        a.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                a.setAnimationListener(null)
                if (mOnAnimationFinish != null) mOnAnimationFinish!!.onAnimationFinishExpand()
            }

            override fun onAnimationRepeat(animation: Animation) {}
        })
        a.duration =
            ((mTargetHeight / v.context.resources.displayMetrics.density).toInt() * speed).toLong()
        v.startAnimation(a)
    }

    fun collapse(v: View, speed: Int) {
        if (v.visibility == View.GONE) return
        v.clearAnimation()
        val targetHeight = v.measuredHeight
        val a: Animation = object : Animation() {
            override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
                v.layoutParams.height = targetHeight - (targetHeight * interpolatedTime).toInt()
                v.requestLayout()
            }

            override fun willChangeBounds(): Boolean {
                return true
            }
        }
        a.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                v.visibility = View.GONE
                a.setAnimationListener(null)
                if (mOnAnimationFinish != null) mOnAnimationFinish!!.onAnimationFinishCollapse()
            }

            override fun onAnimationRepeat(animation: Animation) {}
        })
        a.duration =
            ((targetHeight / v.context.resources.displayMetrics.density).toInt() * speed).toLong()
        v.startAnimation(a)
    }

    interface OnAnimationFinish {
        fun onAnimationFinishExpand()
        fun onAnimationFinishCollapse()
    }

    companion object {
        private var mAnimationUtil: AnimationUtil? = null
        val instance: AnimationUtil?
            get() {
                if (mAnimationUtil == null) mAnimationUtil = AnimationUtil()
                return mAnimationUtil
            }
    }
}