package com.abbidot.tracker.widget

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.DashPathEffect
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Point
import android.graphics.RectF
import android.graphics.Region
import android.text.TextUtils
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.graphics.toRect
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.bean.PointBean
import com.abbidot.tracker.util.ImageUtil
import com.qmuiteam.qmui.util.QMUIDisplayHelper

/**
 *Created  by .yzq on 2022/1/22/022.
 * @link   按以下点组成的多边形
 *         A
 *      F    B
 *      E    C
 *        D
 * @description:添加围栏多边形，只针对围栏
 */
class FencesPolygonView : View {

    companion object {
        const val POINT_A = 1
        const val POINT_B = 2
        const val POINT_C = 3
        const val POINT_D = 4
        const val POINT_E = 5
        const val POINT_F = 6
    }

    private var mWidth = 0
    private var mHeight = 0

    //中心坐标点
    private var mCentreX = 0f
    private var mCentreY = 0f
    private var mAPoint = PointBean()
    private var mFPoint = PointBean()
    private var mEPoint = PointBean()
    private var mDPoint = PointBean()
    private var mCPoint = PointBean()
    private var mBPoint = PointBean()
    private var mTempPoint = PointBean()

    //最外层组成的隐藏的矩形
    private var mOutHideRectWidth = 0f
    private var mOutHideRectHeight = 0f

    //限制边长
    var mLimitSide = 0f

    //定位图标
    private var mLocationBitmap: Bitmap? = null
    private var mDotBitmap: Bitmap? = null

    private lateinit var mDashedPaint: Paint
    private lateinit var mFillPaint: Paint

    private lateinit var mPath: Path

    private var mDashedColor = 0
    private var mFillBgColor = 0

    private var mTouchPointTag = ""
    private val mTageA = "A"
    private val mTageB = "B"
    private val mTageC = "C"
    private val mTageD = "D"
    private val mTageE = "E"
    private val mTageF = "F"

    private var isDrag = false
    private var mOldX = 0f
    private var mOldY = 0f

    //创建矩形的区域,  https://www.jianshu.com/p/6a5d8f0f68d4
    private lateinit var mRectRegion: Region

    //创建路径Path区域,最后获得和矩形的交集
    private lateinit var mPathRegion: Region
    private lateinit var mPathRectF: RectF

    //是否需要测量，防止百度地图使用会执行onMeasure/地图页面上下滑动重新布局执行onMeasure
    private var isNeedMeasure = true

    private var mPointPullClickListener: OnPolygonViewPointPullClickListener? = null

    constructor(context: Context) : super(context) {
        init(context, null)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context, attrs, defStyleAttr
    ) {
        init(context, attrs)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init(context, attrs)
    }

    private fun init(context: Context, attrs: AttributeSet?) {
        initAttrs(context, attrs)

        //禁用硬件加速,防止返回到界面多次执行onDraw
        setLayerType(LAYER_TYPE_SOFTWARE, null)

        mPath = Path()

        mRectRegion = Region()
        mPathRegion = Region()
        mPathRectF = RectF()

        mFillPaint = Paint()
        mFillPaint.color = mFillBgColor

        mDashedPaint = Paint()
        mDashedPaint.style = Paint.Style.STROKE
        mDashedPaint.strokeWidth = QMUIDisplayHelper.dpToPx(1).toFloat()
        //虚线长度
        val dashPathWidth = QMUIDisplayHelper.dpToPx(6).toFloat()
        mDashedPaint.pathEffect = DashPathEffect(floatArrayOf(dashPathWidth, dashPathWidth), 0f)
        mDashedPaint.color = mDashedColor

    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
//        if (null == attrs) {
//            return
//        }
        mDashedColor = ContextCompat.getColor(context, R.color.select_color)
        mFillBgColor = ContextCompat.getColor(context, R.color.select_color4)
        mLocationBitmap =
            ImageUtil.getBitmapFromDrawableAndSvg(context, R.drawable.icon_fences_zone_gps_svg)
        mDotBitmap = ImageUtil.getBitmapFromDrawableAndSvg(
            context, R.drawable.icon_fence_polygon_operate_svg
        )
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mWidth = measuredWidth
        mHeight = measuredHeight
        LogUtil.e("${javaClass.canonicalName}:onMeasure---mWidth=$mWidth,mHeight=$mHeight")

        if (isNeedMeasure) {
            mCentreX = mWidth / 2f
            mCentreY = mHeight / 2f

            initPoint()
        }
    }

