package com.cr.pages

import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.cr.common.CrUnitManager
import com.cr.common.DataManager
import com.cr.common.FileManager
import com.cr.cruav.CrApplication
import com.cr.cruav.R
import com.cr.data.CrUtil
import com.cr.dialog.DialogNormal
import com.cr.map.*
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment
import com.esri.arcgisruntime.arcgisservices.LabelDefinition
import com.esri.arcgisruntime.data.Feature
import com.esri.arcgisruntime.data.FeatureTable
import com.esri.arcgisruntime.data.Geodatabase
import com.esri.arcgisruntime.data.QueryParameters
import com.esri.arcgisruntime.data.ServiceFeatureTable
import com.esri.arcgisruntime.geometry.Geometry
import com.esri.arcgisruntime.geometry.Point
import com.esri.arcgisruntime.geometry.PointBuilder
import com.esri.arcgisruntime.geometry.PolylineBuilder
import com.esri.arcgisruntime.layers.ArcGISMapImageLayer
import com.esri.arcgisruntime.layers.ArcGISTiledLayer
import com.esri.arcgisruntime.layers.FeatureLayer
import com.esri.arcgisruntime.mapping.ArcGISMap
import com.esri.arcgisruntime.mapping.GeoElement
import com.esri.arcgisruntime.mapping.view.*
import com.esri.arcgisruntime.symbology.*
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.JsonPrimitive
import com.squareup.otto.Subscribe
import java.util.concurrent.ExecutionException

/**
 * 操作系统：MAC系统
 * 创建者：王成
 * 创建日期：2023/3/14 09:51
 * 描述：地图界面
 */
class FragmentMap : CrAnimationFragment() {
    // define: 2023/3/14 地图容器
    private var mapView: MapView? = null

    // define: 2023/3/14 地图
    private var mMap: ArcGISMap? = null

    // todo: 2023/4/13 常量定义
    val ONLINE_LAYER_NAME = "底图"
    val ONLINE_LABEL_LAYER_NAME = "标签"

    // todo: 2023/4/13 图层名称定义
    val LAYER_NAME_ICO = "永久标志"
    val LAYER_NAME_DOODLE = "永久涂鸦"
    val LAYER_NAME_MEDIA = "案件点"
    val LAYER_NAME_CASE = "绘制案件图斑"
    val LAYER_NAME_YX = "影像图"
    val LAYER_NAME_GH = "规划图"
    val LAYER_NAME_XZ = "现状图"
    val LAYER_NAME_NET_CASE = "在线案件图斑"
    val LAYER_NAME_TEMP_ICO = "临时标志"
    val LAYER_NAME_TEMP_DOODLE = "临时涂鸦"
    val LAYER_NAME_CONFIG_VILLAGE = "行政区(村界)"
    val LAYER_NAME_CONFIG_TOWNS = "行政区(镇界)"

    val LAYER_NAME_AIR_LINE = "飞行航线"
    val LAYER_NAME_AIR_HISTORY_LINE = "历史航线"
    val LAYER_NAME_AIR_LOCATION = "飞行器"
    val LAYER_NAME_AIR_HOME = "返航点"

    // todo: 2023/4/14 符号相关常量
    val SYMBOL_WIDTH = 25.0f;  //  define: 2023/4/13 图片符号的宽度
    val SYMBOL_HEIGHT = 25.0f;  //  define: 2023/4/13 图片符号的高度
    val R_LABEL_WJ_NO = "wj_no";  //  define: 2023/4/13 未上传违建标识
    val R_LABEL_WJ_YES = "wj_yes"; //  define: 2023/4/13 已上传违建标识
    val R_LABEL_REPEAT_NO = "repeat_no";  //  define: 2023/4/13 为上传复飞点标识
    val R_LABEL_REPEAT_YES = "repeat_yes"; //  define: 2023/4/13 已上传复飞点标识

