package com.gh.gamecenter.home.gamecollection.carousel

import android.view.View
import com.gh.gamecenter.common.view.stacklayoutmanager.StackAnimation
import com.gh.gamecenter.common.view.stacklayoutmanager.StackLayoutManager
import com.gh.gamecenter.R
import kotlin.math.pow

class GameCollectionStackAnimation(
    scrollOrientation: StackLayoutManager.ScrollOrientation,
    visibleCount: Int
) : StackAnimation(scrollOrientation, visibleCount) {
    private var mScale = 0.9F
    private var mOutScale = 1.0F
    private var mOutRotation = 0

    /**
     * 设置 item 缩放比例.
     * @param scale 缩放比例
     */
    fun setItemScaleRate(scale: Float) {
        mScale = scale
    }

    /**
     * 获取item缩放比例.
     * @return item缩放比例
     */
    fun getItemScaleRate(): Float {
        return mScale
    }

    /**
     * 设置 itemView 离开屏幕时候的缩放比例.
     * @param scale 缩放比例
     */
    fun setOutScale(scale: Float) {
        mOutScale = scale
    }

    /**
     * 获取 itemView 离开屏幕时候的缩放比例.
     * @return 缩放比例
     */
    fun getOutScale(): Float {
        return mOutScale
    }

    /**
     * 设置 itemView 离开屏幕时候的旋转角度.
     * @param rotation 旋转角度
     */
    fun setOutRotation(rotation: Int) {
        mOutRotation = rotation
    }

    /**
     * 获取 itemView 离开屏幕时候的旋转角度
     * @return 旋转角度
     */
    fun getOutRotation(): Int {
        return mOutRotation
    }

    override fun doAnimation(firstMovePercent: Float, itemView: View, position: Int) {
        val cover = itemView.findViewById<View>(R.id.cover)
        val content = itemView.findViewById<View>(R.id.content)
        if (cover != null && content != null) {
            val scale: Float
            var alpha = 1.0F
            val rotation: Float
            if (position == 0) {
                // 顶层item透明度变化
                cover.alpha = 0F
                content.alpha = 1F
                if (firstMovePercent > 0.5) alpha = 1F - 2 * (firstMovePercent - 0.5F)
                scale = 1 - ((1 - mOutScale) * firstMovePercent)
                rotation = mOutRotation * firstMovePercent
            } else {
                val minScale = (mScale.toDouble().pow(position.toDouble())).toFloat()
                val maxScale = (mScale.toDouble().pow((position - 1).toDouble())).toFloat()
                scale = minScale + (maxScale - minScale) * firstMovePercent
                when (position) {
                    1 -> {
                        cover.alpha = 0.3F - 0.3F * firstMovePercent
                        content.alpha = firstMovePercent
                    }
                    2 -> cover.alpha = 0.6F - 0.3F * firstMovePercent
                    3 -> {
                        cover.alpha = 1F - 0.4F * firstMovePercent
                        alpha = firstMovePercent
                    }
                }
                rotation = 0F
            }

            setItemPivotXY(mScrollOrientation, itemView)
            rotationFirstVisibleItem(mScrollOrientation, itemView, rotation)
            itemView.scaleX = scale
            itemView.scaleY = scale
            itemView.alpha = alpha
        }
    }

    private fun setItemPivotXY(
        scrollOrientation: StackLayoutManager.ScrollOrientation,
        view: View
    ) {
        when (scrollOrientation) {
            StackLayoutManager.ScrollOrientation.RIGHT_TO_LEFT -> {
                view.pivotX = view.measuredWidth.toFloat()
                view.pivotY = view.measuredHeight.toFloat() / 2
            }
            StackLayoutManager.ScrollOrientation.LEFT_TO_RIGHT -> {
                view.pivotX = 0F
                view.pivotY = view.measuredHeight.toFloat() / 2
            }
            StackLayoutManager.ScrollOrientation.BOTTOM_TO_TOP -> {
                view.pivotX = view.measuredWidth.toFloat() / 2
                view.pivotY = view.measuredHeight.toFloat()
            }
            StackLayoutManager.ScrollOrientation.TOP_TO_BOTTOM -> {
                view.pivotX = view.measuredWidth.toFloat() / 2
                view.pivotY = 0F
            }
        }
    }

    private fun rotationFirstVisibleItem(
        scrollOrientation: StackLayoutManager.ScrollOrientation,
        view: View,
        rotation: Float
    ) {
        when (scrollOrientation) {
            StackLayoutManager.ScrollOrientation.RIGHT_TO_LEFT -> view.rotationY = rotation
            StackLayoutManager.ScrollOrientation.LEFT_TO_RIGHT -> view.rotationY = -rotation
            StackLayoutManager.ScrollOrientation.BOTTOM_TO_TOP -> view.rotationX = -rotation
            StackLayoutManager.ScrollOrientation.TOP_TO_BOTTOM -> view.rotationX = rotation
        }
    }

}