    private fun initPoint() {
        if (mOutHideRectHeight <= 0 || mOutHideRectWidth <= 0) return
        mAPoint.x = mCentreX
        mAPoint.y = mCentreY - mOutHideRectHeight / 2
        mFPoint.x = mCentreX - mOutHideRectWidth / 2
        mFPoint.y = mCentreY - mOutHideRectHeight / 4
        mEPoint.x = mFPoint.x
        mEPoint.y = mCentreY + mOutHideRectHeight / 4
        mDPoint.x = mAPoint.x
        mDPoint.y = mCentreY + mOutHideRectHeight / 2
        mCPoint.x = mCentreX + mOutHideRectWidth / 2
        mCPoint.y = mEPoint.y
        mBPoint.x = mCPoint.x
        mBPoint.y = mFPoint.y

        getCentreXY()
    }

    private fun getCentreXY() {
        val minX = minOf(mAPoint.x, mFPoint.x, mEPoint.x, mDPoint.x, mCPoint.x, mBPoint.x)
        val maxX = maxOf(mAPoint.x, mFPoint.x, mEPoint.x, mDPoint.x, mCPoint.x, mBPoint.x)
        val minY = minOf(mAPoint.y, mFPoint.y, mEPoint.y, mDPoint.y, mCPoint.y, mBPoint.y)
        val maxY = maxOf(mAPoint.y, mFPoint.y, mEPoint.y, mDPoint.y, mCPoint.y, mBPoint.y)
        val rectF = RectF(minX, minY, maxX, maxY)

        //中心点改变时
        mCentreX = rectF.centerX()
        mCentreY = rectF.centerY()
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        LogUtil.e("onAttachedToWindow,${javaClass.canonicalName}视图显示")
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.apply {
            startDraw(this)
        }
    }

