package com.bomostory.sceneeditmodule.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.DashPathEffect
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.RelativeLayout
import com.example.tfat.myapplication.R
import kotlinx.android.synthetic.main.actor_view.view.*
import android.graphics.Paint
import com.bomostory.sceneeditmodule.basicdata.Actor


class EditActorView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0): RelativeLayout(context, attrs, defStyleAttr) {
    init {
        initView()
    }
    var actor = Actor()
        set(value) {
            value?.let {
                field = value
                isSelect = it.isSelect
                actor_view_layout.actor = it
                val layoutParams = RelativeLayout.LayoutParams(it.sideLength, it.sideHeight)
                layoutParams.leftMargin = it.positionX
                layoutParams.topMargin = it.positionY
                actor_layout.layoutParams = layoutParams
                val actorLayoutParams = RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
                actor_view_layout.layoutParams = actorLayoutParams
                when(it.isMoveable) {
                    true -> actor_view_layout.setOnTouchListener(actorOnTouchListener())
                }
            }
        }

    var isSelect: Boolean = false
        set(value) {
            value?.let {
                field = value
                if (it) {
                    change_size_view.visibility = View.VISIBLE
                } else {
                    change_size_view.visibility = View.GONE
                }
            }
        }

    var actorCallback: OnActorChangeListener? = null

    private fun initView() {
        val inflater = LayoutInflater.from(context)
        inflater.inflate(R.layout.actor_view, this, true)
        this.setWillNotDraw(false)
        resize_button_right_bottom.setOnTouchListener(rightBottomSizeChangeListener())
        resize_button_left_top.setOnTouchListener(leftTopSizeChangeListener())
        resize_button_right_top.setOnTouchListener(rightTopSizeChangeListener())
        resize_button_left_bottom.setOnTouchListener(leftBottomSizeChangeListener())
    }


