package com.seatel.mobilehall.util.customview

import android.animation.Animator
import com.facebook.drawee.view.SimpleDraweeView
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.RectF
import android.util.AttributeSet

/**
 * Created by daniel on 7/4/2018 AD.
 */
class ParallaxView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyle: Int = 0, defStyleRes: Int = 0) :
    SimpleDraweeView(context,attrs,defStyle,defStyleRes) {
    private var observerImageLoading: ValueAnimator? = null

    // It would be actual image rect.
    private val rect = RectF()

    // It would be draw matrix.
    private val mMatrix = Matrix()

    // scale between image width and view width
    private var scale = 1f

    // It is fixed when initiated first time.
    private var mTranslationX = 0f


    override fun onDraw(canvas: Canvas) {
        if (observerImageLoading == null) {
            initObserver()
        }
        val saveCount = canvas.save()
        canvas.concat(mMatrix)
        super.onDraw(canvas)
        canvas.restoreToCount(saveCount)
    }

    private fun initObserver() {
        observerImageLoading = ValueAnimator.ofInt(0, 1)
        observerImageLoading!!.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {}
            override fun onAnimationEnd(animation: Animator) {}
            override fun onAnimationCancel(animation: Animator) {}
            override fun onAnimationRepeat(animation: Animator) {
                resetMatrix()
                postInvalidate()
                if (rect.width() != 0f) {
                    observerImageLoading!!.cancel()
                }
            }
        })
        observerImageLoading!!.duration = 60
        observerImageLoading!!.repeatCount = ValueAnimator.INFINITE
        observerImageLoading!!.start()
    }

    private fun resetMatrix() {
        mMatrix.reset()
        hierarchy.getActualImageBounds(rect)
        mMatrix.mapRect(rect)
        scale = height.toFloat() / rect.height()
        mTranslationX = -(height - rect.height()) / 2 * scale
        mMatrix.postScale(scale, scale)
        mMatrix.postTranslate(0f, mTranslationX)
    }

    /**
     * translate actual image by offset.
     *
     * @param offset is between 0 to 1.
     * 0 : view top      <->     image top
     * 1 : view bottom   <->     image bottom
     */
    fun setOffset(offset: Float) {
        resetMatrix()
        val translationX = (rect.width() * scale - width) * offset
        mMatrix.postTranslate(-translationX, 0f)
        postInvalidate()
    }
}