    private fun startDraw(canvas: Canvas) {
        getCentreXY()
        canvas.let {
            mLocationBitmap?.apply {
                it.drawBitmap(this, mCentreX - width / 2, mCentreY - height / 2, null)
            }
            mPath.apply {
                moveTo(mAPoint.x, mAPoint.y)
                lineTo(mFPoint.x, mFPoint.y)
                lineTo(mEPoint.x, mEPoint.y)
                lineTo(mDPoint.x, mDPoint.y)
                lineTo(mCPoint.x, mCPoint.y)
                lineTo(mBPoint.x, mBPoint.y)
                close()

                //计算控制点的边界
                mPath.computeBounds(mPathRectF, true)
                //设置区域路径
                mRectRegion.set(mPathRectF.toRect())
                //设置剪辑描述的区域
                mPathRegion.setPath(mPath, mRectRegion)

                it.drawPath(mPath, mFillPaint)
                it.drawPath(mPath, mDashedPaint)
                reset()
            }
            mDotBitmap?.apply {
                it.drawBitmap(this, mAPoint.x - width / 2, mAPoint.y - height / 2, null)
                it.drawBitmap(this, mFPoint.x - width / 2, mFPoint.y - height / 2, null)
                it.drawBitmap(this, mEPoint.x - width / 2, mEPoint.y - height / 2, null)
                it.drawBitmap(this, mDPoint.x - width / 2, mDPoint.y - height / 2, null)
                it.drawBitmap(this, mCPoint.x - width / 2, mCPoint.y - height / 2, null)
                it.drawBitmap(this, mBPoint.x - width / 2, mBPoint.y - height / 2, null)
            }
//            it.drawRect(mPathRectF, mFillPaint)
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    @Synchronized
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                val x = event.x
                val y = event.y
                mTouchPointTag = ""
                if (isClickWherePoint(x, y, mAPoint)) {
                    mTouchPointTag = mTageA
                } else if (isClickWherePoint(x, y, mFPoint)) {
                    mTouchPointTag = mTageB
                } else if (isClickWherePoint(x, y, mEPoint)) {
                    mTouchPointTag = mTageC
                } else if (isClickWherePoint(x, y, mDPoint)) {
                    mTouchPointTag = mTageD
                } else if (isClickWherePoint(x, y, mCPoint)) {
                    mTouchPointTag = mTageE
                } else if (isClickWherePoint(x, y, mBPoint)) {
                    mTouchPointTag = mTageF
                }
                if (!TextUtils.isEmpty(mTouchPointTag)) {
                    return true
                }
                if (mPathRegion.contains(x.toInt(), y.toInt())) {
                    isDrag = true
                    mOldX = x
                    mOldY = y
                    mDashedPaint.strokeWidth = QMUIDisplayHelper.dpToPx(3).toFloat()
                    mPointPullClickListener?.polygonStartDragClick()
                    invalidate()
                    return true
                }
            }

            MotionEvent.ACTION_MOVE -> {
                val x = event.x
                val y = event.y
                mTempPoint.x = x
                mTempPoint.y = y
                var isInvalidate = false
                when (mTouchPointTag) {
                    mTageA -> {
                        val intersectTBEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBEF$intersectTBEF")
                        if (intersectTBEF) {
                            return false
                        }
                        val intersectTBDE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBDE$intersectTBDE")
                        if (intersectTBDE) {
                            return false
                        }
                        val intersectTBCD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBCD$intersectTBCD")
                        if (intersectTBCD) {
                            return false
                        }
                        val intersectTBBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBBC$intersectTBBC")
                        if (intersectTBBC) {
                            return false
                        }

                        val intersectTFBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFBC$intersectTFBC")
                        if (intersectTFBC) {
                            return false
                        }
                        val intersectTFCD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFCD$intersectTFCD")
                        if (intersectTFCD) {
                            return false
                        }
                        val intersectTFDE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFDE$intersectTFDE")
                        if (intersectTFDE) {
                            return false
                        }
                        val intersectTFEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFEF$intersectTFEF")
                        if (intersectTFEF) {
                            return false
                        }
                        val tempRect = getTempRect(mTouchPointTag, mTempPoint)
                        if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
                            return false
                        }
                        mOutHideRectWidth = tempRect.width()
                        mOutHideRectHeight = tempRect.height()
                        mAPoint.x = x
                        mAPoint.y = y
                        isInvalidate = true
                    }

                    mTageB -> {
                        val intersectTCAF =
                            isSegmentIntersect(mAPoint, mBPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCAF$intersectTCAF")
                        if (intersectTCAF) {
                            return false
                        }
                        val intersectTCEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCEF$intersectTCEF")
                        if (intersectTCEF) {
                            return false
                        }
                        val intersectTCDE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCDE$intersectTCDE")
                        if (intersectTCDE) {
                            return false
                        }
                        val intersectTCCD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCCD$intersectTCCD")
                        if (intersectTCCD) {
                            return false
                        }


                        val intersectTACD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTACD$intersectTACD")
                        if (intersectTACD) {
                            return false
                        }
                        val intersectTADE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTADE$intersectTADE")
                        if (intersectTADE) {
                            return false
                        }
                        val intersectTAEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTAEF$intersectTAEF")
                        if (intersectTAEF) {
                            return false
                        }
                        val intersectTAFA =
                            isSegmentIntersect(mBPoint, mAPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTAFA$intersectTAFA")
                        if (intersectTAFA) {
                            return false
                        }
                        val tempRect = getTempRect(mTouchPointTag, mTempPoint)
                        if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
                            return false
                        }
                        mOutHideRectWidth = tempRect.width()
                        mOutHideRectHeight = tempRect.height()
                        mFPoint.x = x
                        mFPoint.y = y
                        isInvalidate = true
                    }

                    mTageC -> {
                        val intersectTBDE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBDE$intersectTBDE")
                        if (intersectTBDE) {
                            return false
                        }
                        val intersectTBEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBEF$intersectTBEF")
                        if (intersectTBEF) {
                            return false
                        }
                        val intersectTBFA =
                            isSegmentIntersect(mBPoint, mAPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBFA$intersectTBFA")
                        if (intersectTBFA) {
                            return false
                        }
                        val intersectTBAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mFPoint)
                        LogUtil.i("交点intersectTBAB$intersectTBAB")
                        if (intersectTBAB) {
                            return false
                        }

                        val intersectTDAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDAB$intersectTDAB")
                        if (intersectTDAB) {
                            return false
                        }
                        val intersectTDAF =
                            isSegmentIntersect(mAPoint, mBPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDAF$intersectTDAF")
                        if (intersectTDAF) {
                            return false
                        }
                        val intersectTDEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDEF$intersectTDEF")
                        if (intersectTDEF) {
                            return false
                        }
                        val intersectTDED =
                            isSegmentIntersect(mCPoint, mDPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDED$intersectTDED")
                        if (intersectTDED) {
                            return false
                        }
                        val tempRect = getTempRect(mTouchPointTag, mTempPoint)
                        if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
                            return false
                        }
                        mOutHideRectWidth = tempRect.width()
                        mOutHideRectHeight = tempRect.height()
                        mEPoint.x = x
                        mEPoint.y = y
                        isInvalidate = true
                    }

                    mTageD -> {
                        val intersectTCEF =
                            isSegmentIntersect(mCPoint, mBPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCEF$intersectTCEF")
                        if (intersectTCEF) {
                            return false
                        }
                        val intersectTCAF =
                            isSegmentIntersect(mAPoint, mBPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCAF$intersectTCAF")
                        if (intersectTCAF) {
                            return false
                        }
                        val intersectTCAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCAB$intersectTCAB")
                        if (intersectTCAB) {
                            return false
                        }
                        val intersectTCBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mEPoint)
                        LogUtil.i("交点intersectTCBC$intersectTCBC")
                        if (intersectTCBC) {
                            return false
                        }

                        val intersectTEBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEBC$intersectTEBC")
                        if (intersectTEBC) {
                            return false
                        }
                        val intersectTEAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEAB$intersectTEAB")
                        if (intersectTEAB) {
                            return false
                        }
                        val intersectTEAF =
                            isSegmentIntersect(mAPoint, mBPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEAF$intersectTEAF")
                        if (intersectTEAF) {
                            return false
                        }
                        val intersectTEFE =
                            isSegmentIntersect(mBPoint, mCPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEFE$intersectTEFE")
                        if (intersectTEFE) {
                            return false
                        }
                        val tempRect = getTempRect(mTouchPointTag, mTempPoint)
                        if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
                            return false
                        }
                        mOutHideRectWidth = tempRect.width()
                        mOutHideRectHeight = tempRect.height()
                        mDPoint.x = x
                        mDPoint.y = y
                        isInvalidate = true
                    }

                    mTageE -> {
                        val intersectTDAF =
                            isSegmentIntersect(mAPoint, mBPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDAF$intersectTDAF")
                        if (intersectTDAF) {
                            return false
                        }
                        val intersectTDAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDAB$intersectTDAB")
                        if (intersectTDAB) {
                            return false
                        }
                        val intersectTDBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDBC$intersectTDBC")
                        if (intersectTDBC) {
                            return false
                        }
                        val intersectTDCD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mDPoint)
                        LogUtil.i("交点intersectTDCD$intersectTDCD")
                        if (intersectTDCD) {
                            return false
                        }

                        val intersectTFCD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFCD$intersectTFCD")
                        if (intersectTFCD) {
                            return false
                        }
                        val intersectTFBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFBC$intersectTFBC")
                        if (intersectTFBC) {
                            return false
                        }
                        val intersectTFAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFAB$intersectTFAB")
                        if (intersectTFAB) {
                            return false
                        }
                        val intersectTFAF =
                            isSegmentIntersect(mAPoint, mBPoint, mTempPoint, mBPoint)
                        LogUtil.i("交点intersectTFAF$intersectTFAF")
                        if (intersectTFAF) {
                            return false
                        }
                        val tempRect = getTempRect(mTouchPointTag, mTempPoint)
                        if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
                            return false
                        }
                        mOutHideRectWidth = tempRect.width()
                        mOutHideRectHeight = tempRect.height()
                        mCPoint.x = x
                        mCPoint.y = y
                        isInvalidate = true
                    }

                    mTageF -> {
                        val intersectTEAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEAB$intersectTEAB")
                        if (intersectTEAB) {
                            return false
                        }
                        val intersectTEBC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEBC$intersectTEBC")
                        if (intersectTEBC) {
                            return false
                        }
                        val intersectTECD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTECD$intersectTECD")
                        if (intersectTECD) {
                            return false
                        }
                        val intersectTEDE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mCPoint)
                        LogUtil.i("交点intersectTEDE$intersectTEDE")
                        if (intersectTEDE) {
                            return false
                        }

                        val intersectTADE =
                            isSegmentIntersect(mDPoint, mCPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTADE$intersectTADE")
                        if (intersectTADE) {
                            return false
                        }
                        val intersectTACD =
                            isSegmentIntersect(mEPoint, mDPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTACD$intersectTACD")
                        if (intersectTACD) {
                            return false
                        }
                        val intersectTABC =
                            isSegmentIntersect(mFPoint, mEPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTABC$intersectTABC")
                        if (intersectTABC) {
                            return false
                        }
                        val intersectTAAB =
                            isSegmentIntersect(mAPoint, mFPoint, mTempPoint, mAPoint)
                        LogUtil.i("交点intersectTAAB$intersectTAAB")
                        if (intersectTAAB) {
                            return false
                        }
                        val tempRect = getTempRect(mTouchPointTag, mTempPoint)
                        if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
                            return false
                        }
                        mOutHideRectWidth = tempRect.width()
                        mOutHideRectHeight = tempRect.height()
                        mBPoint.x = x
                        mBPoint.y = y
                        isInvalidate = true
                    }
                }
                if (isInvalidate) {
                    invalidate()
                    return true
                } else if (isDrag) {
                    val transformX = x - mOldX
                    val transformY = y - mOldY
                    mCentreX += transformX
                    mCentreY += transformY
                    mAPoint.x += transformX
                    mAPoint.y += transformY
                    mBPoint.x += transformX
                    mBPoint.y += transformY
                    mCPoint.x += transformX
                    mCPoint.y += transformY
                    mDPoint.x += transformX
                    mDPoint.y += transformY
                    mEPoint.x += transformX
                    mEPoint.y += transformY
                    mFPoint.x += transformX
                    mFPoint.y += transformY
                    mOldX = x
                    mOldY = y
                    invalidate()
                    return true
                }
            }

            MotionEvent.ACTION_UP -> {
                if (isDrag) {
                    mPointPullClickListener?.polygonEndDragClick()
                    isDrag = false
                    mDashedPaint.strokeWidth = QMUIDisplayHelper.dpToPx(1).toFloat()
                    invalidate()
                } else {
                    mPointPullClickListener?.polygonPointPullClick()
                }
            }
        }
        return super.onTouchEvent(event)
    }

    private fun getTempRect(touchPointTag: String, tempPoint: PointBean): RectF {
        when (touchPointTag) {
            mTageA -> {
                val listX =
                    listOf(tempPoint.x, mBPoint.x, mCPoint.x, mDPoint.x, mEPoint.x, mFPoint.x)
                val listY =
                    listOf(tempPoint.y, mBPoint.y, mCPoint.y, mDPoint.y, mEPoint.y, mFPoint.y)
                return getTRect(listX, listY)
            }

            mTageB -> {
                val listX =
                    listOf(mAPoint.x, tempPoint.x, mCPoint.x, mDPoint.x, mEPoint.x, mFPoint.x)
                val listY =
                    listOf(mAPoint.y, tempPoint.y, mCPoint.y, mDPoint.y, mEPoint.y, mFPoint.y)
                return getTRect(listX, listY)
            }

            mTageC -> {
                val listX =
                    listOf(mAPoint.x, mBPoint.x, tempPoint.x, mDPoint.x, mEPoint.x, mFPoint.x)
                val listY =
                    listOf(mAPoint.y, mBPoint.y, tempPoint.y, mDPoint.y, mEPoint.y, mFPoint.y)
                return getTRect(listX, listY)
            }

            mTageD -> {
                val listX =
                    listOf(mAPoint.x, mBPoint.x, mCPoint.x, tempPoint.x, mEPoint.x, mFPoint.x)
                val listY =
                    listOf(mAPoint.y, mBPoint.y, mCPoint.y, tempPoint.y, mEPoint.y, mFPoint.y)
                return getTRect(listX, listY)
            }

            mTageE -> {
                val listX =
                    listOf(mAPoint.x, mBPoint.x, mCPoint.x, mDPoint.x, tempPoint.x, mFPoint.x)
                val listY =
                    listOf(mAPoint.y, mBPoint.y, mCPoint.y, mDPoint.y, tempPoint.y, mFPoint.y)
                return getTRect(listX, listY)
            }

            mTageF -> {
                val listX =
                    listOf(mAPoint.x, mBPoint.x, mCPoint.x, mDPoint.x, mEPoint.x, tempPoint.x)
                val listY =
                    listOf(mAPoint.y, mBPoint.y, mCPoint.y, mDPoint.y, mEPoint.y, tempPoint.y)
                return getTRect(listX, listY)
            }
        }
        return RectF()
    }

    private fun getTRect(listX: List<Float>, listY: List<Float>): RectF {
        val minX = listX.min()
        val minY = listY.min()
        val maxX = listX.max()
        val maxY = listY.max()
        return RectF(minX, minY, maxX, maxY)
    }

    private fun crossProduct(p1: PointBean, p2: PointBean, p3: PointBean): Float {
        val x1 = p2.x - p1.x
        val y1 = p2.y - p1.y
        val x2 = p3.x - p1.x
        val y2 = p3.y - p1.y
        return x1 * y2 - x2 * y1
    }

    /**
     * 判断两条线段是否相交
     * https://zhuanlan.zhihu.com/p/644689588
     */
    private fun isSegmentIntersect(
        pointBean1: PointBean, pointBean2: PointBean, pointBean3: PointBean, pointBean4: PointBean
    ): Boolean {
        val d1 = crossProduct(pointBean1, pointBean2, pointBean3)
        val d2 = crossProduct(pointBean1, pointBean2, pointBean4)
        val d3 = crossProduct(pointBean3, pointBean4, pointBean1)
        val d4 = crossProduct(pointBean3, pointBean4, pointBean2)

        return d1 * d2 < 0 && d3 * d4 < 0
    }

    /**
     * 是否点击了某个点
     */
    private fun isClickWherePoint(downX: Float, downY: Float, pointBean: PointBean): Boolean {
        mDotBitmap?.apply {
            if (downX in pointBean.x - width..pointBean.x + width && downY in pointBean.y - height..pointBean.y + height) {
                return true
            }
            return false
        }
        return false
    }

    fun setOnPolygonViewPointPullClickListener(pointPullClickListener: OnPolygonViewPointPullClickListener) {
        mPointPullClickListener = pointPullClickListener
    }

    /**
     * 设置默认的大小
     */
    fun initDefaultWidthHeightSize(widthDp: Int = 120, heightDp: Int = 120) {
        mOutHideRectWidth = QMUIDisplayHelper.dpToPx(widthDp).toFloat()
        mOutHideRectHeight = QMUIDisplayHelper.dpToPx(heightDp).toFloat()
        initPoint()
        invalidate()
    }

    /**
     * 设置边框颜色和图片
     */
    fun setColorAndImage(
        context: Context,
        dashedColorRes: Int = 0,
        fillBgColorRes: Int = 0,
        locationDrawableRes: Int = 0,
        dotDrawableRes: Int = 0
    ) {
        var isRefresh = false
        if (dashedColorRes > 0) {
            mDashedColor = ContextCompat.getColor(context, dashedColorRes)
            mDashedPaint.color = mDashedColor
            isRefresh = true
        }
        if (fillBgColorRes > 0) {
            mFillBgColor = ContextCompat.getColor(context, fillBgColorRes)
            mFillPaint.color = mFillBgColor
            isRefresh = true
        }
        if (locationDrawableRes > 0) {
            mLocationBitmap = ImageUtil.getBitmapFromDrawableAndSvg(context, locationDrawableRes)
            isRefresh = true
        }
        if (dotDrawableRes > 0) {
            mDotBitmap = ImageUtil.getBitmapFromDrawableAndSvg(context, dotDrawableRes)
            isRefresh = true
        }
        if (isRefresh) invalidate()
    }

    /**
     * 获取中心点
     */
    fun getPolygonCentrePoint() = Point(mCentreX.toInt(), mCentreY.toInt())

    /**
     * 重新设置中心点
     */
    fun setCentreXY(point: Point) {
        point.let {
            val diffValueX = it.x - mCentreX
            val diffValueY = it.y - mCentreY

            mCentreX = it.x.toFloat()
            mCentreY = it.y.toFloat()

            mAPoint.apply {
                x += diffValueX
                y += diffValueY
            }
            mBPoint.apply {
                x += diffValueX
                y += diffValueY
            }
            mCPoint.apply {
                x += diffValueX
                y += diffValueY
            }
            mDPoint.apply {
                x += diffValueX
                y += diffValueY
            }
            mEPoint.apply {
                x += diffValueX
                y += diffValueY
            }
            mFPoint.apply {
                x += diffValueX
                y += diffValueY
            }
            isNeedMeasure = false
            invalidate()
        }
    }


    fun setPolygonABCDEFPoint(
        pointCentre: Point,
        pointA: Point,
        pointB: Point,
        pointC: Point,
        pointD: Point,
        pointE: Point,
        pointF: Point
    ) {
        mAPoint.apply {
            x = pointA.x.toFloat()
            y = pointA.y.toFloat()
        }
        mBPoint.apply {
            x = pointB.x.toFloat()
            y = pointB.y.toFloat()
        }
        mCPoint.apply {
            x = pointC.x.toFloat()
            y = pointC.y.toFloat()
        }
        mDPoint.apply {
            x = pointD.x.toFloat()
            y = pointD.y.toFloat()
        }
        mEPoint.apply {
            x = pointE.x.toFloat()
            y = pointE.y.toFloat()
        }
        mFPoint.apply {
            x = pointF.x.toFloat()
            y = pointF.y.toFloat()
        }
        mCentreX = pointCentre.x.toFloat()
        mCentreY = pointCentre.y.toFloat()
        invalidate()
    }

    /**
     * 获取多边形的某一个点
     */
    fun getPolygonABCDEFPoint(wherePoint: Int): Point {
        LogUtil.e("getPolygonABCDEFPoint,$mAPoint,$mCentreX")
        var point = PointBean()
        when (wherePoint) {
            POINT_A -> point = mAPoint
            POINT_B -> point = mBPoint
            POINT_C -> point = mCPoint
            POINT_D -> point = mDPoint
            POINT_E -> point = mEPoint
            POINT_F -> point = mFPoint
        }
        return Point(point.x.toInt(), point.y.toInt())
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        LogUtil.e("${javaClass.canonicalName}视图销毁")
        if (null != mLocationBitmap) {
            mLocationBitmap?.recycle()
            mLocationBitmap = null
        }
        if (null != mDotBitmap) {
            mDotBitmap?.recycle()
            mDotBitmap = null
        }
    }

}