    // todo: 2023/4/14 媒体点相关常量
    val MEDIA_TYPE_WJ_NO = "0";    //  define: 2023/4/13 未上传的违建点
    val MEDIA_TYPE_WJ_YES = "1";  //  define: 2023/4/13 已上传的违建点
    val MEDIA_TYPE_REPEAT_NO = "4";   //  define: 2023/4/13 未上传的复飞案件
    val MEDIA_TYPE_REPEAT_YES = "5";   //  define: 2023/4/13 已上传的复飞案件

    // todo: 2023/4/14 字段相关常量
    val FIELD_NET_CASE_POLYGON_AJH = "AJH";   //  define: 2023/4/13 网络案件的案件编号
    val FIELD_CASE_POLYGON_ANJID = "ANJID";   //  define: 2023/4/13 案件ID
    val FIELD_CASE_POLYGON_MJ = "MJ";   //  define: 2023/4/13 面积
    val FIELD_CASE_POLYGON_BZ = "BZ";   //  define: 2023/4/13 违建面的类型 0--代表未匹配 1--代表已匹配
    val FIELD_CASE_POLYGON_BZ_VALUE_NO = "0";   //  define: 2023/4/13 未匹配
    val FIELD_CASE_POLYGON_BZ_VALUE_YES = "1";   //  define: 2023/4/13 已匹配
    val FIELD_CASE_NAME = "NAME";   //  define: 2023/4/13 名称字段
    val FIELD_CASE_IMAGES = "IMAGES";   //  define: 2023/4/13 图片集合字段
    val FIELD_CASE_RQ = "RQ";   //  define: 2023/4/13 日期字段
    val FIELD_CASE_LAT = "LAT";   //  define: 2023/4/13 纬度字段
    val FIELD_CASE_LNG = "LNG";   //  define: 2023/4/13 经度字段
    val FIELD_CASE_ISUP = "ISUP";   //  define: 2023/4/13 是否上传
    val FIELD_CASE_ALT = "ALT";   //  define: 2023/4/13 高度字段
    val FIELD_CASE_ANG = "ANG";   //  define: 2023/4/13 角度字段
    val FIELD_CASE_TYPE = "TYPE";   //  define: 2023/4/13 类型字段
    val FIELD_CASE_ISDOWN = "ISDOWN";   //  define: 2023/4/13 是否下载


    // todo: 2023/4/13 标志相关
    private var markChange: EventMarkChange? = null

    // todo: 2023/4/13 动作相关
    private var mapAction: MapAction? = null

    // todo: 2023/4/14 绘制图层
    private var gLayerIco: GraphicsOverlay? = null // define: 2023/4/13 标志图层
    private var gLayerDoodle: GraphicsOverlay? = null // define: 2023/4/13 涂鸦图层
    private var gLayerAirplaneLocation: GraphicsOverlay? = null // define: 2023/4/13 飞行器位置图层
    private var gLayerAirplaneHomeLocation: GraphicsOverlay? = null // define: 2023/4/13 飞行器返航点位置图层
    private var gLayerAirplaneLine: GraphicsOverlay? = null // define: 2023/4/13 飞行航线图层
    private var gLayerHistoryAirplaneLine: GraphicsOverlay? = null // define: 2023/4/13 历史航线图层

    // todo: 2023/4/13 样式相关
    private var symbolAirplaneLine: SimpleLineSymbol? = null // define: 2023/4/13 飞行航线样式
    private var symbolAirplaneLink: SimpleLineSymbol? = null // define: 2023/4/13 飞行器与返航点连接线样式
    private var symbolAirplaneLocation: PictureMarkerSymbol? = null // define: 2023/4/13 飞行器符号样式

    // todo: 2023/4/13 要素相关
    private var builderAirplaneLine: PolylineBuilder? = null // define: 2023/4/13 航线点集
    private var builderAirplaneLink: PolylineBuilder? = null // define: 2023/4/13 飞行器与返航点连接线点集
    private var builderAirplaneLocation: PointBuilder? = null // define: 2023/4/13 飞行器位置点
    private var builderAirplaneHomeLocation: PointBuilder? = null // define: 2023/4/13 返航点位置
    private var graAirplaneLine: Graphic? = null // define: 2023/4/13 航线图形
    private var graAirplaneLink: Graphic? = null // define: 2023/4/13 飞行器与返航点连接线图形
    private var graAirplaneLocation: Graphic? = null // define: 2023/4/13 飞行器位置图形
    private var graAirplaneHomeLocation: Graphic? = null // define: 2023/4/13 返航点位置图形

