package com.waytous.anticollision.utils

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.blankj.utilcode.util.LogUtils
import com.mapbox.maps.LayerPosition
import com.mapbox.maps.MapboxMap
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.expressions.dsl.generated.get
import com.mapbox.maps.extension.style.layers.addLayer
import com.mapbox.maps.extension.style.layers.addLayerBelow
import com.mapbox.maps.extension.style.layers.generated.circleLayer
import com.mapbox.maps.extension.style.layers.generated.fillLayer
import com.mapbox.maps.extension.style.layers.generated.lineLayer
import com.mapbox.maps.extension.style.layers.generated.symbolLayer
import com.mapbox.maps.extension.style.layers.properties.generated.LineCap
import com.mapbox.maps.extension.style.layers.properties.generated.LineJoin
import com.mapbox.maps.extension.style.layers.properties.generated.TextAnchor
import com.mapbox.maps.extension.style.layers.properties.generated.TextRotationAlignment
import com.mapbox.maps.extension.style.layers.properties.generated.Visibility
import com.mapbox.maps.extension.style.sources.addSource
import com.mapbox.maps.extension.style.sources.generated.geoJsonSource
import com.mapbox.maps.plugin.animation.flyTo
import com.waytous.anticollision.R
import com.waytous.anticollision.databinding.LayoutMapBoxBinding
import com.waytous.anticollision.ui.MainViewModel
import kotlinx.coroutines.launch
import java.math.BigDecimal


const val MY_MAP_BOX_STYLE = "asset://style.json"

const val DUMP_AREA_SOURCE = "dumpAreaSource"
const val DUMP_AREA_LAYER = "dumpAreaLayer"
const val DUMP_AREA_TEXT_LAYER = "dumpAreaTextLayer"

const val OBSTACLES_SOURCE = "obstaclesSource"
const val OBSTACLES_LAYER = "obstaclesLayer"
const val OBSTACLES_TEXT_LAYER = "obstaclesTextLayer"

const val ELECTRONIC_FENCE_SOURCE = "electronicFenceSource"
const val ELECTRONIC_FENCE_LAYER = "electronicFenceLayer"
const val ELECTRONIC_FENCE_TEXT_LAYER = "electronicFenceTextLayer"

const val WET_AREA_SOURCE = "wetAreaSource"
const val WET_AREA_LAYER = "wetAreaLayer"
const val WET_AREA_TEXT_LAYER = "wetAreaTextLayer"

const val LANE_NODE_SOURCE = "laneNodeSource"
const val LANE_NODE_LAYER = "laneNodeLayer"
const val LANE_NODE_TEXT_LAYER = "laneNodeTextLayer"

const val LANE_SOURCE = "laneSource"
const val LANE_LAYER = "laneLayer"
const val LANE_TEXT_LAYER = "laneTextLayer"

const val RUNNABLE_AREA_SOURCE = "runnableAreaSource"
const val RUNNABLE_AREA_LAYER = "runnableAreaLayer"
const val RUNNABLE_AREA_TEXT_LAYER = "runnableAreaTextLayer"

const val DIGGING_WORK_AREA_SOURCE = "diggingWorkAreaSource"
const val DIGGING_WORK_AREA_LAYER = "diggingWorkAreaLayer"
const val DIGGING_WORK_AREA_TEXT_LAYER = "diggingWorkAreaTextLayer"

const val BARRICADE_SOURCE = "barricadeSource"
const val BARRICADE_LAYER = "barricadeLayer"
const val BARRICADE_TEXT_LAYER = "barricadeTextLayer"

const val STATION_AREA_SOURCE = "stationAreaSource"
const val STATION_AREA_LAYER = "stationAreaLayer"
const val STATION_AREA_TEXT_LAYER = "stationAreaTextLayer"

const val STATIC_OBJECTS_SOURCE = "staticObjectsSource"
const val STATIC_OBJECTS_LAYER = "staticObjectsLayer"
const val STATIC_OBJECTS_TEXT_LAYER = "staticObjectsTextLayer"

const val PARK_SPOT_SOURCE = "parkSpotSource"
const val PARK_SPOT_LAYER = "parkSpotLayer"
const val PARK_SPOT_TEXT_LAYER = "parkSpotTextLayer"

