package com.github.mikephil.charting.manager

import android.graphics.Paint
import android.graphics.Typeface
import com.github.mikephil.charting.animation.Easing
import com.github.mikephil.charting.charts.PieChart
import com.github.mikephil.charting.components.Description
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.data.PieData
import com.github.mikephil.charting.data.PieDataSet
import com.github.mikephil.charting.data.PieEntry
import com.github.mikephil.charting.formatter.PercentFormatter


class MPieChartManager(var mPieChart: PieChart) {

    private lateinit var pieDataSet: PieDataSet

    /**
     * 饼状图中间是否显示中间的洞
     * @param isHole 是否显示中间的洞
     * @param vHole 设置中间洞的大小
     * @param vCircleRadius 半径
     * @param vCircleColor 颜色 0为透明
     * @param vCircleAlpha 透明度
     * */
    fun initCenter(
        isHole: Boolean,
        vHole: Float,
        vCircleRadius: Float,
        vCircleColor: Int,
        vCircleAlpha: Int
    ) {
        mPieChart.isDrawHoleEnabled = isHole// 是否显示中间的洞
        mPieChart.holeRadius = vHole// 设置中间洞的大小
        // 半透明圈
        mPieChart.transparentCircleRadius = vCircleRadius
        mPieChart.setTransparentCircleColor(vCircleColor) //设置半透明圆圈的颜色
        mPieChart.setTransparentCircleAlpha(vCircleAlpha) //设置半透明圆圈的透明度
    }

    /**
     * 饼状图中间是否添加文字
     * @param isTxt 是否添加文字
     * @param txt 设置中间文字
     * @param txtColor 中间文字的颜色
     * @param txtSizeDp 中间文字的大小dp
     * @param txtSizeSp 中间文字的大小sp
     * */
    fun setCenterText(
        isTxt: Boolean,
        txt: String = "",
        txtColor: Int = 0,
        txtSizeDp: Float = 0f,
        txtSizeSp: Float = 0f
    ) {
        mPieChart.setDrawCenterText(isTxt) //是否添加文字
        if (isTxt) {
            mPieChart.centerText = txt //设置中间文字
            mPieChart.setCenterTextColor(txtColor) //中间文字的颜色
            if (txtSizeDp != 0f) {
                mPieChart.setCenterTextSize(txtSizeDp)  //中间文字的大小dp
            } else {
                mPieChart.setCenterTextSizePixels(txtSizeSp)//中间文字的大小sp
            }
//            mPieChart.centerTextRadiusPercent = 180f//获取中间文本半径与空洞半径的百分比，默认100%
//            mPieChart.setCenterTextTypeface(Typeface.DEFAULT) //中间文字的样式
//            mPieChart.setCenterTextOffset(0F, 0F) //中间文字的偏移量
        }
    }

    /**
     * 是否可以手动旋转
     * @param isRation 是否可以手动旋转
     * @param rotationAngle 初始旋转角度
     * @param dfc 设置pieChart图表转动阻力摩擦系数[0-1] （值越小摩擦系数越大）
     * @param isPercent 是否显示成百分比
     * */
    fun setRotation(
        isRation: Boolean,
        isPercent: Boolean,
        rotationAngle: Float = 0f,
        dfc: Float = 0f
    ) {
        mPieChart.isRotationEnabled = isRation// 是否可以手动旋转
        if (isRation) {
            mPieChart.rotationAngle = rotationAngle// 初始旋转角度
            //设置摩擦系数（值越小摩擦系数越大）
            mPieChart.dragDecelerationFrictionCoef = dfc//设置pieChart图表转动阻力摩擦系数[0-1]
        }
        mPieChart.setUsePercentValues(isPercent)//是否显示成百分比
    }

    /**
     * 是否显示右下角描述
     * @param isDescription 是否取消右下角描述
     * */
    fun setDescription(
        isDescription: Boolean,
        des: String = "",
        size: Float = 0f,
        color: Int = 0,
        x: Float = 0f,
        y: Float = 0f,
        align: Paint.Align = Paint.Align.CENTER
    ) {
        mPieChart.description.isEnabled = isDescription //是否取消右下角描述
        if (isDescription) {
            var description = Description()
            description.text = des
            description.textSize = size
            description.textColor = color
            description.textAlign = align
            description.setPosition(x, y)
            mPieChart.description = description
        }
    }

