package com.waytous.anticollision.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.SpannableString
import android.text.style.AbsoluteSizeSpan
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.blankj.utilcode.util.LogUtils
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.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.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.extension.style.sources.generated.geoJsonSource
import com.waytous.anticollision.ui.MainViewModel


const val databaseName = "anti_collision.db"

/**
 * 连接状态
 * */
enum class ConnectStatus {
    Disconnected, Connected
}

/**
 * 登录状态
 * */
enum class SignInStatus {
    SignOut, SignIn
}

/**
 * tcp通信错误定义
 * */
enum class Error(val reason:String = "success") {
    NOError,
    IOError("io error"),
    StreamClosed("stream closed"),
    ConnectionRefused("connection refused"),
    Timeout("time out"),
    NotConnected("not connected"),
    UserDisconnected("user disconnected"),
    InvalidParam("invalid param"),
    ServerUnknownError("server unknown error"),
    JT808EncodeError("jt808 codec encode error"),
    JT808DecodeError("jt808 codec decode error")
}

fun TextView.setTextSize(spannableString: SpannableString,content:String,delimiter:String = "km"){
    val absoluteSizeSpan = AbsoluteSizeSpan(40,true)
    spannableString.setSpan(absoluteSizeSpan,0,content.indexOf(delimiter),Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    text = spannableString
}

fun Context.getBitmapFromVectorDrawable(drawableId:Int,scale:Int = 2): Bitmap? {
    val drawable: Drawable? = ContextCompat.getDrawable(this, drawableId)
    val bitmap = drawable?.intrinsicWidth?.let {
        Bitmap.createBitmap(
            it/scale, drawable.intrinsicHeight/scale,
            Bitmap.Config.ARGB_8888
        )
    }
    bitmap?.let { Canvas(it).also {canvas->
        drawable.setBounds(0, 0, canvas.width, canvas.height)
        drawable.draw(canvas)
    } }
    return bitmap
}

/**
 * runablearea:可行驶区域
 * */
fun Style.addRunnableAreaSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addRunnableAreaSource")
    LogUtils.dTag("MapBoxExtensions","addRunnableAreaSource,source = ${source.substring(0..15)}")
    val source = geoJsonSource(MainViewModel.RUNNABLE_AREA_SOURCE){
        data(source)
    }
    addSource(source)
}

fun Style.addRunnableAreaLayer(){
    LogUtils.dTag("MapBoxExtensions","addRunnableAreaLayer")
    val fillLayer = fillLayer(
        MainViewModel.RUNNABLE_AREA_LAYER,
        MainViewModel.RUNNABLE_AREA_SOURCE
    ){
        fillColor("#98a0a0")
        fillOpacity(0.85)
        fillOutlineColor("#FFFF00")
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}
/**
 * lanelayer:整个矿山边界路线
 * */
fun Style.addLaneSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addLaneSource")
    val source = geoJsonSource(MainViewModel.LANE_SOURCE){
        data(source)
    }
    addSource(source)
}
fun Style.addLaneLayer(){
    LogUtils.dTag("MapBoxExtensions","addLaneLayer")
    val lineLayer = lineLayer(
        MainViewModel.LANE_LAYER,
        MainViewModel.LANE_SOURCE
    ){
        lineColor("white")
        lineWidth(3.0)
        lineJoin(LineJoin.ROUND)
        lineCap(LineCap.ROUND)
        visibility(Visibility.VISIBLE)
    }
    addLayer(lineLayer)
}
/**
 * staticobjs:静态对象区域
 * */
fun Style.addStaticObjectsSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addStaticObjectsSource")
    val source = geoJsonSource(MainViewModel.STATIC_OBJECTS_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addStaticObjectsFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addStaticObjectsFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.STATIC_OBJECTS_LAYER,
        MainViewModel.STATIC_OBJECTS_SOURCE
    ){
        fillColor("#98a0a0")
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}
fun Style.addStaticObjectsSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addStaticObjectsSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.STATIC_OBJECTS_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
/**
 * diggingarea:挖掘区域
 * */
fun Style.addDiggingWorkAreaSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addDiggingWorkAreaSource")
    val source = geoJsonSource(MainViewModel.DIGGING_WORK_AREA_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addDiggingWorkAreaFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addStaticObjectsFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.DIGGING_WORK_AREA_LAYER,
        MainViewModel.DIGGING_WORK_AREA_SOURCE
    ){
        fillColor("#886e26")
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}
fun Style.addDiggingWorkAreaSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addDiggingWorkAreaSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.DIGGING_WORK_AREA_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
/**
 * dumparea:排土区域
 * */
fun Style.addDumpAreaSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addDumpAreaSource")
    val source = geoJsonSource(MainViewModel.DUMP_AREA_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addDumpAreaFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addDumpAreaFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.DUMP_AREA_LAYER,
        MainViewModel.DUMP_AREA_SOURCE
    ){
        fillColor("#886e26")
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}
fun Style.addDumpAreaSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addDumpAreaSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.DUMP_AREA_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
/**
 * barricade:挡墙
 * */
fun Style.addBarricadeSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addBarricadeSource")
    val source = geoJsonSource(MainViewModel.BARRICADE_SOURCE) {
        data(source)
    }
    addSource(source)
}