const val TRUCK_PATH_SOURCE = "truckPathSource"
const val TRUCK_PATH_LAYER = "truckPathLayer"

const val ADJUST_LAYER_ORDER = "adjustLayerOrder"

const val LONGITUDE = 119.7622539014
const val LATITUDE = 49.3795031825
const val ZOOM = 16.0

/**
 * runablearea:可行驶区域
 * 地图图层由下往上依次：
 * runablearea->staticobjs->diggingarea->dumparea->
 * barricade->electronicFence->wetArea->lane->
 * obstacles->stationarea->parkspot->lanenode
 * */
fun Style.addRunnableAreaSource(source: String){
    LogUtils.d("addRunnableAreaSource")
    val geoJsonSource = geoJsonSource(RUNNABLE_AREA_SOURCE){
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addRunnableAreaLayer(){
    LogUtils.d("addRunnableAreaLayer")
    val fillLayer = fillLayer(
        RUNNABLE_AREA_LAYER,
        RUNNABLE_AREA_SOURCE
    ){
        fillColor("#98a0a0")
        fillOpacity(0.85)
        fillOutlineColor("#FFFF00")
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(STATIC_OBJECTS_LAYER)) {
        addLayerBelow(fillLayer, STATIC_OBJECTS_LAYER)
    } else {
        addLayer(fillLayer)
    }

}
/**
 * staticobjs:静态对象区域
 * */
fun Style.addStaticObjectsSource(source: String){
    LogUtils.d("addStaticObjectsSource")
    val geoJsonSource = geoJsonSource(STATIC_OBJECTS_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addStaticObjectsFillLayer(){
    LogUtils.d("addStaticObjectsFillLayer")
    val fillLayer = fillLayer(
        STATIC_OBJECTS_LAYER,
        STATIC_OBJECTS_SOURCE
    ){
        fillColor("#98a0a0")
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(DIGGING_WORK_AREA_LAYER)) {
        addLayerBelow(fillLayer, DIGGING_WORK_AREA_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addStaticObjectsSymbolLayer(){
    LogUtils.d("addStaticObjectsSymbolLayer")
    val symbolLayer = symbolLayer(STATIC_OBJECTS_TEXT_LAYER, STATIC_OBJECTS_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(DIGGING_WORK_AREA_LAYER)) {
        addLayerBelow(symbolLayer, DIGGING_WORK_AREA_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * diggingarea:挖掘区域
 * */
fun Style.addDiggingWorkAreaSource(source: String){
    LogUtils.d("addDiggingWorkAreaSource")
    val geoJsonSource = geoJsonSource(DIGGING_WORK_AREA_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addDiggingWorkAreaFillLayer(){
    LogUtils.d("addStaticObjectsFillLayer")
    val fillLayer = fillLayer(
        DIGGING_WORK_AREA_LAYER,
        DIGGING_WORK_AREA_SOURCE
    ){
        fillColor("#886e26")
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(DUMP_AREA_LAYER)) {
        addLayerBelow(fillLayer, DUMP_AREA_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addDiggingWorkAreaSymbolLayer(){
    LogUtils.d("addDiggingWorkAreaSymbolLayer")
    val symbolLayer = symbolLayer(DIGGING_WORK_AREA_TEXT_LAYER, DIGGING_WORK_AREA_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(DUMP_AREA_LAYER)) {
        addLayerBelow(symbolLayer, DUMP_AREA_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * dumparea:排土区域
 * */
fun Style.addDumpAreaSource(source: String){
    LogUtils.d("addDumpAreaSource")
    val geoJsonSource = geoJsonSource(DUMP_AREA_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addDumpAreaFillLayer(){
    LogUtils.d("addDumpAreaFillLayer")
    val fillLayer = fillLayer(
        DUMP_AREA_LAYER,
        DUMP_AREA_SOURCE
    ){
        fillColor("#886e26")
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(BARRICADE_LAYER)) {
        addLayerBelow(fillLayer, BARRICADE_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addDumpAreaSymbolLayer(){
    LogUtils.d("addDumpAreaSymbolLayer")
    val symbolLayer = symbolLayer(DUMP_AREA_TEXT_LAYER, DUMP_AREA_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(BARRICADE_LAYER)) {
        addLayerBelow(symbolLayer, BARRICADE_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * barricade:挡墙
 * */
fun Style.addBarricadeSource(source: String){
    LogUtils.d("addBarricadeSource")
    val geoJsonSource = geoJsonSource(BARRICADE_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addBarricadeLineLayer(){
    LogUtils.d("addBarricadeLineLayer")
    val lineLayer = lineLayer(
        BARRICADE_LAYER,
        BARRICADE_SOURCE
    ){
        lineColor("blue")
        lineWidth(4.0)
        lineJoin(LineJoin.ROUND)
        lineCap(LineCap.ROUND)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(ELECTRONIC_FENCE_LAYER)) {
        addLayerBelow(lineLayer, ELECTRONIC_FENCE_LAYER)
    } else {
        addLayer(lineLayer)
    }
}
/**
 * electronicFence:电子围栏
 * */
fun Style.addElectronicFenceSource(source: String){
    LogUtils.d("addElectronicFenceSource")
    val geoJsonSource = geoJsonSource(ELECTRONIC_FENCE_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addElectronicFenceFillLayer(){
    LogUtils.d("addElectronicFenceFillLayer")
    val fillLayer = fillLayer(
        ELECTRONIC_FENCE_LAYER,
        ELECTRONIC_FENCE_SOURCE
    ){
        fillColor(get("color"))
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(WET_AREA_LAYER)) {
        addLayerBelow(fillLayer, WET_AREA_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addElectronicFenceSymbolLayer(){
    LogUtils.d("addElectronicFenceSymbolLayer")
    val symbolLayer = symbolLayer(ELECTRONIC_FENCE_TEXT_LAYER, ELECTRONIC_FENCE_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(WET_AREA_LAYER)) {
        addLayerBelow(symbolLayer, WET_AREA_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * wetArea:湿滑区
 * */
fun Style.addWetAreaSource(source: String){
    LogUtils.d("addWetAreaSource")
    val geoJsonSource = geoJsonSource(WET_AREA_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addWetAreaFillLayer(){
    LogUtils.d("addWetAreaFillLayer")
    val fillLayer = fillLayer(
        WET_AREA_LAYER,
        WET_AREA_SOURCE
    ){
        fillColor(get("color"))
        fillOpacity(0.8)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(LANE_LAYER)) {
        addLayerBelow(fillLayer, LANE_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addWetAreaSymbolLayer(){
    LogUtils.d("addWetAreaSymbolLayer")
    val symbolLayer = symbolLayer(WET_AREA_TEXT_LAYER, WET_AREA_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(LANE_LAYER)) {
        addLayerBelow(symbolLayer, LANE_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * lanelayer:整个矿山边界路线
 * */
fun Style.addLaneSource(source: String){
    LogUtils.d("addLaneSource")
    val geoJsonSource = geoJsonSource(LANE_SOURCE){
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addLaneLayer(){
    LogUtils.d("addLaneLayer")
    val lineLayer = lineLayer(
        LANE_LAYER,
        LANE_SOURCE
    ){
        lineColor("white")
        lineWidth(3.0)
        lineJoin(LineJoin.ROUND)
        lineCap(LineCap.ROUND)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(OBSTACLES_LAYER)) {
        addLayerBelow(lineLayer, OBSTACLES_LAYER)
    } else {
        addLayer(lineLayer)
    }
}
/**
 * obstacles:障碍物
 * */
fun Style.addObstaclesSource(source: String){
    LogUtils.d("addObstaclesSource")
    val geoJsonSource = geoJsonSource(OBSTACLES_SOURCE) {
        url(source)
    }
    addSource(geoJsonSource)
}
fun Style.addObstaclesFillLayer(){
    LogUtils.d("addObstaclesFillLayer")
    val fillLayer = fillLayer(
        OBSTACLES_LAYER,
        OBSTACLES_SOURCE
    ){
        fillColor("#6f9bdd")
        fillOpacity(0.8)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(STATION_AREA_LAYER)) {
        addLayerBelow(fillLayer, STATION_AREA_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addObstaclesSymbolLayer(){
    LogUtils.d("addObstaclesSymbolLayer")
    val symbolLayer = symbolLayer(OBSTACLES_TEXT_LAYER, OBSTACLES_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(STATION_AREA_LAYER)) {
        addLayerBelow(symbolLayer, STATION_AREA_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * stationarea:静态物体
 * */
fun Style.addStationAreaSource(source: String){
    LogUtils.d("addStationAreaSource")
    val geoJsonSource = geoJsonSource(STATION_AREA_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addStationAreaFillLayer(){
    LogUtils.d("addStationAreaFillLayer")
    val fillLayer = fillLayer(
        STATION_AREA_LAYER,
        STATION_AREA_SOURCE
    ){
        fillColor("lightgreen")
        fillOpacity(0.8)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(PARK_SPOT_LAYER)) {
        addLayerBelow(fillLayer, PARK_SPOT_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addStationAreaSymbolLayer(){
    LogUtils.d("addStationAreaSymbolLayer")
    val symbolLayer = symbolLayer(STATION_AREA_TEXT_LAYER, STATION_AREA_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
    }
    if (styleLayerExists(PARK_SPOT_LAYER)) {
        addLayerBelow(symbolLayer, PARK_SPOT_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * parkspot:停车区
 * */
fun Style.addParkSpotSource(source: String){
    LogUtils.d("addParkSpotSource")
    val geoJsonSource = geoJsonSource(PARK_SPOT_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addParkSpotFillLayer(){
    LogUtils.d("addParkSpotFillLayer")
    val fillLayer = fillLayer(
        PARK_SPOT_LAYER,
        PARK_SPOT_SOURCE
    ){
        fillColor(get("#7e8185"))
        fillOpacity(0.8)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(LANE_NODE_LAYER)) {
        addLayerBelow(fillLayer, LANE_NODE_LAYER)
    } else {
        addLayer(fillLayer)
    }
}
fun Style.addParkSpotSymbolLayer(){
    LogUtils.d("addParkSpotSymbolLayer")
    val symbolLayer = symbolLayer(PARK_SPOT_TEXT_LAYER, PARK_SPOT_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(16.0)
        textMaxWidth(10.0)
        visibility(Visibility.VISIBLE)
    }
    if (styleLayerExists(LANE_NODE_LAYER)) {
        addLayerBelow(symbolLayer, LANE_NODE_LAYER)
    } else {
        addLayer(symbolLayer)
    }
}
/**
 * lanenode:道路节点
 * */
fun Style.addLaneNodeSource(source: String){
    LogUtils.d("addLaneNodeSource")
    val geoJsonSource = geoJsonSource(LANE_NODE_SOURCE) {
        data(source)
    }
    addSource(geoJsonSource)
}
fun Style.addLaneNodeCircleLayer(){
    LogUtils.d("addLaneNodeCircleLayer")
    val circleLayer = circleLayer(
        LANE_NODE_LAYER,
        LANE_NODE_SOURCE
    ){
        circleColor("red")
        circleRadius(6.0)
        visibility(Visibility.VISIBLE)
    }
    addLayer(circleLayer)
}
fun Style.addLaneNodeSymbolLayer(){
    LogUtils.d("addLaneNodeSymbolLayer")
    val symbolLayer = symbolLayer(LANE_NODE_TEXT_LAYER, LANE_NODE_SOURCE){
        textColor(Color.BLACK)
        textField(get("name"))
        textFont(listOf("DIN Offc Pro Italic", "Arial Unicode MS Regular"))
        textLineHeight(1.0)
        textPadding(1.0)
        textOffset(listOf(0.5,-0.5))
        textRotationAlignment(TextRotationAlignment.MAP)
        textAnchor(TextAnchor.TOP)
        textSize(9.0)
        textMaxWidth(10.0)
    }
    addLayer(symbolLayer)
}
fun Style.addTruckPathSource(){
    LogUtils.d("addTruckPathSource")
    val source =  geoJsonSource(TRUCK_PATH_SOURCE) {
        data("{ \"type\": \"FeatureCollection\", \"features\":[]}")
    }
    addSource(source)
}
fun Style.addTruckPathLineLayer(){
    LogUtils.d("addTruckPathLineLayer")
    val lineLayer = lineLayer(
        TRUCK_PATH_LAYER,
        TRUCK_PATH_SOURCE
    ){
        lineColor("green")
        lineWidth(8.0)
        lineOpacity(0.8)
        lineJoin(LineJoin.ROUND)
        lineCap(LineCap.ROUND)
        visibility(Visibility.VISIBLE)
    }
    addLayer(lineLayer)
}

fun Style.adjustLayerOrder(){
    LogUtils.d("adjustLayerOrder")
    moveStyleLayer(TRUCK_PATH_LAYER,LayerPosition(null,
        null,null))
    moveStyleLayer(LANE_NODE_LAYER,LayerPosition(null,
        TRUCK_PATH_LAYER,null))
    moveStyleLayer(LANE_NODE_TEXT_LAYER,LayerPosition(null,
        TRUCK_PATH_LAYER,null))
    moveStyleLayer(
        PARK_SPOT_LAYER, LayerPosition(null,
            LANE_NODE_LAYER,null)
    )
    moveStyleLayer(
        PARK_SPOT_TEXT_LAYER,
        LayerPosition(null, LANE_NODE_LAYER,null)
    )
    moveStyleLayer(
        STATION_AREA_LAYER, LayerPosition(null,
            PARK_SPOT_LAYER,null)
    )
    moveStyleLayer(
        STATION_AREA_TEXT_LAYER,
        LayerPosition(null, PARK_SPOT_LAYER,null)
    )
    moveStyleLayer(
        OBSTACLES_LAYER, LayerPosition(null,
            STATION_AREA_LAYER,null)
    )
    moveStyleLayer(
        OBSTACLES_TEXT_LAYER,
        LayerPosition(null, STATION_AREA_LAYER,null)
    )
    moveStyleLayer(
        LANE_LAYER, LayerPosition(null,
            OBSTACLES_LAYER,null)
    )
    moveStyleLayer(WET_AREA_LAYER, LayerPosition(null, LANE_LAYER,null))
    moveStyleLayer(
        WET_AREA_TEXT_LAYER,
        LayerPosition(null, LANE_LAYER,null)
    )
    moveStyleLayer(
        ELECTRONIC_FENCE_LAYER, LayerPosition(null,
            WET_AREA_LAYER,null)
    )
    moveStyleLayer(
        ELECTRONIC_FENCE_TEXT_LAYER,
        LayerPosition(null, WET_AREA_LAYER,null)
    )
    moveStyleLayer(
        BARRICADE_LAYER, LayerPosition(null,
            ELECTRONIC_FENCE_LAYER,null)
    )
    moveStyleLayer(
        DUMP_AREA_LAYER, LayerPosition(null,
            BARRICADE_LAYER,null)
    )
    moveStyleLayer(
        DUMP_AREA_TEXT_LAYER,
        LayerPosition(null, BARRICADE_LAYER,null)
    )
    moveStyleLayer(
        DIGGING_WORK_AREA_LAYER, LayerPosition(null,
            DUMP_AREA_LAYER,null)
    )
    moveStyleLayer(
        DIGGING_WORK_AREA_TEXT_LAYER,
        LayerPosition(null, DUMP_AREA_LAYER,null)
    )
    moveStyleLayer(
        STATIC_OBJECTS_LAYER, LayerPosition(null,
            DIGGING_WORK_AREA_LAYER,null)
    )
    moveStyleLayer(
        STATIC_OBJECTS_TEXT_LAYER,
        LayerPosition(null, DIGGING_WORK_AREA_LAYER,null)
    )
    moveStyleLayer(
        RUNNABLE_AREA_LAYER, LayerPosition(null,
            STATIC_OBJECTS_LAYER,null)
    )
}

internal fun AppCompatActivity.setupMapBoxStyle(mapBox:MapboxMap,viewModel:MainViewModel){
    mapBox.loadStyleUri(MY_MAP_BOX_STYLE)
    mapBox.getStyle{style->
       lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                viewModel.loadMapDataSource().collect{
                    when(it.sourceId){
                        OBSTACLES_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addObstaclesSource(it.geojson)
                                style.addObstaclesFillLayer()
                                style.addObstaclesSymbolLayer()
                            }
                        }
                        ELECTRONIC_FENCE_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addElectronicFenceSource(it.geojson)
                                style.addElectronicFenceFillLayer()
                                style.addElectronicFenceSymbolLayer()
                            }
                        }
                        WET_AREA_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addWetAreaSource(it.geojson)
                                style.addWetAreaFillLayer()
                                style.addWetAreaSymbolLayer()
                            }
                        }
                        LANE_NODE_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addLaneNodeSource(it.geojson)
                                style.addLaneNodeCircleLayer()
                                style.addLaneNodeSymbolLayer()
                            }
                        }
                        LANE_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addLaneSource(it.geojson)
                                style.addLaneLayer()
                            }
                        }
                        RUNNABLE_AREA_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addRunnableAreaSource(it.geojson)
                                style.addRunnableAreaLayer()
                            }
                        }
                        DUMP_AREA_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addDumpAreaSource(it.geojson)
                                style.addDumpAreaFillLayer()
                                style.addDumpAreaSymbolLayer()
                            }
                        }
                        DIGGING_WORK_AREA_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addDiggingWorkAreaSource(it.geojson)
                                style.addDiggingWorkAreaFillLayer()
                                style.addDiggingWorkAreaSymbolLayer()
                            }
                        }
                        BARRICADE_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addBarricadeSource(it.geojson)
                                style.addBarricadeLineLayer()
                            }
                        }
                        STATION_AREA_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addStationAreaSource(it.geojson)
                                style.addStationAreaFillLayer()
                                style.addStationAreaSymbolLayer()
                            }
                        }
                        PARK_SPOT_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addParkSpotSource(it.geojson)
                                style.addParkSpotFillLayer()
                                style.addParkSpotSymbolLayer()
                            }
                        }
                        STATIC_OBJECTS_SOURCE ->{
                            if (it.geojson.isNotEmpty()&&it.version != "-1") {
                                style.addStaticObjectsSource(it.geojson)
                                style.addStaticObjectsFillLayer()
                                style.addStaticObjectsSymbolLayer()
                            }
                        }
                        TRUCK_PATH_SOURCE ->{
                            style.addTruckPathSource()
                            style.addTruckPathLineLayer()
                        }
                    }
                    style.adjustLayerOrder()
                }
            }
        }
    }
}

private fun  AppCompatActivity.zoomOut(boxBinding:LayoutMapBoxBinding,viewModel:MainViewModel){
    boxBinding.zoomOut.setOnClickListener {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                viewModel.updateZoom(
                    BigDecimal("${boxBinding.mapView.getMapboxMap().cameraState.zoom}").add(
                    BigDecimal("0.1")
                ))
            }
        }
    }
}
private fun AppCompatActivity.zoomIn(boxBinding:LayoutMapBoxBinding, viewModel:MainViewModel){
    boxBinding.zoomIn.setOnClickListener {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                viewModel.updateZoom(
                    BigDecimal("${boxBinding.mapView.getMapboxMap().cameraState.zoom}").minus(
                    BigDecimal("0.1")
                ))
            }
        }
    }
}

private fun locationTruck(boxBinding:LayoutMapBoxBinding,viewModel:MainViewModel){
    boxBinding.locationTruck.setOnClickListener {
        boxBinding.mapView.getMapboxMap().flyTo(viewModel.cameraOptions.value)
    }
}

fun AppCompatActivity.setupMapBox(boxBinding:LayoutMapBoxBinding, viewModel:MainViewModel){
    val mapBox = boxBinding.mapView.getMapboxMap()
    lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.CREATED) {
            viewModel.cameraOptions.collect{
                mapBox.setCamera(it)
            }
        }
    }
    zoomOut(boxBinding,viewModel)
    zoomIn(boxBinding,viewModel)
    locationTruck(boxBinding,viewModel)
    setupMapBoxStyle(boxBinding.mapView.getMapboxMap(),viewModel)
}

fun AppCompatActivity.vehicleIcon() = BitmapUtils.bitmapFromDrawableRes(this, R.drawable.my_vehicle_normal)
fun AppCompatActivity.otherVehicleIcon() = BitmapUtils.bitmapFromDrawableRes(this, R.drawable.my_vehicle_normal)