package cn.sagacloud.android.cadengine

import android.graphics.Color
import android.graphics.PointF
import android.util.Log
import cn.sagacloud.android.cadengine.types.*
import com.sybotan.android.graphy.SGraphyScene
import com.sybotan.base.extensions.toJson
import com.sybotan.base.utils.SHttpUtil
import com.sybotan.base.utils.SJsonUtil
import android.text.TextUtils
import cn.sagacloud.android.cadengine.items.*
import com.sybotan.android.graphy.SMotionEvent
import com.sybotan.android.graphy.events.SGraphyViewMoveEvent
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**
 * 楼层场景
 *
 * @author  庞利祥(sybotan@126.com)
 */
open class FloorScene : SGraphyScene() {
    //点击事件回调到界面
    lateinit var topUp: OnSingleTopUp

    //    var item: PointItem? = null
//    val point = Point()
    var canEdit = true
    var point = Point()
    var item: QrcodeItem? = null
    var eqItem: EquipItem? = null

    var pipeItem: PipeLineItem? = null

    /** 默认缩放比例，用于指定最小缩放比例*/
    var defaultPointScale = 0.01785718f

    /**
     * normol 普通可以查看，可以点击问题点的模式
     * dot 绘制问题点
     * pipe 绘制管道模式
     * qrcode 绘制二维码
     * equip 绘制设备
     */
    var type: String? = "normal"

    /**
     * nothing 不显示任何操作界面
     * space 选中某一空间
     */
    var mapType: String? = "nothing"
    var choseSpace: TunableSpaceItem? = null
    var pipeLineList: ArrayList<PointF> = ArrayList()

    /**  正在绘制的管道 */
    val drawingPipeItemList = ArrayList<PipeLineItem>()

    /** item 数据  */
    var data: FloorData? = null
        set(value) {
            addBaseMapItem(value!!)
            field = value
        } // Set data

    /** 初始化 */
    init {
        //addItem(SGraphyClockItem(SizeF(500f, 500f), null))
    } // Init()

    /** 是否显示墙体  */
    var isShowColumn: Boolean = true
        set(value) {
            field = value
            for (column in columnList) {
                column.isVisible = value
            }
        } // Set isShowColumn

    /** 是否显示墙体  */
    var isShowWall: Boolean = true
        set(value) {
            field = value
            for (wall in wallList) {
                wall.isVisible = value
            }
        } // Set isShowWall

    /** 是否显示虚拟墙  */
    var isShowVirtualWall: Boolean = true
        set(value) {
            field = value
            for (wall in virtualWallList) {
                wall.isVisible = value
            }
        } // Set isShowWall

    /** 是否显示空间  */
    var isShowSpace: Boolean = true
        set(value) {
            field = value
            for (space in spaceList) {
                space.isVisible = value
            }
        } // Set isShowSpace

    /** 是否显示门  */
    var isShowDoor: Boolean = true
        set(value) {
            field = value
            for (door in doorList) {
                door.isVisible = value
            }
        } // Set isShowDoor

    /** 是否显示窗户  */
    var isShowWindow: Boolean = true
        set(value) {
            field = value
            for (window in windowList) {
                window.isVisible = value
            }
        } // Set isShowWindow

    /** 墙 list   */
    val wallList = ArrayList<WallItem>()

    /** 虚拟墙 list   */
    val virtualWallList = ArrayList<VirtualWallItem>()

    /** 柱子 list   */
    var columnList = ArrayList<ColumnItem>()

    /** 空间 list   */
    var spaceList = ArrayList<SpaceItem>()

    /** 空间名称 list   */
    val spaceNameList = ArrayList<SpaceNameItem>()

    /** 门 list   */
    var doorList = ArrayList<DoorItem>()

    /** 空间 list   */
    var windowList = ArrayList<WindowItem>()

    /** 点 */
    val pointItemList = java.util.ArrayList<PointItem>()

    /** 二维码 */
    val qrcodeItemList = java.util.ArrayList<QrcodeItem>()

    /** 管道 */
    val pipeItemList = ArrayList<PipeLineItem>()

    /** 有任务的空间 list   */
    var tunableSpaceList = ArrayList<TunableSpaceItem>()

    /** 设备 list   */
    var equipList = ArrayList<EquipItem>()

