package com.adealink.weparty.commonui.recycleview.layoutmanager

import android.graphics.Point
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView

/**
 * 我的勋章 布局管理器
 * 具体布局样式详见蓝湖（https://lanhuapp.com/web/#/item/project/stage?pid=0c119e80-c008-474b-9600-d53b51a43da8&image_id=113c75cc-afe4-47d7-9d0e-b8ff1f4a39b8）
 */
class CenterGridLayoutManger(
    private val span: Int //每行最多放多少个Item
) : RecyclerView.LayoutManager() {
    private val mOrientationHelper =
        OrientationHelper.createOrientationHelper(this, RecyclerView.HORIZONTAL)

    override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
        return RecyclerView.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )
    }

    /**
     * 禁止水平方向的滑动
     */
    override fun canScrollHorizontally(): Boolean {
        return false
    }

    /**
     * 禁止垂直方向的滑动
     */
    override fun canScrollVertically(): Boolean {
        return false
    }

    override fun isAutoMeasureEnabled(): Boolean {
        return true
    }

    /**
     * 布局
     */
    override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
        super.onLayoutChildren(recycler, state)
        if (state.itemCount == 0) {
            removeAndRecycleAllViews(recycler)
            return
        }
        detachAndScrapAttachedViews(recycler)

        onLayout(recycler, state.itemCount)
        recycleChildren(recycler)
    }

    /**
     * 确定Item位置,尺寸
     */
    private fun onLayout(recycler: RecyclerView.Recycler, itemCount: Int) {
        val itemWidth = width / span

        //先摆第一行
        var itemCountPerLine = (itemCount % span)
        if (itemCountPerLine == 0) {
            //等于0说明能放"span"个
            itemCountPerLine = span
        }
        var viewIndex = 0
        var left = (width - itemCountPerLine * itemWidth) / 2
        var itemHeight = 0
        for (i in 0 until itemCountPerLine) {
            itemHeight = addViewAndLayout(recycler, viewIndex, itemWidth, left, 0)
            viewIndex++
            left += itemWidth
        }

        //再摆剩余的几行
        itemCountPerLine = span
        var top = itemHeight
        while (viewIndex < itemCount) {
            left = 0
            for (i in 0 until itemCountPerLine) {
                addViewAndLayout(recycler, viewIndex, itemWidth, left, top)
                viewIndex++
                left += itemWidth
            }
            top += itemHeight
        }
    }

    private fun addViewAndLayout(
        recycler: RecyclerView.Recycler,
        index: Int,
        itemWidth: Int,
        left: Int,
        top: Int
    ): Int {

        val itemView = recycler.getViewForPosition(index)
        addView(itemView)

        val wSpec = getChildMeasureSpec(
            mOrientationHelper.totalSpace,
            widthMode,
            0,
            itemWidth, false
        )
        val hSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        itemView.measure(wSpec, hSpec)

        layoutDecorated(
            itemView,
            left,
            top,
            left + itemWidth,
            top + itemView.measuredHeight
        )
        return itemView.measuredHeight
    }

    /**
     * 计算出控件
     */
    private fun initGuideLine(): Map<Int, List<Int>> {
        val blockCount = (2 * span - 1) * 2
        val blockWith = width / blockCount
        val locationMap = hashMapOf<Int, MutableList<Int>>()
        for (i in 1..span) {
            var points = locationMap[i]
            if (points == null) {
                points = mutableListOf()
            }
            points.add(((i - 1) * 2 + 1) * blockWith)
        }
        return locationMap
    }

    /**
     * 获取当前View坐标(x,y)
     */
    private fun getViewLocation(viewIndex: Int, itemCount: Int): Point {

        if (viewIndex < span - 1) {
            return Point(0, viewIndex)
        }
        val line1Count = itemCount % span
        val row = (viewIndex - line1Count) / span + 1
        val col = (viewIndex - line1Count) % span
        return Point(row, col)
    }

    /**
     * 回收屏幕外需回收的Item
     */
    private fun recycleChildren(recycler: RecyclerView.Recycler) {
        val scrapList = recycler.scrapList
        for (i in scrapList.indices) {
            val holder = scrapList[i]
            removeView(holder.itemView)
            recycler.recycleView(holder.itemView)
        }
    }
}