    // todo: 2023/4/17 草图编辑
    private var sketchEditor: SketchEditor? = null // define: 2023/4/13 草图编辑器
    private var feaSelectCase: Feature? = null // define: 2023/4/13 选中的案件点

    // todo: 2023/4/14 编辑图层
    private var fTableICO: FeatureTable? = null // define: 2023/4/14 永久标志表
    private var fLayerICO: FeatureLayer? = null // define: 2023/4/14 永久标志图层
    private var fTableMedia: FeatureTable? = null // define: 2023/4/14 媒体表
    private var fLayerMedia: FeatureLayer? = null // define: 2023/4/14 媒体图层
    private var fTableDoodle: FeatureTable? = null // define: 2023/4/14 永久涂鸦表
    private var fLayerDoodle: FeatureLayer? = null // define: 2023/4/14 永久涂鸦图层
    private var fTableCasePolygon: FeatureTable? = null // define: 2023/4/14 永久案件表
    private var fLayerCasePolygon: FeatureLayer? = null // define: 2023/4/14 永久案件图层
    private var fTableNetCasePolygon: ServiceFeatureTable? = null // define: 2023/4/14 网路案件表
    private var fLayerNetCasePolygon: ArcGISMapImageLayer? = null // define: 2023/4/14 网络案件图层

    // todo: 2023/4/18 地图Touch事件
    private var mapTouch: MapTouch? = null