    /**
     * 是否显示每个部分的文字描述
     * @param isDraw 是否显示每个部分的文字描述
     * @param etColor 描述文字的颜色
     * @param etSize 描述文字的大小
     * */
    fun setEntryLabel(isDraw: Boolean, etColor: Int, etSize: Float) {
        mPieChart.setDrawEntryLabels(isDraw)//是否显示每个部分的文字描述
        if (isDraw) {
            mPieChart.setEntryLabelColor(etColor) //描述文字的颜色
            mPieChart.setEntryLabelTextSize(etSize)//描述文字的大小
            mPieChart.setEntryLabelTypeface(Typeface.DEFAULT_BOLD) //描述文字的样式
        }
    }

    /**
     * 图相相关
     * @param left 图相对于上下左右的偏移
     * @param top 图相对于上下左右的偏移
     * @param right 图相对于上下左右的偏移
     * @param bom 图相对于上下左右的偏移
     *
     * */
    fun setExtraOffset(left: Float, top: Float, right: Float, bom: Float) {
        mPieChart.setExtraOffsets(left, top, right, bom)//图相对于上下左右的偏移
    }

    /**
     * 设置图标的背景色
     *
     * @param color 图标的背景色
     *
     */
    fun setBackgroundColor(color: Int){
        mPieChart.setBackgroundColor(color)//图标的背景色
    }

    /**
     * 获取图例
     * @param isEnacled 是否启用图列
     * @param orientation 设置图例水平显示: HORIZONTAL / VERTICAL
     * @param vAlignment 垂直布局：TOP/CENTER/BOTTOM
     * @param hAlignment 水平布局：RIGHT/CENTER/LEFT
     * @param xOs x轴的偏移
     * @param yOs y轴的偏移
     * @param color 字颜色
     * @param size 字大小
     * */
    fun setLegend(
        isEnacled: Boolean,
        orientation: Legend.LegendOrientation = Legend.LegendOrientation.HORIZONTAL,
        vAlignment: Legend.LegendVerticalAlignment = Legend.LegendVerticalAlignment.BOTTOM,
        hAlignment: Legend.LegendHorizontalAlignment = Legend.LegendHorizontalAlignment.CENTER,
        xOs: Float = 0f,
        yOs: Float = 0f,
        color: Int = 0,
        size: Float = 0f
    ) {
        //获取图例
        mPieChart.legend.apply {
            isEnabled = isEnacled
            if (isEnacled) {
                setOrientation(orientation)        //设置图例水平显示
                verticalAlignment = vAlignment   //顶部
                horizontalAlignment = hAlignment //右对其
                form = Legend.LegendForm.CIRCLE //设置图例的形状
                formToTextSpace = 10f               //设置每个图例实体中标签和形状之间的间距
                yOffset = yOs                       //设置比例块 Y 轴偏移量
                xOffset = xOs                    //设置比例块 X 轴偏移量
                textColor = color                //图例文字的颜色
                textSize = size                  //设置图例标签文本的大小
            }
        }
    }

    /**
     * 创建数据
     * @param pieEntryList 数据
     * @param colors 颜色
     * @param title 标题
     * @param sliceSpace 设置饼状Item之间的间隙
     * @param selSpace 设置饼状Item被选中时变化的距离
     * */
    fun setData(
        pieEntryList: List<PieEntry>,
        colors: List<Int>,
        title: String,
        sliceSpace: Float,
        selSpace: Float
    ) {
        //饼状图数据集 PieDataSet
        pieDataSet = PieDataSet(pieEntryList, title)
        pieDataSet.sliceSpace = sliceSpace           //设置饼状Item之间的间隙
        pieDataSet.selectionShift = selSpace      //设置饼状Item被选中时变化的距离
        pieDataSet.colors = colors           //为DataSet中的数据匹配上颜色集(饼图Item颜色)
    }

    /**
     * 设置数据
     * @param pieEntryList 数据
     * */
    fun setData(pieEntryList: List<PieEntry>) {
        pieDataSet = mPieChart.data.getDataSetByIndex(0) as PieDataSet
        pieDataSet.entries = pieEntryList
        pieDataSet.setDrawValues(false)
        mPieChart.data.notifyDataChanged()
    }

