<template>
	<el-form label-width="80px" size="mini" :inline="inline">
		<span v-for="(va, key) in value" :key="key">
			<AMap v-if="includes(va, 'Object')" :value="va" :keys="keys[key] || {}"></AMap>
			<div v-else-if="includes(va, 'Array') && keys[key]">
				<el-form-item :label="keys[key]" v-if="key == 'center'">
					{{ va }}
					<el-button type="primary" @click="clickCenter(va)">修改中心</el-button>
				</el-form-item>
				<el-form-item :label="keys[key]._name" v-else-if="key == 'covers'">
					<el-button type="primary" @click="clickPolygon(value, key)" style="margin-bottom: 5px;">新增或修改覆盖物</el-button>
					<el-table :data="value[key]" border style="width: 100%">
						<el-table-column v-for="(name, prop) in keys[key]" :label="name" v-if="prop != '_name'" :key="prop">
							<template slot-scope="scope">
								<el-input v-if="prop == 'legend'" v-model="scope.row[prop]"></el-input>
								<el-input v-else-if="prop == 'value'" v-model="scope.row[prop]"></el-input>
								<span v-else>{{ scope.row[prop] }}</span>
							</template>
						</el-table-column>
						<el-table-column label="操作" fixed="right" width="50">
							<template slot-scope="scope">
								<el-button type="danger" icon="el-icon-delete" circle @click="value[key].splice(scope.$index,1)"></el-button>
							</template>
						</el-table-column>
					</el-table>
				</el-form-item>
				<component
					:label="keys[key]._name"
					v-else
					:is="va | arrayType"
					:value="va"
					:keys="keys[key]"
					:headers="value['tabHeader'] || []"
					@change="change"
					:changeData="changeData"
				></component>
			</div>
			<template v-else>
				<el-form-item :label="keys[key] || key" v-if="keys[key] && key != '_caveat'"><el-input v-model="value[key]" type="textarea"></el-input></el-form-item>
				<el-alert style="margin-bottom: 10px;" v-if="key == '_caveat'" :title="value[key]" type="error" effect="dark" :closable="false"></el-alert>
			</template>
		</span>
		<el-drawer class="map-address-drawer" size="60%" direction="ltr" :append-to-body="true" :visible.sync="mapInnerDrawer">
			<template slot="title">
				<div>{{ mapTitle }}</div>
				<el-form style="margin-right: 10px;" label-width="6em" size="mini">
					<el-form-item style="margin-bottom: 0;" label="地名查询">
						<el-select style="width: 26em;" v-model="mapAddress" filterable placeholder="请输入关键字" remote :remote-method="remoteMethod" @change="addressChange">
							<el-option v-for="(item, index) in addressTips" :key="item.id" :label="item.name" :value="index" v-if="item.location">
								<span style="float: left">{{ item.name }}</span>
								<span style="float: right; color: #8492a6; font-size: 13px">{{ item.district + item.address }}</span>
							</el-option>
						</el-select>
					</el-form-item>
				</el-form>
			</template>
			<el-card class="box-card" style="position: absolute;top: 100px;left: 30px;z-index: 9999;">
				<div slot="header" class="clearfix"><span>操作说明</span></div>
				<div>1、圆和矩形通过拖拽来绘制</div>
				<div>2、其他覆盖物通过点击来绘制、双击结束绘制</div>
				<div style="color: red;">3、右键单击图形清除绘制</div>
				<div style="color: red;">4、图形上左键双击再次编辑,再双击结束编辑</div>
				<div>
					<el-radio v-model="coversType" label="marker">画点</el-radio>
					<el-radio v-model="coversType" label="polyline">画折线</el-radio>
					<el-radio v-model="coversType" label="polygon">画多边形</el-radio>
					<el-radio v-model="coversType" label="rectangle">画矩形</el-radio>
					<el-radio v-model="coversType" label="circle">画圆</el-radio>
				</div>
			</el-card>
			<div ref="amap" style="width: 100%;height: 100%;position: relative;"></div>
		</el-drawer>
	</el-form>
</template>