    /**
     *  获取底图压缩文件
     *
     *  @param  url         请求数据文件路径
     *  @param  isGzip      是否为压缩格式
     */
    fun loadUrl(url: String, isGzip: Boolean = true) {
        Log.e("PLX", "url = $url")
        try {
            val json = if (isGzip) {
                SHttpUtil.getZipRequest(url)
            } else {
                SHttpUtil.getRequest(url)
            }
//            SJsonUtil.propertyNamingStrategy = PropertyNamingStrategy.PascalCase
            val d = SJsonUtil.fromJson<FloorData>(json)
            Log.e("PLX", "json = ${d?.toJson()}")
            data = SJsonUtil.fromJson(json, FloorData::class.java)
            Log.e("数据源", "json = ${d?.toJson()}")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    } // Function loadUrl()

    fun loadData(json: FloorData) {
        try {
//            SJsonUtil.propertyNamingStrategy = PropertyNamingStrategy.PascalCase
            Log.e("PLX", "json = ${json?.toJson()}")
            data = json
            Log.e("数据源", "json = ${json?.toJson()}")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    } // Function loadUrl()


    /**
     *  增添所有底图 item;
     *
     *  @param  data    itemList对象
     */
    private fun addBaseMapItem(data: FloorData) {
        if (data.entityList.size < 1) {
            return;
        }
        val elements = data.entityList[0].elements ?: return

        // 添加墙
        if (elements.walls != null) {
            for (wall in elements.walls!!) {
                addWall(wall);
            }
        }

        // 添加虚拟墙
        if (elements.virtualWalls != null) {
            for (wall in elements.virtualWalls!!) {
                addVirtualWall(wall);
            }
        }

        // 添加柱子
        if (elements.columns != null) {
            for (column in elements.columns!!) {
                addColumn(column);
            }
        }

        // 添加空间
        if (elements.spaces != null) {
            for (space in elements.spaces!!) {
                addSpace(space)
            }
        }

        // 添加空间名称
//        if (elements.spaces != null) {
//            for (space in elements.spaces!!) {
//                addSpaceName(space)
//            }
//        }

        // 添加门
        if (elements.doors != null) {
            for (door in elements.doors!!) {
                addDoor(door);
            }
        }

        // 添加窗户
        if (elements.windows != null) {
            for (window in elements.windows!!) {
                addWindow(window);
            }
        }

        //添加问题点
        for (item in pointItemList) {
            item.isVisible = isShowSpace
            item.zOrder = 100000f
            addItem(item)
        }

        //添加管道
        for (item in pipeItemList) {
            item.isVisible = isShowSpace
            item.zOrder = 100000f
            addItem(item)
        }

        // 添加空间
        for (tunableSpace in tunableSpaceList) {
            tunableSpace.isVisible = isShowSpace
            tunableSpace.zOrder = 99996f
            addItem(tunableSpace)

            val space = Space()
            space.outLine = tunableSpace.data.outLine
            space.name = tunableSpace.data.name
            val item = SpaceNameItem(space)
            item.zOrder = 99999f
            item.isVisible = isShowSpace
            spaceNameList.add(item)
            addItem(item)
        }
    } // Function addBaseMapItem()

    /**
     *  添加柱子到 scene 中
     *
     *  @param  column   柱子
     */
    open fun addColumn(column: Column) {
        val item = ColumnItem(column)
        item.isVisible = isShowColumn
        columnList.add(item)
        addItem(item)
    } // Function addColumn()

    /**
     *  添加墙到 scene 中
     *
     *  @param  wall   墙
     */
    open fun addWall(wall: Wall) {
        val item = WallItem(wall)
        item.isVisible = isShowWall
        item.zOrder = 100000f
        wallList.add(item)
        addItem(item)
    } // Function addWall()

    /**
     *  添加所有虚拟墙到 scene 中
     *
     *  @param  wall   墙
     */
    open fun addVirtualWall(wall: VirtualWall) {
        val item = VirtualWallItem(wall)
        item.isVisible = isShowVirtualWall
        item.zOrder = 100000f
        virtualWallList.add(item)
        addItem(item)
    } // Function addVirtualWall()

    /**
     *  添加空间到 scene 中
     *
     *  @param  space       空间
     */
    open fun addSpace(space: Space) {
        val item = SpaceItem(space)
        Log.e("打印数据", space.toJson())
        item.isVisible = isShowSpace
        spaceList.add(item)
        addItem(item)
    } // Function addSpace()

    /**
     *  添加空间名称 scene 中
     *
     *  @param  space       空间
     */
//    open fun addSpaceName(space: Space) {
//        if (space.outLine != null) {
//            val scitem = SpatialCenterItem(space.name!!)
//            scitem.moveTo(PointF(space.location!!.points!![0].x, -space.location!!.points!![0].y))
//            scitem.zOrder = 100f
//            scitem.isVisible = true
//            spaceNameList.add(scitem)
//            this.addItem(scitem)
//
//        }
//    } // Function addSpace()

    /**
     *  添加门到 scene 中
     *
     *  @param  door        门
     */
    open fun addDoor(door: Door) {
        val item = DoorItem(door)
        item.isVisible = isShowSpace
        item.zOrder = 100001f
        doorList.add(item)
        addItem(item)
    } // Function addWindow()


    /**
     *  添加窗户到 scene 中
     *
     *  @param  window     窗户
     */
    open fun addWindow(window: Window) {
        val item = WindowItem(window)
        item.isVisible = isShowSpace
        windowList.add(item)
        addItem(item)
    } // Function addWindow()

    /**
     * 截断输出日志
     * 解决Log打印不全的问题
     */
    fun println1(msg: String) {
        var msg = msg
        if (TextUtils.isEmpty(msg))
            return
        val segmentSize = 3 * 1024
        val length = msg.length.toLong()
        if (length <= segmentSize) {// 长度小于等于限制直接打印
            Log.e("PLX", msg)
        } else {
            while (msg.length > segmentSize) {// 循环分段打印日志
                val logContent = msg.substring(0, segmentSize)
                msg = msg.replace(logContent, "")
                Log.e("PLX", logContent)
            }
            Log.e("PLX", msg)// 打印剩余日志
        }
    }

    /**
     *  接收移动坐标
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMoveEvent(event: SGraphyViewMoveEvent) {
        Log.e("x", event.x.toString())
        Log.e("y", event.y.toString())
//        mapToScene = this.mapToScene( PointF(this.width/2f,this.height/2f))
//        if (cadViewMovePointF!=null){
//            cadViewMovePointF!!.viewMovePointF(mapToScene)
//        }
    }

    override fun onSingleTapUp(e: SMotionEvent): Boolean {
        //如果只是查看模式，可以选中空间，进行空间内业务操作
        if ("normal".equals(type)) {
            var hasChose = false
            for (space in tunableSpaceList) {
                val polygonContainsPoint = Lasso.isPolygonContainsPoint(
                        space.mPoints,
                        android.graphics.Point(e.x.toInt(), -e.y.toInt())
                )
                if (polygonContainsPoint) {
                    if (hasChose) {
                        if (space.calculateArea() < choseSpace!!.calculateArea()) {
                            space.outPaint.color = Color.rgb(0xbd, 0xe8, 0xfe)
                            space.paint.color = Opt.spaceChoseColor
                            mapType = "space"
                            choseSpace = space
                            hasChose = true
                        }
                    } else {
                        space.outPaint.color = Color.rgb(0xbd, 0xe8, 0xfe)
                        space.paint.color = Opt.spaceChoseColor
                        mapType = "space"
                        choseSpace = space
                        hasChose = true
                    }
                } else {
                    space.paint.color = Opt.spaceColor
                    space.outPaint.color = Color.rgb(0xff, 0xff, 0xff)
                }
            }
            if (!hasChose) {
                mapType = "nothing"
                choseSpace = null
            }
        }


        var outSide = false
        //计算控制点的边界
        //是否已经拥有该点
        //打点业务
        if ("dot".equals(type)) {
            for (space in spaceList) {
                val polygonContainsPoint = Lasso.isPolygonContainsPoint(
                        space.mPoints,
                        android.graphics.Point(e.x.toInt(), -e.y.toInt())
                )
                outSide = true
                space.paint.color = Opt.spaceChoseColor
                space.outPaint.color = Color.rgb(0xbd, 0xe8, 0xfe)
            }
//            val point = Point()
//            point.mX = e.x
//            point.mY = e.y
//            var item = PointItem(point, null, defaultPointScale)
//            item!!.isVisible = true
//            item!!.zOrder = 100000f
//            pointItemList.add(item!!)

            //添加问题点业务
            for (item in pointItemList) {
                item.isVisible = isShowSpace
                item.zOrder = 100000f
                addItem(item)
            }
            if (!outSide) {
                return true
            }
        }

        //绘制管道业务
        else if ("pipe".equals(type)) {
            var pipe = PipeLine()
            var pointf = PointF()
            pointf.x = e.x
            pointf.y = -e.y
            pipeLineList.add(pointf)
            pipe.points!!.add(pipeLineList)
            var item = PipeLineItem(pipe, null)
            item!!.isVisible = true
            item!!.zOrder = 100000f
            drawingPipeItemList.add(item)
            for (item in drawingPipeItemList) {
                item.isVisible = isShowSpace
                item.zOrder = 100000f
                addItem(item)
            }

            //绘制二维码
        } else if ("qrcode".equals(type)) {
            point.mX = e.x
            point.mY = e.y

            if (item != null) {
                removeItem(item!!)
            }
            item = QrcodeItem(point, null, defaultPointScale)
            item!!.isVisible = true
            item!!.zOrder = 100000f
            addItem(item!!)

            //绘制设备
        } else if ("equip".equals(type)) {
            point.mX = e.x
            point.mY = e.y

            if (eqItem != null) {
                removeItem(eqItem!!)
            }
            eqItem = EquipItem(point, null, defaultPointScale)
            eqItem!!.isVisible = true
            eqItem!!.zOrder = 100000f
            addItem(eqItem!!)
        }

        if (topUp != null) {
            topUp.onSingUp(e.x, e.y)
        }
        return super.onSingleTapUp(e)
    }

    interface OnSingleTopUp {
        fun onSingUp(x: Float, y: Float)
    }

    fun setOnSingleTopUp(topUp: OnSingleTopUp) {
        this.topUp = topUp
    }

} // Class FloorScene