    /**
     * 创建数据
     * @param isValueShow 设置是否显示数据实体(百分比，true:以下属性才有意义)
     * @param valueSize 设置所有DataSet内数据实体（百分比）的文本字体大小
     * @param valueColor 设置所有DataSet内数据实体（百分比）的文本颜色
     * @param part1 当值位置为外边线时，表示线的前半段长度
     * @param part2 当值位置为外边线时，表示线的后半段长度
     * @param per 当ValuePosits为OutsiDice时，指示偏移为切片大小的百分比
     * @param lineColor 当值位置为外边线时，表示线的颜色。
     * */
    fun setPercent(
        isValueShow: Boolean,
        valueSize: Float = 0f,
        valueColor: Int = 0,
        part1: Float = 0f,
        part2: Float = 0f,
        per: Float = 0f,
        lineColor: Int = 0
    ) {
        //最终数据 PieData
        var pieData = PieData(pieDataSet)
        if (isValueShow) {
            pieData.setDrawValues(isValueShow)            //设置是否显示数据实体(百分比，true:以下属性才有意义)
            pieData.setValueTextColor(valueColor)  //设置所有DataSet内数据实体（百分比）的文本颜色
            pieData.setValueTextSize(valueSize)          //设置所有DataSet内数据实体（百分比）的文本字体大小
            pieData.setValueFormatter(PercentFormatter())//设置所有DataSet内数据实体（百分比）的文本字体格式

            pieDataSet.valueLinePart1Length = part1// 当值位置为外边线时，表示线的前半段长度。
            pieDataSet.valueLinePart2Length = part2// 当值位置为外边线时，表示线的后半段长度。
            pieDataSet.valueLinePart1OffsetPercentage = per// 当ValuePosits为OutsiDice时，指示偏移为切片大小的百分比
            pieDataSet.valueLineColor = lineColor// 当值位置为外边线时，表示线的颜色。
            pieDataSet.yValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE// 设置Y值的位置是在圆内还是圆外
        }
        mPieChart.data = pieData
    }

    /**
     * 动画
     * @see 动画失效可能原因 1.添加混淆文件 2.先调用invalidate方法刷新数据
     * @param durationMillis 动画时长
     * @param easing 缓动函数
     */
    fun animateY(durationMillis: Int, easing: Easing.EasingFunction? = null) {
        if (null == easing) {
            mPieChart.animateY(durationMillis)
        } else {
            mPieChart.animateY(durationMillis, easing)
        }
    }

    /**
     * 动画
     *
     * @see 动画失效可能原因 1.添加混淆文件 2.先调用invalidate方法刷新数据
     * @param durationMillis 动画时长
     * @param easing 缓动函数
     */
    fun animateX(durationMillis: Int, easing: Easing.EasingFunction? = null) {
        if (null == easing) {
            mPieChart.animateX(durationMillis)
        } else {
            mPieChart.animateX(durationMillis, easing)
        }
    }

    /**
     * 动画
     * @see 动画失效可能原因 1.添加混淆文件 2.先调用invalidate方法刷新数据
     * @param durationMillis 动画时长
     * @param easing 缓动函数
     */
    fun animateXY(
        durationMillisX: Int,
        durationMillisY: Int,
        easing: Easing.EasingFunction? = null
    ) {
        if (null == easing) {
            mPieChart.animateXY(durationMillisX, durationMillisY)
        } else {
            mPieChart.animateXY(durationMillisX, durationMillisY, easing)
        }
    }

    /**
     * 是否显示百分比
     * */
    fun changePercent(b: Boolean) {
        for (set in mPieChart.data.dataSets) {
            set.setDrawValues(b)
        }
        invalidate()
    }

    /**
     * 刷新
     * */
    fun invalidate() {
        mPieChart.invalidate()
    }

    /**
     * 是否显示饼图上文字
     */
    fun showLabels(isShow: Boolean) {
        mPieChart.setDrawEntryLabels(isShow)//是否显示饼图上文字
    }

    /**
     * 设置初始旋转角度
     */
    fun setRotationAngle(rotationAngle: Float){
        mPieChart.rotationAngle = rotationAngle// 初始旋转角度
    }


    /**
     * 其他设置
     * */
    fun initOther() {
        mPieChart.highlightValues(null)

    }

    /**
     * 设置Y轴数据是否显示
     */
    fun setYValues(drawYValues: Boolean) {
        for (set in mPieChart.data.dataSets) {
            set.setDrawValues(drawYValues)
        }
        mPieChart.invalidate()
    }

    /**
     * 隐藏X轴数据是否显示
     */
    fun setXValues(drawXValues: Boolean) {
        mPieChart.setDrawEntryLabels(drawXValues)
        mPieChart.invalidate()
    }
}