    private fun actorOnTouchListener() : View.OnTouchListener {
        var clickPeriod = 0L
        var positionStart = 0
        var positionEnd = 0
        var mx: Int
        var my: Int
        return View.OnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    clickPeriod = System.currentTimeMillis()
                    positionStart = (motionEvent.x).toInt()
                    positionEnd = (motionEvent.y).toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    if (!(Math.abs(motionEvent.x - positionStart) < 10 && Math.abs(motionEvent.y - positionEnd) < 10) && isSelect) {
                        mx = motionEvent.rawX.toInt() - positionStart
                        my = motionEvent.rawY.toInt() - positionEnd
                        var laParams = actor_layout.layoutParams as RelativeLayout.LayoutParams
                        laParams.setMargins(mx, my - 200, 0, 0)
                        actor_layout.layoutParams = laParams
                        val actorLayoutParams = RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
                        view.layoutParams = actorLayoutParams
                        actor.positionX = mx
                        actor.positionY = my - 200
                    }
                }
                MotionEvent.ACTION_UP -> {
                    if (Math.abs(motionEvent.x - positionStart) < 10 && Math.abs(motionEvent.y - positionEnd) < 10 && (System.currentTimeMillis() - clickPeriod) > 1000) {
                        actor.isSelect = !actor.isSelect
                        actorCallback?.onActorLongClick(actor)
                    } else if (Math.abs(motionEvent.x - positionStart) < 10 && Math.abs(motionEvent.y - positionEnd) < 10) {
                        actor.isSelect = !actor.isSelect
                        actorCallback?.onActorSelected(actor)
                    } else {
                        if (isSelect){
                            actorCallback?.onActorChange(actor)
                        }
                    }
                }
            }
            return@OnTouchListener true
        }
    }

    private fun rightBottomSizeChangeListener() : View.OnTouchListener {
        var positionX = 0
        var positionY = 0
        var sizeX = 0
        var sizeY = 0
        var x = 0
        var y = 0
        return View.OnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    val layoutParams = actor_layout.layoutParams as RelativeLayout.LayoutParams
                    sizeX = layoutParams.width
                    sizeY = layoutParams.height
                    x = layoutParams.leftMargin
                    y = layoutParams.topMargin
                    positionX = (motionEvent.rawX).toInt()
                    positionY = (motionEvent.rawY).toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    var mx =  motionEvent.rawX.toInt() - positionX
                    var my =  motionEvent.rawY.toInt() - positionY
                    var actorData = actor
                    actorData.sideLength = sizeX + mx
                    actorData.sideHeight = sizeY + my
                    actorData.positionX = x
                    actorData.positionY = y
                    actor = actorData
                }
                MotionEvent.ACTION_UP -> {
                    actor.isSelect = true
                    actorCallback?.onActorChange(actor)
                }
            }
            return@OnTouchListener true
        }
    }

    private fun leftTopSizeChangeListener() : View.OnTouchListener {
        var positionX = 0
        var positionY = 0
        var sizeX = 0
        var sizeY = 0
        var x = 0
        var y = 0
        return View.OnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    val layoutParams = actor_layout.layoutParams as RelativeLayout.LayoutParams
                    sizeX = layoutParams.width
                    sizeY = layoutParams.height
                    x = layoutParams.leftMargin
                    y = layoutParams.topMargin
                    positionX = (motionEvent.rawX).toInt()
                    positionY = (motionEvent.rawY).toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    var mx =  motionEvent.rawX.toInt() - positionX
                    var my =  motionEvent.rawY.toInt() - positionY
                    var actorData = actor
                    actorData.sideLength = sizeX - mx
                    actorData.sideHeight = sizeY - my
                    actorData.positionX = x + mx
                    actorData.positionY = y + my
                    actor = actorData
                }
                MotionEvent.ACTION_UP -> {
                    actor.isSelect = true
                    actorCallback?.onActorChange(actor)
                }
            }
            return@OnTouchListener true
        }
    }

    private fun rightTopSizeChangeListener() : View.OnTouchListener {
        var positionX = 0
        var positionY = 0
        var sizeX = 0
        var sizeY = 0
        var x = 0
        var y = 0
        return View.OnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    val layoutParams = actor_layout.layoutParams as RelativeLayout.LayoutParams
                    sizeX = layoutParams.width
                    sizeY = layoutParams.height
                    x = layoutParams.leftMargin
                    y = layoutParams.topMargin
                    positionX = (motionEvent.rawX).toInt()
                    positionY = (motionEvent.rawY).toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    var mx =  motionEvent.rawX.toInt() - positionX
                    var my =  motionEvent.rawY.toInt() - positionY
                    var actorData = actor
                    actorData.sideLength = sizeX + mx
                    actorData.sideHeight = sizeY - my
                    actorData.positionX = x
                    actorData.positionY = y + my
                    actor = actorData
                }
                MotionEvent.ACTION_UP -> {
                    actor.isSelect = true
                    actorCallback?.onActorChange(actor)
                }
            }
            return@OnTouchListener true
        }
    }

    private fun leftBottomSizeChangeListener() : View.OnTouchListener {
        var positionX = 0
        var positionY = 0
        var sizeX = 0
        var sizeY = 0
        var x = 0
        var y = 0
        return View.OnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    val layoutParams = actor_layout.layoutParams as RelativeLayout.LayoutParams
                    sizeX = layoutParams.width
                    sizeY = layoutParams.height
                    x = layoutParams.leftMargin
                    y = layoutParams.topMargin
                    positionX = (motionEvent.rawX).toInt()
                    positionY = (motionEvent.rawY).toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    var mx =  motionEvent.rawX.toInt() - positionX
                    var my =  motionEvent.rawY.toInt() - positionY
                    var actorData = actor
                    actorData.sideLength = sizeX - mx
                    actorData.sideHeight = sizeY + my
                    actorData.positionX = x + mx
                    actorData.positionY = y
                    actor = actorData
                }
                MotionEvent.ACTION_UP -> {
                    actor.isSelect = true
                    actorCallback?.onActorChange(actor)
                }
            }
            return@OnTouchListener true
        }
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        val mPaint = Paint()
        if(isSelect) {
            setLayerType(LAYER_TYPE_SOFTWARE, null)
            mPaint.style = Paint.Style.STROKE
            mPaint.strokeWidth = 5f
            mPaint.isAntiAlias = true
            mPaint.color = Color.parseColor("#4e342e")
            mPaint.pathEffect = DashPathEffect(floatArrayOf(8f, 8f), 0f)
            canvas?.drawLine(actor.positionX.toFloat() + 25, actor.positionY.toFloat() + 25, actor.positionX.toFloat() + 25, actor.positionY.toFloat() + actor.sideHeight.toFloat() - 25 , mPaint)
            canvas?.drawLine(actor.positionX.toFloat() + 25, actor.positionY.toFloat() + 25, actor.positionX.toFloat() + actor.sideLength.toFloat() - 25, actor.positionY.toFloat() + 25, mPaint)
            canvas?.drawLine(actor.positionX.toFloat() + 25, actor.positionY.toFloat() + actor.sideHeight.toFloat() - 25, actor.positionX.toFloat()  + actor.sideLength.toFloat() + 25, actor.positionY.toFloat() + actor.sideHeight.toFloat() - 25, mPaint)
            canvas?.drawLine(actor.positionX.toFloat() + actor.sideLength.toFloat() - 25, actor.positionY.toFloat() + 25, actor.positionX.toFloat() + actor.sideLength.toFloat() - 25, actor.positionY.toFloat() + actor.sideHeight.toFloat() - 25, mPaint)
        }
    }

    interface OnActorChangeListener{
        fun onActorChange(actor: Actor)
        fun onActorSelected(actor: Actor)
        fun onActorLongClick(actor: Actor)
    }
}