// leaflet 地图组件
// author: wzx
// version: 1.0

import L from 'leaflet'
// import 'leaflet.motion/dist/leaflet.motion.min.js'

import patch from '@/utils/map/sub/patch'
import config from '@/utils/map/sub/config'
import global from '@/utils/map/sub/global'
import player from '@/utils/map/sub/player'
import checkPoint from '@/utils/map/sub/checkPoint'
import route from '@/utils/map/sub/route'
import store from '@/store/index'

export default {
	global: global,
	config: config,
	player: player,
	checkPoint: checkPoint,
	route: route,

	exControlContainer: null,
	elRoute: null,
	elPlayer: null,
	elPlayerTooltip: null,
	elPlayerTrail: null,
	elList: null,
	elFullScreen: null,

	// 地图初始化
	// mapid <string> 地图容器的id
	// mapUrl <string> 地图瓦片的地址
	// options <object> 地图选项
	init(caller, mapid, mapUrl, options) {
		patch.run()

		global.init()
		global.setCaller(caller)
		global.setMapUrl(mapUrl)
		global.mapOptions = Object.assign(config.mapDefaultOptions, options)
		if (global.mapOptions.maxBounds != null) {
			global.setPreloadBounds(global.mapOptions.maxBounds)
			// console.log("preloadBounds: ", global.mapOptions.maxBounds)
			// global.mapOptions.maxBounds = L.latLngBounds(global.mapOptions.maxBounds).pad(0.3)
			global.mapOptions.maxBounds = null
			// console.log("maxBounds: ", global.mapOptions.maxBounds)
		}

		global.map = L.map(mapid, global.mapOptions)
		// global.map = L.map(mapid, {
		// 	attributionControl: false
		// }).setView(centPoint, zoomNum)

		L.control.attribution({
			// prefix: '&copy; 小飞龙定向', // 地图右下角属性文本的前缀内容
			prefix: false // 地图右下角属性文本的前缀内容
		}).addTo(global.map);

		L.control.scale({
			maxWidth: 120, // 控件的最大宽度，单位是像素
			metric: true, // 是否显示公制比例线（米/公里）
			imperial: false, // 是否显示英制比例线（英里/英尺）
			position: 'topright' // 控件的位置（地图的一个角）。可能的值是 ‘topleft’、 ‘topright’、 ‘bottomleft’ 或 ‘bottomright’
		}).addTo(global.map)

		this.extendControl()

		// 添加地图点击弹窗
		global.map.on('click', (e) => {
			console.log("坐标", e.latlng.toString())
			// L.popup().setLatLng(e.latlng)
			// 	.setContent("坐标：" + e.latlng.toString())
			// 	.openOn(global.map);
		});

		// global.map.on('resize', (e) => {
		// 	console.log("[resize] 地图大小调整", e)
		// 	this.onWindowResize()
		// });

		// global.map.on('invalidateSize', (e) => {
		// 	console.log("[invalidateSize] 地图容器大小调整", e)
		// 	// this.onWindowResize()
		// });

		global.map.on('zoomstart', (e) => {
			// console.log("[zoomstart] 即将开始地图缩放", e)
			player.onZoomStart(e)
			checkPoint.onZoomStart(e)
			route.onZoomStart(e)
		});

		global.map.on('zoom', (e) => {
			// console.log("[zoom] 地图缩放", e)
			player.onZoom(e)
			checkPoint.onZoom(e)
			route.onZoom(e)
		});

		global.map.on('zoomend', (e) => {
			// console.log("[zoomend] 地图缩放结束", e)
			this.preLoadTile()
			player.onZoomEnd(e)
			checkPoint.onZoomEnd(e)
			route.onZoomEnd(e)
		});

		// global.map.on('zoomanim', (e) => {
		// 	console.log("地图缩放中...", e)
		// 	// player.onZoomEnd(e)
		// 	// checkPoint.onZoomEnd(e)
		// 	// route.onZoomEnd(e)
		// });

		// global.map.on('moveend', (e) => {
		// 	// console.log("[zoomend] 地图移动结束", e)
		// 	this.preLoadTile()
		// });

		this.addMapLayer(mapUrl)

		player.init()
		checkPoint.init()
		route.init()

		this.preLoadTile()
	},

	addMapLayer(mapUrl) {
		// console.log('[addMapLayer] mapurl', mapurl)
		// var mapurl = 'static/map/' + mapid + '/{z}/{x}/{y}.png'
		var tileUrl = mapUrl + '/{z}/{x}/{y}.png'
		global.map_layer = L.tileLayer(tileUrl, {
			// minZoom: minZoom,
			// maxZoom: maxZoom,
			errorTileUrl: '/static/image/tileMiss.png',
			tms: false, // 是否反转Y轴坐标,
			// keepBuffer: 20, // 平移地图时，在卸载切片之前，请保留这么多行和几列的切片
			// attribution: '版权所有'
		}).addTo(global.map);
	},

	// onWindowResize() {
	// 	var centPoint = global.mapOptions.center
	// 	if (centPoint != null) {
	// 		console.log("[Leaflet] onWindowResize centPoint:", centPoint)
	// 		global.map.setView(centPoint)
	// 		// global.map.panTo(centPoint)
	// 	}
	// },

	extendControl() {
		var that = this
		L.Control.Search = L.Control.extend({
			options: {
				position: 'topleft' //初始位置
			},
			initialize: function(options) {
				L.Util.extend(this.options, options)
			},
			onAdd: function(map) {
				// var caller = global.getCaller()
				//创建Dom元素 L.DomUtil.create('元素类型', 'class类名')
				that.exControlContainer = L.DomUtil.create('div', 'leaflet-bar')

				that.elRoute = L.DomUtil.create('a', 'leaflet-control-common')
				that.elRoute.innerHTML = '<span>路线</span>'
				if (store.state.mapControlRoute) {
					L.DomUtil.setClass(that.elRoute, 'leaflet-control-selected')
				}

				that.elPlayer = L.DomUtil.create('a', 'leaflet-control-common')
				that.elPlayer.innerHTML = '<span>玩家</span>'
				if (store.state.mapControlPlayer) {
					L.DomUtil.setClass(that.elPlayer, 'leaflet-control-selected')
				}

				that.elPlayerTooltip = L.DomUtil.create('a', 'leaflet-control-common')
				that.elPlayerTooltip.innerHTML = '<span>提示</span>'
				if (store.state.mapControlTooltip) {
					L.DomUtil.setClass(that.elPlayerTooltip, 'leaflet-control-selected')
				}

				that.elPlayerTrail = L.DomUtil.create('a', 'leaflet-control-common')
				that.elPlayerTrail.innerHTML = '<span>轨迹</span>'
				if (store.state.mapControlTrail) {
					L.DomUtil.setClass(that.elPlayerTrail, 'leaflet-control-selected')
				}

				that.elList = L.DomUtil.create('a', 'leaflet-control-common')
				that.elList.innerHTML = '<span>列表</span>'
				if (store.state.mapPopupShow) {
					L.DomUtil.setClass(that.elList, 'leaflet-control-selected')
				}

				that.elFullScreen = L.DomUtil.create('a', 'leaflet-control-common')
				that.elFullScreen.innerHTML = '<span>全屏</span>'
				if (store.state.fullScreen) {
					L.DomUtil.setClass(that.elFullScreen, 'leaflet-control-selected')
				}

				// that.exControlContainer.style.display = 'flex'
				that.exControlContainer.appendChild(that.elRoute)
				that.exControlContainer.appendChild(that.elPlayer)
				that.exControlContainer.appendChild(that.elPlayerTooltip)
				that.exControlContainer.appendChild(that.elPlayerTrail)
				that.exControlContainer.appendChild(that.elList)
				that.exControlContainer.appendChild(that.elFullScreen)

				//注册事件
				L.DomEvent.addListener(that.elRoute, 'click dblclick', function(ev) {
					that.elRouteClick(ev)
				}, that.route)

				L.DomEvent.addListener(that.elPlayer, 'click dblclick', function(ev) {
					that.elPlayerClick(ev)
				}, that.player)

				L.DomEvent.addListener(that.elPlayerTooltip, 'click dblclick', function(ev) {
					that.elPlayerTooltipClick(ev)
				}, that.player)

				L.DomEvent.addListener(that.elPlayerTrail, 'click dblclick', function(ev) {
					that.elPlayerTrailClick(ev)
				}, that.player)

				L.DomEvent.addListener(that.elList, 'click dblclick', function(ev) {
					that.elListClick(ev)
				}, this)

				L.DomEvent.addListener(that.elFullScreen, 'click dblclick', function(ev) {
					that.elFullScreenClick(ev)
				}, this)

				//返回这个主元素
				return that.exControlContainer
			},
			onRemove: function(map) {
				// Clean up the DOM
			},
		})

		//在L.control上添加一个search（封装好的函数）
		L.control.Search = function(options) {
			return new L.Control.Search(options)
		}
		//将自定义控件添加到地图上
		L.control.Search().addTo(global.map)
	},
	
	preventEvent(ev) {
		L.DomEvent.stopPropagation(ev)
		L.DomEvent.preventDefault(ev)
	},
	
	elRouteClick(ev) {
		this.preventEvent(ev)
		this.route.toggle()
		this.toggleControl(this.elRoute)
	},
	
	elPlayerClick(ev) {
		this.preventEvent(ev)
		this.toggleControl(this.elPlayer)
		this.player.togglePlayer()
	},
	
	elPlayerTooltipClick(ev) {
		this.preventEvent(ev)
		this.toggleControl(this.elPlayerTooltip)
		this.player.toggleTooltip()
		console.log("store.state.mapControlPlayer: " + store.state.mapControlPlayer)
		if (!store.state.mapControlPlayer) {
			this.player.togglePlayer(true)
			// this.player.toggleTooltipFlag = false
			this.toggleControl(this.elPlayer)
		}
	},
	
	elPlayerTrailClick(ev) {
		this.preventEvent(ev)
		this.toggleControl(this.elPlayerTrail)
		this.player.toggleTrail()
	},
	
	elListClick(ev) {
		this.preventEvent(ev)
		this.toggleControl(this.elList)
		global.getCaller().popupToggle()
	},
	
	elFullScreenClick(ev) {
		this.preventEvent(ev)
		this.toggleControl(this.elFullScreen)
		global.getCaller().fullScreenToggle()
	},
	
	toggleControl(el) {
		if (L.DomUtil.hasClass(el, 'leaflet-control-selected')) {
			L.DomUtil.removeClass(el, 'leaflet-control-selected')
		} else {
			L.DomUtil.setClass(el, 'leaflet-control-selected')
		}
	},

	long2tile(lon, zoom) {
		return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom)));
	},

	lat2tile(lat, zoom) {
		return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
			2 * Math.pow(2, zoom)));
	},

	// 预加载地图瓦片
	preLoadTile() {
		var zoom = global.map.getZoom()
		if (zoom >= global.mapOptions.maxZoom) {
			console.log("[preLoadTile] 已达到最大缩放级别，无需预加载地图瓦片")
			return
		}

		var preloadZoom = zoom + 1;
		if (global.getPreloadTileMapByZoom(preloadZoom) != null) {
			console.log("[preLoadTile] 跳过，已预加载地图瓦片 Zoom: " + preloadZoom)
			return
		} else {
			console.log("[preLoadTile] 预加载地图瓦片 Zoom: " + preloadZoom)
			global.setPreloadTileMap({
				zoom: preloadZoom
			})
		}

		var bounds = null
		var preloadBounds = global.getPreloadBounds()
		if (preloadBounds != null) {
			// console.log("[preLoadTile] preloadBounds", preloadBounds)
			bounds = L.latLngBounds(preloadBounds)
		} else {
			console.warn("[preLoadTile] preloadBounds == null")
			bounds = global.map.getBounds().pad(0.2)
		}

		var west = bounds.getWest()
		var south = bounds.getSouth()
		var east = bounds.getEast()
		var north = bounds.getNorth()

		// console.log("[preLoadTile] 预加载地图瓦片", bounds, west, south, east, north, zoom)

		// L.circleMarker([south, west], {
		// 		radius: 18, // 圆的半径 px
		// 		weight: 1.6, // 描边宽度 px
		// 		opacity: 1.0, // 描边不透明度
		// 		fill: true, // 是否填充
		// 		fillColor: 'red', // 填充颜色
		// 		fillOpacity: 1.0, // 填充不透明度
		// 	})
		// 	.addTo(global.map)
		// console.log("[preLoadTile] circleMarker", [south, west])

		// L.circleMarker([north, east], {
		// 		radius: 18, // 圆的半径 px
		// 		weight: 1.6, // 描边宽度 px
		// 		opacity: 1.0, // 描边不透明度
		// 		fill: true, // 是否填充
		// 		fillColor: 'red', // 填充颜色
		// 		fillOpacity: 1.0, // 填充不透明度
		// 	})
		// 	.addTo(global.map)
		// console.log("[preLoadTile] circleMarker", [north, east])

		// Determine which tile we need
		var dataEast = this.long2tile(east, preloadZoom)
		var dataWest = this.long2tile(west, preloadZoom)
		var dataNorth = this.lat2tile(north, preloadZoom)
		var dataSouth = this.lat2tile(south, preloadZoom)

		var mapUrl = global.getMapUrl()
		// console.log("[preLoadTile] dataNorth = " + dataNorth + "  dataSouth = " + dataSouth)
		for (let y = dataNorth; y < dataSouth + 1; y++) {
			// console.log("[preLoadTile] y = " + y)
			for (let x = dataWest; x < dataEast + 1; x++) {
				// console.log("[preLoadTile] x = " + x)
				var url = mapUrl + '/' + preloadZoom + '/' + x + '/' + y + '.png'
				var img = new Image()
				img.src = url
				// console.log("[preLoadTile] 预加载地图瓦片", url)
			}
		}
	},

	test() {
		console.log("test ok")
	},

	free() {
		console.log("[Leaflet] free()")
		player.free()
		checkPoint.free()
		route.free()
	}
}