<script>
import tplArray from './dataTypeTpl/array1Obj.vue';
export default {
	name: 'AMap',
	components: {
		tplArray
	},
	props: {
		value: {
			type: Object,
			default() {
				return {};
			}
		},
		keys: {
			type: Object,
			default() {
				return {};
			}
		},
		inline: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			//关键字搜索
			mapAddress: '',
			addressTips: [],
			//地图
			mapInnerDrawer: false,
			mapTitle: '',
			center: [106.630153, 26.647661],
			events: '',
			//表头变化
			changeData: {},
			//保存的轮廓数据Id
			overlaysId: [],
			//覆盖物绘画类型
			coversType: 'polygon',
			mouseTool: null
		};
	},
	//检测数组 - 对应数据结构类型
	filters: {
		arrayType(value) {
			return value.length ? (Array.isArray(value[0]) ? 'tplTabArray' : 'tplArray') : 'tplArray';
		}
	},
	watch: {
		coversType(n, v) {
			this.mouseTool[n]();
		}
	},
	mounted() {
		//输入提示 多边形编辑器插件
		AMap.plugin(['AMap.Autocomplete', 'AMap.PolyEditor', 'AMap.ToolBar','AMap.MouseTool'], () => {
			//输入提示
			this.autocomplete = new AMap.Autocomplete();
			this.autocomplete.on('complete', e => {
				this.addressTips = e.tips || [];
			});
		});
	},
	methods: {
		clickCenter(value) {
			this.mapTitle = '鼠标双击选择点';
			this.mapInnerDrawer = true;
			this.initmap().then(map => {
				map.on('dblclick', e => {
					value.splice(0, 1, e.lnglat.getLng());
					value.splice(1, 1, e.lnglat.getLat());
					this.$message({
						message: `中心点更新为${value.toString()}`,
						showClose: true,
						type: 'success'
					});
				});
			});
		},
		clickPolygon(value, key) {
			this.coversKey = key;
			this.mapTitle = '鼠标点击绘画轮廓';
			this.mapInnerDrawer = true;
			this.initmap().then(map => {
				//添加轮廓绘画工具
				this.mouseTool = new AMap.MouseTool(map);
				//监听draw事件可获取画好的覆盖物
				this.mouseTool.on('draw', e => {
					this.addPolyDraw(e.obj,value[key]);
				});
				this.mouseTool[this.coversType]();
				//同步数据ID
				const fgw = value[key].map((x, i) => {
					const id = x.id || i+1;
					this.overlaysId.includes(id) || this.overlaysId.push(id);
					let m = null;
					switch (x.type) {
						case 'Marker':
							m = new AMap[x.type]({
								position: x.position,
								icon: x.iconm,
								draggable:true
							});
							break;
						case 'Circle':
							m = new AMap[x.type]({
								center: { ...x.center },
								radius: x.radius,
								...x.style
							});
							break;
						case 'Polygon':
						case 'Polyline':
							m = new AMap[x.type]({
								path: [...x.path],
								...x.style
							});
							break;
					}
					if (m) {
						let pEdit = null;
						m.on('rightclick', e => {
							pEdit && pEdit.close();
							map.remove(e.target);
							const idIndex = this.overlaysId.indexOf(id);
							idIndex > -1 && value[key].splice(idIndex, 1);
							idIndex > -1 && this.overlaysId.splice(idIndex, 1);
						});
						this.initEdit(m,map,value[key][i],e=>pEdit=e);
						map.add(m);
					}
					return m;
				});
				setTimeout(() => {
					// map.setFitView(fgw, true, [0, 0, 0, 0], 17.5);
					map.setFitView(fgw, true, [-100, -100, -100, -100], 17.5);
					map.setZoom(17.5);
				}, 500);
			});
		},
		//启用修改理
		initEdit(m,map,value,fun) {
			// 实例化多边形编辑器，传入地图实例和要进行编辑的多边形实例
			const pe = new AMap.PolyEditor(map, m);
			let __edit = false;
			//编辑
			m.on('dblclick', e => {
				//关闭绘图
				this.mouseTool.close();
				// 开启编辑模式
				(__edit = !__edit)?pe.open():pe.close();
			});
			//结束编辑
			pe.on("end",e=>{
				//开启绘图
				this.mouseTool[this.coversType]();
				value && this.addPolyDraw(e.target,value,true);
			});
			typeof fun == "function" && fun(pe);
		},
		//新增图形处理函数
		addPolyDraw(e,value,_id){
			const type = e.CLASS_NAME.split('.')[1],
				id = e._amap_id;
			// typeof e.setDraggable == "function" && e.setDraggable(true);
			switch (type) {
				case 'Marker':
					const position = e.getPosition();
					!_id?value.push({
						id,
						type,
						position,
						legend: 1,
						value: ''
					}):(value.position = position);
					break;
				case 'Circle':
					//获取中心
					const center = e.getCenter(),
						//获取半径
						radius = e.getRadius();
					if(!_id){
						value.push({
							id,
							type,
							center,
							radius,
							legend: 1,
							value: ''
						})
					}else{
						value.center = center;
						value.radius = radius;
					}
					break;
				case 'Polygon':
				case 'Polyline':
					const path = e.getPath().map(x => {
						return [x.lng, x.lat];
					});
					if(!_id){
						value.push({
							id,
							type,
							path,
							legend: 1,
							value: ''
						})
					}else{
						value.path = path;
					}
					break;
			}
			this.initEdit(e,this.mapObject,null,pe=>{
				if(!_id){
					this.overlaysId.push(id);
					//对画好的覆盖物绑定事件
					e.on('rightclick', e => {
						pe.close();
						this.mapObject.remove(e.target);
						const idIndex = this.overlaysId.indexOf(id);
						idIndex > -1 && value.splice(idIndex, 1);
						idIndex > -1 && this.overlaysId.splice(idIndex, 1);
					});
				}
			});
		},
		change(data) {
			this.changeData = data;
		},
		initmap() {
			return this.getAMap().then(div => {
				this.mapObject = new AMap.Map(div, {
					layers: [
						// 卫星
						new AMap.TileLayer({
							tileUrl: 'https://mt3.google.cn/vt/imgtp=png32&lyrs=y&hl=zh-CN&gl=cn&x=[x]&y=[y]&z=[z]&s=Galil',
							zIndex: 2 // 在默认层级之上
						})
					],
					resizeEnable: true, //是否监控地图容器尺寸变化
					zoom: 10, //初始化地图层级
					...this.value.map
				});
				this.mapObject.addControl(
					new AMap.ToolBar({
						position: 'RT'
					})
				);
				return this.mapObject;
			});
		},
		getAMap(i = 0) {
			if (this.$refs.amap) {
				return new Promise(r => {
					r(this.$refs.amap);
				});
			} else if (i < 5) {
				return new Promise(r => {
					setTimeout(() => {
						r(this.getAMap(i++));
					}, 500);
				});
			}
		},
		remoteMethod(e) {
			if (!this.autocomplete) return;
			this.autocomplete.search(e);
		},
		addressChange(e) {
			this.mapObject.setZoomAndCenter(17,this.addressTips[e].location);
		}
	}
};
</script>
<style>
.map-address-drawer #el-drawer__title {
	margin-bottom: 20px;
	flex: none;
}
</style>