fun Style.addBarricadeLineLayer(){
    LogUtils.dTag("MapBoxExtensions","addLaneLayer")
    val lineLayer = lineLayer(
        MainViewModel.BARRICADE_LAYER,
        MainViewModel.BARRICADE_SOURCE
    ){
        lineColor("blue")
        lineWidth(4.0)
        lineJoin(LineJoin.ROUND)
        lineCap(LineCap.ROUND)
        visibility(Visibility.VISIBLE)
    }
    addLayer(lineLayer)
}
/**
 * obstacles:障碍物
 * */
fun Style.addObstaclesSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addObstaclesSource")
    val source = geoJsonSource(MainViewModel.OBSTACLES_SOURCE) {
        url(source)
    }
    addSource(source)
}
fun Style.addObstaclesFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addObstaclesFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.OBSTACLES_LAYER,
        MainViewModel.OBSTACLES_SOURCE
    ){
        fillColor("#6f9bdd")
        fillOpacity(0.8)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}
fun Style.addObstaclesSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addObstaclesSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.OBSTACLES_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
/**
 * stationarea:静态物体
 * */
fun Style.addStationAreaSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addStationAreaSource")
    val source = geoJsonSource(MainViewModel.STATION_AREA_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addStationAreaFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addStationAreaFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.STATION_AREA_LAYER,
        MainViewModel.STATION_AREA_SOURCE
    ){
        fillColor("lightgreen")
        fillOpacity(0.8)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}
fun Style.addStationAreaSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addStationAreaSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.STATION_AREA_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
/**
 * lanenode:道路节点
 * */
fun Style.addLaneNodeSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addLaneNodeSource")
    val source = geoJsonSource(MainViewModel.LANE_NODE_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addLaneNodeCircleLayer(){
    LogUtils.dTag("MapBoxExtensions","addLaneNodeCircleLayer")
    val circleLayer = circleLayer(
        MainViewModel.LANE_NODE_LAYER,
        MainViewModel.LANE_NODE_SOURCE
    ){
        circleColor("red")
        circleRadius(6.0)
        visibility(Visibility.VISIBLE)
    }
    addLayer(circleLayer)
}
fun Style.addLaneNodeSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addLaneNodeSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.LANE_NODE_TEXT_LAYER, MainViewModel.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)
}
/**
 * parkspot:停车区
 * */
fun Style.addParkSpotSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addParkSpotSource")
    val source = geoJsonSource(MainViewModel.PARK_SPOT_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addParkSpotFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addParkSpotFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.PARK_SPOT_LAYER,
        MainViewModel.PARK_SPOT_SOURCE
    ){
        fillColor(get("#7e8185"))
        fillOpacity(0.8)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}

fun Style.addParkSpotSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addParkSpotSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.PARK_SPOT_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
/**
 * 电子围栏
 * */
fun Style.addElectronicFenceSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addElectronicFenceSource")
    val source = geoJsonSource(MainViewModel.ELECTRONIC_FENCE_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addElectronicFenceFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addElectronicFenceFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.ELECTRONIC_FENCE_LAYER,
        MainViewModel.ELECTRONIC_FENCE_SOURCE
    ){
        fillColor(get("color"))
        fillOpacity(0.85)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}

fun Style.addElectronicFenceSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addElectronicFenceSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.ELECTRONIC_FENCE_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}

fun Style.addWetAreaSource(source: String){
    LogUtils.dTag("MapBoxExtensions","addWetAreaSource")
    val source = geoJsonSource(MainViewModel.WET_AREA_SOURCE) {
        data(source)
    }
    addSource(source)
}
fun Style.addWetAreaFillLayer(){
    LogUtils.dTag("MapBoxExtensions","addWetAreaFillLayer")
    val fillLayer = fillLayer(
        MainViewModel.WET_AREA_LAYER,
        MainViewModel.WET_AREA_SOURCE
    ){
        fillColor(get("color"))
        fillOpacity(0.8)
        fillAntialias(false)
        visibility(Visibility.VISIBLE)
    }
    addLayer(fillLayer)
}

fun Style.addWetAreaSymbolLayer(){
    LogUtils.dTag("MapBoxExtensions","addWetAreaSymbolLayer")
    val symbolLayer = symbolLayer(MainViewModel.WET_AREA_TEXT_LAYER, MainViewModel.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)
    }
    addLayer(symbolLayer)
}
fun Style.addTruckPathSource(){
    LogUtils.dTag("MapBoxExtensions","addTruckPathSource")
    val source =  geoJsonSource("truckPathSource") {
        data("{ \"type\": \"FeatureCollection\", \"features\":[]}")
    }
    addSource(source)
}
fun Style.addTruckPathLineLayer(){
    LogUtils.dTag("MapBoxExtensions","addTruckPathLineLayer")
    val lineLayer = lineLayer(
        "truckPathLayer",
        "truckPathSource"
    ){
        lineColor("green")
        lineWidth(8.0)
        lineOpacity(0.8)
        lineJoin(LineJoin.ROUND)
        lineCap(LineCap.ROUND)
        visibility(Visibility.VISIBLE)
    }
    addLayer(lineLayer)
}

fun AppCompatActivity.checkSelfPermissionCompat(permission: String) =
    ActivityCompat.checkSelfPermission(this, permission)

fun AppCompatActivity.shouldShowRequestPermissionRationaleCompat(permission: String) =
    ActivityCompat.shouldShowRequestPermissionRationale(this, permission)

fun AppCompatActivity.requestPermissionsCompat(permissionsArray: Array<String>,
                                               requestCode: Int) {
    ActivityCompat.requestPermissions(this, permissionsArray, requestCode)
}