    /**
     * 重写创建View方法
     * @param inflater LayoutInflater
     * @param container ViewGroup?
     * @param savedInstanceState Bundle?
     * @return View?
     */
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mainView = inflater.inflate(R.layout.frag_map, container, false)
        // todo: 2023/4/17 注册订阅
        CrApplication.getEventBus().register(this)
        return mainView
    }

    /**
     * 重写创建视图
     * @param view View
     * @param savedInstanceState Bundle?
     */
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initUI()
    }

    /**
     * 初始化UI
     */
    private fun initUI() {
        //ArcGISRuntimeEnvironment.setLicense("runtimelite,1000,rud4449636536,none,NKMFA0PL4S0DRJE15166");
        // todo: 2023/3/14 初始化控件
        mapView = mainView?.findViewById(R.id.map_mapView)
        mapView?.let { itView ->
            // todo: 2023/4/13 设置底部标识是否显示
            itView.isAttributionTextVisible = false
            mMap = ArcGISMap()
            itView.map = mMap
            // todo: 2023/4/13 地图控件初始化
            itView.backgroundGrid.color = Color.argb(255, 216, 216, 216)
            itView.backgroundGrid.gridLineColor = Color.argb(0, 255, 255, 255)
            // todo: 2023/4/17 设置草图编辑
            sketchEditor = SketchEditor()
            sketchEditor?.sketchEditConfiguration?.let {
                it.isAllowPartSelection = false
            }
            itView.sketchEditor = sketchEditor
            // todo: 2023/4/18 Touch事件初始化
            mapTouch = MapTouch(context!!, itView)
            mapTouch?.setListener(touchListener)
            itView.onTouchListener = mapTouch
        }
        // todo: 2023/4/13 地图初始化
        mapInit()
    }

    /**
     * Touch监听
     */
    private var touchListener = object : MapTouch.TouchListener {
        // todo: 2023/4/18 涂鸦选择回调
        override fun onDoodleSelect(feature: Feature?) {
            if (feature != null) {
                // todo: 2023/4/18 高亮显示
                focusFeature(fLayerDoodle!!, feature)
            } else {
                unfocusFeature(fLayerDoodle!!)
            }
        }
    }

    /**
     * 地图初始化
     */
    private fun mapInit() {
        // todo: 2023/4/13 加载在线底图
        addOnlineRasterLayer()
        // todo: 2023/4/13 添加切片图层
        addTiledToMap()
        // todo: 2023/4/13 添加基础矢量地图
        addBaseGeoDatabaseToMap()
        // todo: 2023/4/14 添加可编辑矢量数据
        addEditGeoDatabaseToMap()

        // todo: 2023/4/13 定位地图中心点
        setMapCenter(118.709, 35.219, 5000.0);
    }

    /**
     * 添加在线地图
     */
    private fun addOnlineRasterLayer() {
        var url: String =
            "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer";
        var layer = ArcGISTiledLayer(url)
        layer.name = ONLINE_LAYER_NAME
        mMap?.operationalLayers?.add(layer)
    }

    /**
     * 添加切片图层
     */
    private fun addTiledToMap() {
        var tileLayers = DataManager.getTileLayerConfig()
        for (model in tileLayers) {
            var layer = ArcGISTiledLayer(model.url)
            layer.name = model.name
            layer.isVisible = model.isVisible
            mMap?.operationalLayers?.add(layer)
            // todo: 2023/4/13 添加到配置
            LayerManager.getInstance().addLayer(
                LayerModel(
                    model.name!!,
                    model.isVisible,
                    LayerType.LAYER_TYPE_TILED,
                    layer
                ), LayerManager.LayerGroup.LAYER_NAME_DAILY
            )
        }
    }

    /**
     * 添加基础矢量地图集合
     */
    private fun addBaseGeoDatabaseToMap() {
        if (!FileManager.isExists(CrUtil.MAP_PATH_BASE)) return
        var geoDatabase = Geodatabase(CrUtil.MAP_PATH_BASE)
        // todo: 2023/4/13 加载完成监听
        geoDatabase.addDoneLoadingListener(Runnable {
            var vLayers = DataManager.getVectorLayerConfig()
            var tables = geoDatabase.geodatabaseFeatureTables
            for (vLayer in vLayers) {
                var table = tables[vLayer.lyrIdx]
                var layer = FeatureLayer(table)
                layer.name = vLayer.lyrName
                layer.isVisible = vLayer.isVisible
                mMap?.operationalLayers?.add(layer)
                // todo: 2023/4/13 添加到配置信息
                LayerManager.getInstance().addLayer(
                    LayerModel(
                        vLayer.lyrName,
                        vLayer.isVisible,
                        LayerType.LAYER_TYPE_FEATURE,
                        layer
                    ), LayerManager.LayerGroup.LAYER_NAME_BASE
                )
            }
        })
        // todo: 2023/4/13 加载数据集
        geoDatabase.loadAsync()
    }

    /**
     * 加载可编辑数据
     */
    private fun addEditGeoDatabaseToMap() {
        if (!FileManager.isExists(CrUtil.MAP_PATH_EDIT)) return
        var geoDatabase = Geodatabase(CrUtil.MAP_PATH_EDIT)
        // todo: 2023/4/14 数据加载完监听
        geoDatabase.addDoneLoadingListener(Runnable {
            // todo: 2023/4/14 初始化标志图层
            fTableICO = geoDatabase.getGeodatabaseFeatureTable("ico84")
            fLayerICO = FeatureLayer(fTableICO)
            fLayerICO!!.name = LAYER_NAME_ICO
            fLayerICO!!.isVisible = true
            mMap!!.operationalLayers.add(fLayerICO)
            LayerManager.getInstance().addLayer(
                LayerModel(
                    fLayerICO!!.name,
                    fLayerICO!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerICO!!
                ), LayerManager.LayerGroup.LAYER_NAME_DAILY
            )
            // todo: 2023/4/14  初始化涂鸦图层
            fTableDoodle = geoDatabase.getGeodatabaseFeatureTable("ty84")
            fLayerDoodle = FeatureLayer(fTableDoodle)
            fLayerDoodle!!.name = LAYER_NAME_DOODLE
            fLayerDoodle!!.isVisible = true
            mMap!!.operationalLayers.add(fLayerDoodle)
            LayerManager.getInstance().addLayer(
                LayerModel(
                    fLayerDoodle!!.name,
                    fLayerDoodle!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerDoodle!!
                ), LayerManager.LayerGroup.LAYER_NAME_DAILY
            )
            // todo: 2023/4/14  初始化媒体点图层
            fTableMedia = geoDatabase.getGeodatabaseFeatureTable("media84")
            fLayerMedia = FeatureLayer(fTableMedia)
            fLayerMedia!!.name = LAYER_NAME_MEDIA
            fLayerMedia!!.isVisible = true
            mMap!!.operationalLayers.add(fLayerMedia)
            LayerManager.getInstance().addLayer(
                LayerModel(
                    fLayerMedia!!.name,
                    fLayerMedia!!.isVisible, LayerType.LAYER_TYPE_FEATURE_EDIT, fLayerMedia!!
                ), LayerManager.LayerGroup.LAYER_NAME_DAILY
            )
            // todo: 2023/4/14  初始化违建面图层
            fTableCasePolygon = geoDatabase.getGeodatabaseFeatureTable("sbwj84")
            fLayerCasePolygon = FeatureLayer(fTableCasePolygon)
            fLayerCasePolygon!!.name = LAYER_NAME_CASE
            fLayerCasePolygon!!.isVisible = true
            // todo: 2023/4/14 给图层添加标注
            val labelDefinition: LabelDefinition =
                createLabelDefinition(Color.BLUE, 12.0f, "round(\$feature.MJ,2) + '亩';")
            fLayerCasePolygon!!.labelDefinitions.add(labelDefinition)
            fLayerCasePolygon!!.isLabelsEnabled = true
            mMap!!.operationalLayers.add(fLayerCasePolygon)
            LayerManager.getInstance().addLayer(
                LayerModel(
                    fLayerCasePolygon!!.name,
                    fLayerCasePolygon!!.isVisible,
                    LayerType.LAYER_TYPE_FEATURE_EDIT,
                    fLayerCasePolygon!!
                ), LayerManager.LayerGroup.LAYER_NAME_DAILY
            )
            // todo: 2023/4/14 可编辑数据符号化
            editLayerRenderer()
        })
        // todo: 2023/4/14 异步加载
        geoDatabase.loadAsync()
    }

    /**
     * 编辑图层符号话
     */
    private fun editLayerRenderer() {
        // todo: 2023/4/14  永久涂鸦图层符号化
        val doodleSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 2.5f)
        val doodleRenderer = SimpleRenderer(doodleSymbol)
        fLayerDoodle?.renderer = doodleRenderer
        // todo: 2023/4/14  永久标志图层符号化
        val icoSymbol: PictureMarkerSymbol =
            createPictureMarkerSymbol(R.drawable.ico_ty1, 30f, 30f)
        val icoRenderer = SimpleRenderer(icoSymbol)
        fLayerICO?.renderer = icoRenderer
        // todo: 2023/4/14  违建符号化
        val mediaRenderer = UniqueValueRenderer()
        val mediaSymbolYes: PictureMarkerSymbol = createPictureMarkerSymbol(
            R.drawable.ico_wj_upload_yes,
            SYMBOL_WIDTH,
            SYMBOL_HEIGHT
        )
        val mediaSymbolNo: PictureMarkerSymbol = createPictureMarkerSymbol(
            R.drawable.ico_wj_no,
            SYMBOL_WIDTH,
            SYMBOL_HEIGHT
        )
        val mediaSymbolRepeatYes: PictureMarkerSymbol = createPictureMarkerSymbol(
            R.drawable.ico_repeatflight_yes,
            SYMBOL_WIDTH,
            SYMBOL_HEIGHT
        )
        val mediaSymbolRepeatNo: PictureMarkerSymbol = createPictureMarkerSymbol(
            R.drawable.ico_repeatflight_no,
            SYMBOL_WIDTH,
            SYMBOL_HEIGHT
        )
        mediaRenderer.defaultSymbol = mediaSymbolNo
        mediaRenderer.defaultLabel = R_LABEL_WJ_NO
        mediaRenderer.fieldNames.add(FIELD_CASE_ISUP)
        val cValueNo: MutableList<Any> = ArrayList()
        cValueNo.add(MEDIA_TYPE_WJ_NO)
        mediaRenderer.uniqueValues.add(
            UniqueValueRenderer.UniqueValue(
                R_LABEL_WJ_NO,
                R_LABEL_WJ_NO,
                mediaSymbolNo,
                cValueNo
            )
        )
        val cValueYes: MutableList<Any> = ArrayList()
        cValueYes.add(MEDIA_TYPE_WJ_YES)
        mediaRenderer.uniqueValues.add(
            UniqueValueRenderer.UniqueValue(
                R_LABEL_WJ_YES,
                R_LABEL_WJ_YES,
                mediaSymbolYes,
                cValueYes
            )
        )
        val cValueRepeatNo: MutableList<Any> = ArrayList()
        cValueRepeatNo.add(MEDIA_TYPE_REPEAT_NO)
        mediaRenderer.uniqueValues.add(
            UniqueValueRenderer.UniqueValue(
                R_LABEL_REPEAT_NO,
                R_LABEL_REPEAT_NO,
                mediaSymbolRepeatNo,
                cValueRepeatNo
            )
        )
        val cValueRepeatYes: List<Any> = ArrayList()
        cValueNo.add(MEDIA_TYPE_REPEAT_YES)
        mediaRenderer.uniqueValues.add(
            UniqueValueRenderer.UniqueValue(
                R_LABEL_REPEAT_YES,
                R_LABEL_REPEAT_YES,
                mediaSymbolRepeatYes,
                cValueRepeatYes
            )
        )
        fLayerMedia?.renderer = mediaRenderer
        // todo: 2023/4/14  绘制违建面符号化
        val colorClear = Color.argb(0, 255, 255, 255)
        val caseNoLineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.DASH_DOT, Color.BLUE, 2.5f)
        val caseYesLineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.DASH_DOT, Color.RED, 2.5f)
        val caseNoFillSymbol =
            SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, colorClear, caseNoLineSymbol)
        val caseYesFillSymbol =
            SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, colorClear, caseYesLineSymbol)
        val casePolygonRenderer = UniqueValueRenderer()
        casePolygonRenderer.fieldNames.add(FIELD_CASE_POLYGON_BZ)
        casePolygonRenderer.defaultSymbol = caseNoFillSymbol
        casePolygonRenderer.defaultLabel = FIELD_CASE_POLYGON_BZ_VALUE_NO
        val cValueCaseNo: MutableList<Any> = ArrayList()
        cValueCaseNo.add(FIELD_CASE_POLYGON_BZ_VALUE_NO)
        casePolygonRenderer.uniqueValues.add(
            UniqueValueRenderer.UniqueValue(
                FIELD_CASE_POLYGON_BZ_VALUE_NO,
                FIELD_CASE_POLYGON_BZ_VALUE_NO,
                caseNoFillSymbol,
                cValueCaseNo
            )
        )
        val cValueCaseYes: MutableList<Any> = ArrayList()
        cValueCaseYes.add(FIELD_CASE_POLYGON_BZ_VALUE_YES)
        casePolygonRenderer.uniqueValues.add(
            UniqueValueRenderer.UniqueValue(
                FIELD_CASE_POLYGON_BZ_VALUE_YES,
                FIELD_CASE_POLYGON_BZ_VALUE_YES,
                caseYesFillSymbol,
                cValueCaseYes
            )
        )
        fLayerCasePolygon?.renderer = casePolygonRenderer
    }

    /**
     * 创建图片符号
     * @param drawable Int 图片资源Id
     * @param width Float 宽度
     * @param height Float 高度
     * @return PictureMarkerSymbol?
     */
    private fun createPictureMarkerSymbol(
        drawable: Int,
        width: Float,
        height: Float
    ): PictureMarkerSymbol {
        val tDrawable = context!!.resources.getDrawable(drawable) as BitmapDrawable
        val symbol = PictureMarkerSymbol(tDrawable)
        if (width > 0) symbol.width = width else symbol.width =
            CrUnitManager.px2dp(tDrawable.bitmap.width).toFloat()
        if (height > 0) symbol.height = height else symbol.height =
            CrUnitManager.px2dp(tDrawable.bitmap.height).toFloat()
        return symbol
    }

    /**
     * 创建标注
     * @param txtColor Int 文字颜色
     * @param txtSize Float 文字大小
     * @param expression String 表达式
     * @return LabelDefinition? 标注
     */
    private fun createLabelDefinition(
        txtColor: Int,
        txtSize: Float,
        expression: String
    ): LabelDefinition {
        val textSymbol = TextSymbol()
        textSymbol.color = txtColor
        textSymbol.fontWeight = TextSymbol.FontWeight.BOLD
        textSymbol.haloColor = Color.WHITE
        textSymbol.haloWidth = 2.0f
        textSymbol.fontFamily = "Arial"
        textSymbol.size = txtSize
        val label = JsonObject()
        val labelExpression = JsonObject()
        labelExpression.add("expression", JsonPrimitive(expression))
        label.add("labelExpressionInfo", labelExpression)
        label.add("labelPlacement", JsonPrimitive("esriServerPolygonPlacementAlwaysHorizontal"))
        label.add("symbol", JsonParser().parse(textSymbol.toJson()))
        return LabelDefinition.fromJson(label.toString())
    }

    /**
     * 定位地图中心
     * @param longitude Double 中心经度
     * @param latitude Double 中心纬度
     * @param scale Double 缩放比例
     */
    private fun setMapCenter(longitude: Double, latitude: Double, scale: Double) {
        // todo: 2023/4/13 创建中心点
        var centerPoint: Point =
            Point(longitude, latitude, MapTouch.wgs84SpatialReference)
        if (scale > 0) {
            mapView?.setViewpointCenterAsync(centerPoint, scale)
        } else {
            mapView?.setViewpointCenterAsync(centerPoint)
        }
    }

    /**
     * 高亮显示要素
     * @param layer FeatureLayer 要素所在图层
     * @param feature Feature 要素
     */
    private fun focusFeature(layer: FeatureLayer, feature: Feature) {
        layer.selectFeature(feature)
    }

    /**
     * 清除高亮显示
     * @param layer FeatureLayer 图层
     */
    private fun unfocusFeature(layer: FeatureLayer) {
        layer.clearSelection()
    }

    /**
     * 清除全部选择
     */
    private fun unfocusAllFeature(){
        for(layer in mMap!!.operationalLayers){
            if(layer is FeatureLayer){
                layer.clearSelection()
            }
        }

        for(overLayer in mapView!!.graphicsOverlays){
            overLayer.clearSelection()
        }
    }

    /**
     * 开始绘制涂鸦
     */
    private fun doodleStartDraw() {
        sketchEditor?.start(SketchCreationMode.FREEHAND_LINE)
    }

    /**
     * 清除草图
     */
    private fun clearSketch() {
        sketchEditor?.clearGeometry()
    }

    /**
     * 保存绘制的涂鸦
     */
    private fun doodleSave() {
        var geometry: Geometry? = sketchEditor?.geometry
        geometry?.let {
            var feature: Feature = fTableDoodle!!.createFeature()
            feature.geometry = it
            var addAsync = fTableDoodle!!.addFeatureAsync(feature)
            addAsync.addDoneListener(Runnable {
                try {
                    addAsync.get()
                    if (addAsync.isDone) {
                        DialogNormal(context!!, "提示", "涂鸦保存成功！").show()
                        sketchEditor?.stop()
                        CrApplication.getEventBus()
                            .post(FragmentDoodle.EventAction(FragmentDoodle.EventAction.CLOSE_DRAW))
                    }
                } catch (e: InterruptedException) {
                    DialogNormal(context!!, "警告", e.message!!).show()
                } catch (e: ExecutionException) {
                    DialogNormal(context!!, "警告", e.message!!).show()
                }
            })
        }
    }

    /**
     * 删除全部涂鸦
     */
    private fun doodleRemove() {
        var dialog = DialogNormal(context!!, "警告", "删除后无法恢复，是否删除？")
        dialog.setButtonsText("是", "否")
        dialog.setListener(object : DialogNormal.DialogNormalListener {
            // todo: 2023/4/17 删除
            override fun completion() {
                var params = QueryParameters()
                params.whereClause = "1=1"
                var queryAsync = fTableDoodle?.queryFeaturesAsync(params)
                queryAsync?.addDoneListener(Runnable {
                    try {
                        if (queryAsync.isDone) {
                            var deleteAsync = fTableDoodle?.deleteFeaturesAsync(queryAsync.get())
                            deleteAsync?.addDoneListener(Runnable {
                                try {
                                    if (deleteAsync.isDone) {
                                        DialogNormal(context!!, "提示", "删除成功！").show()
                                    }
                                } catch (e: java.lang.IllegalArgumentException) {
                                    DialogNormal(context!!, "错误", "删除错误！").show()
                                }
                            })
                        }

                    } catch (e: java.lang.IllegalArgumentException) {
                        DialogNormal(context!!, "错误", "查询错误！").show()
                    }
                })
            }

            // todo: 2023/4/17 否
            override fun close() {

            }

        })
        dialog.show()
    }

    /**
     * 删除选择涂鸦
     */
    private fun doodleDelete() {
        var dialog = DialogNormal(context!!, "警告", "删除后无法恢复，是否删除？")
        dialog.setButtonsText("是", "否")
        dialog.setListener(object : DialogNormal.DialogNormalListener {
            override fun completion() {
                var sAsync = fLayerDoodle!!.selectedFeaturesAsync
                sAsync.addDoneListener(Runnable {
                    if (sAsync.isDone){
                        var result = sAsync.get()
                        var dAsync = fTableDoodle!!.deleteFeaturesAsync(result)
                        dAsync.addDoneListener(Runnable{
                            try {
                                if(dAsync.isDone){
                                    DialogNormal(context!!, "提示", "删除成功！").show()
                                }
                            }catch (e:java.lang.IllegalArgumentException){
                                DialogNormal(context!!, "错误", "删除错误！").show()
                            }
                        })
                    }
                })
            }

            override fun close() {
            }
        })
        dialog.show()
    }

    /**
     * 订阅地图事件执行动作
     * @param event EventMap 事件
     */
    @Subscribe
    fun onAction(event: EventMap) {
        when (event.action) {
            // todo: 2023/4/17 绘制涂鸦
            MapAction.MapTapDrawDoodle -> {
                CrUtil.showMessage("地图接收绘制命令")
                doodleStartDraw()
            }
            // todo: 2023/4/17 清除涂鸦
            MapAction.EventDoodleClear -> {
                clearSketch()
            }
            // todo: 2023/4/17 保存涂鸦
            MapAction.EventDoodleSave -> {
                doodleSave()
            }
            // todo: 2023/4/17 停止草图编辑
            MapAction.EventStopSketch -> {
                sketchEditor?.stop()
            }
            // todo: 2023/4/17 全部删除保存的涂鸦
            MapAction.EventDoodleRemove -> {
                doodleRemove()
            }
            // todo: 2023/4/18 删除选择涂鸦
            MapAction.EventDoodleDelete -> {
                doodleDelete()
            }
            // todo: 2023/4/18 选择涂鸦
            MapAction.MapTapSelectDoodle -> {
                CrUtil.showMessage("地图上点击需要选择的涂鸦")
                mapTouch?.setQueryLayer(fLayerDoodle!!, MapAction.MapTapSelectDoodle)
            }
            // todo: 2023/4/18 停止Touch
            MapAction.EventStopTouch->{
                mapTouch?.setQueryLayer(null,null)
                unfocusAllFeature()
            }
        }
    }

    // todo: 2023/4/17 生命周期
    override fun onDestroy() {
        // todo: 2023/4/17 移除订阅监听
        CrApplication.getEventBus().unregister(this)
        super.onDestroy()
    }


}