<template>
	<pane class="views" icon="el-icon-s-grid" :title="$t('panes.Views')">
		<div class="container">
			<div class="header-bar">
				<el-link class="menu-item" @click="toAddView">{{$t('Add')}}</el-link>
				<el-link @click="onImportCommand('single')">{{$t('Import')}}</el-link>
				<el-dropdown trigger="hover" placement="top" size="mini" @command="onImportCommand">
					<el-link icon="el-icon-arrow-down" :underline="false"></el-link>
					<el-dropdown-menu slot="dropdown">
						<el-dropdown-item v-for="(item, key) in importViewMenu" :key="key" :command="key">{{item}}</el-dropdown-item>
					</el-dropdown-menu>
				</el-dropdown>
			</div>
			<div class="filter-bar">
				<el-input class="filter-input" prefix-icon="el-icon-search" v-model="filterText" size="mini" clearable/>
				<el-dropdown class="more-button" trigger="click" size="mini" @command="onFilterCommand">
					<el-link icon="el-icon-more" :underline="false"></el-link>
					<el-dropdown-menu slot="dropdown">
						<el-dropdown-item v-for="(item, key) in nodeFilterPresets" :command="key" :key="key">{{item}}
						</el-dropdown-item>
					</el-dropdown-menu>
				</el-dropdown>
				<!--<el-button size="mini" class="micro" icon="el-icon-magic-stick" circle @click="filterByBehavior"></el-button>-->
			</div>
			<el-scrollbar class="tree-scrollbar" wrap-class="wrap-x-hidden">
				<el-tree
					ref="tree"
					:data="views"
					:props="defaultProps"
					:expand-on-click-node="true"
					:default-expanded-keys="expandedKeys"
					draggable
					node-key="uuid"
					highlight-current
					:default-expand-all="false"
					empty-text=""
					:allow-drag="allowDrag"
					:allow-drop="allowDrop"
					:filter-node-method="filterNodeMethod"
					@current-change="handleNodeClick"
					@node-drop="onNodeDrop"
				>
					<div slot-scope="{ node, data }" class="tree-node">
						<div class="node-name">
							<i v-show="Object.keys(iconMap).includes(data.type)" :class="iconMap[data.type]"
							   style="color:#9b82e3"></i>
							{{data.name}}
						</div>

						<el-dropdown class="more-button" size="mini" trigger="click"
						             @command="(command)=>{onMoreMenu(command, data, node)}">
							<el-link icon="el-icon-more" :underline="false" @click.stop/>
							<el-dropdown-menu slot="dropdown">
								<el-dropdown-item command="delete">{{$t('Delete')}}</el-dropdown-item>
								<el-dropdown-item command="copy">{{$t('Copy')}}</el-dropdown-item>
								<el-dropdown-item command="paste">{{$t('Paste same level')}}</el-dropdown-item>
								<el-dropdown-item command="pasteChild">{{$t('Paste child')}}</el-dropdown-item>
								<el-dropdown-item command="export" divided v-if="!node.parent.parent">{{$t('Export')}}
								</el-dropdown-item>
								<el-dropdown-item v-for="(type, key, index) in $t('view_node_menu')"
								                  :key="key"
								                  :command="'add_node_' + key"
								                  :divided="index===0">
									{{$t('Add') + type}}
								</el-dropdown-item>
							</el-dropdown-menu>
						</el-dropdown>
					</div>
				</el-tree>
			</el-scrollbar>
		</div>
		<select-design-mode-dialog ref="selectDesignModeDialog" @change="onSelectDesignMode"/>
	</pane>
</template>

<script>
	import {mapState, mapMutations, mapActions, mapGetters} from 'vuex';
	import Pane from '../../components/Pane';
	import {selectFile} from "../../utils";
	import events from "../../global-events";
	import SelectDesignModeDialog from "./Views/SelectDesignModeDialog";

	export default {
		name: 'Views',
		components: {SelectDesignModeDialog, Pane},
		data() {
			return {
				filterText: '',
				defaultProps: {
					children: 'children',
					label: 'name'
				},
				expandedKeys: [],
				nodeFilterPresets: this.$t('nodeFilterPresets'),
				importViewMenu: this.$t('importViewMenu'),
				iconMap: {
					image: 'el-icon-picture',
					label: 'el-icon-edit-outline'
				}
			};
		},
		mounted() {
			events.$on('locate-view-node', this.locateViewNode);
			events.$on('locate-view-node-active', this.locateViewNodeActive);
		},
		destroyed() {
			events.$off('locate-view-node', this.locateViewNode);
		},
		computed: {
			...mapGetters(['activeComponentId']),
			...mapState({
				views: state => state.project.data.views
			})
		},
		watch: {
			activeComponentId: function (val) {
				this.$refs.tree.setCheckedKeys([val]); // 设置选中节点
				this.$refs.tree.setCurrentKey(val); // 设置高亮节点
				this.expandedKeys = [val]; // 展开对应的节点
			},
			filterText(val) {
				this.updateFilter();
			},
		},
		methods: {
			locateViewNode(node) {
				this.$refs.tree.setCurrentKey(node.uuid);
				this.expandedKeys = [node.uuid];
			},
			//重置编辑视图数据为实际视图数据
			resetScrollType(data) {
				if (data.type == "editScrollList") {
					data.type = "scrollList"
				}
				if (data.type == "editScrollView") {
					data.type = "scrollView"
				}
				if (data.children) {
					 for(let i=0;i<data.children.length;i++){
						this.resetScrollType(data.children[i])
					}
				}
				//console.log("1122334")
			},
			locateViewNodeActive(node) {

				if (this.$refs.tree) {
					//console.log("选中")
					this.$refs.tree.setCurrentKey(node.uuid);
					this.expandedKeys = [node.uuid];
					let data = this.$refs.tree.getCurrentNode()
					let nodeDom = this.$refs.tree.getNode(data)
					//this.resetScrollType(this.activeComponent)
					this.resetScrollType(data)
					this.resetScrollType(nodeDom.data)
					// if(data.type=="editScrollList"){
					// 	data.type="scrollList"
					// 	nodeDom.data.type="scrollList"
					// }

					// if(data.type=="editScrollView"){
					// 	data.type="scrollView"
					// 	nodeDom.data.type="scrollView"
					// }
					//console.log(data,nodeDom)
					this.$store.dispatch('activeComponent', {data, node: nodeDom});

					let styleCatch = {
						x: node.x,
						y: node.y,
						anchorX: node.anchorX,
						anchorY: node.anchorY,
						scaleX: node.scaleX,
						scaleY: node.scaleY,
						// imageWidth:parseInt(node.imageWidth),
						// imageHeight:parseInt(node.imageHeight),
						width: node._width,
						_width: node._width,
						_height: node._height,
						height: node._height,
					}
					this.$store.dispatch("modifyProperties", styleCatch);
				}
			},
			updateFilter() {
				if (this.$refs.tree) {
					this.$refs.tree.filter(this.filterText);
				}
			},
			filterNodeMethod(filterText, data) {
				let visible = false;
				if (filterText.startsWith(':')) {
					let remain = filterText.substr(1);
					let arr = remain.split('|');
					let cmd = arr[0];
					let param = arr[1];
					switch (cmd) {
						case 'trigger':
							if (data.events && Object.keys(data.events).length > 0) {
								visible = true;

								if (param && param.length > 0) {
									let events = param.split(',');
									let exists = false;
									for (let event of events) {
										if (data.events[event]) {
											exists = true;
											break;
										}
									}
									visible = exists;
								}
							}
							break;
						case 'script':
							if (data.scripts && data.scripts.length > 0) {
								visible = true;

								if (param && param.length > 0) {
									let scripts = param.split(',');
									let exists = false;
									for (let script of data.scripts) {
										if (scripts.includes(script.script)) {
											exists = true;
											break;
										}
									}
									visible = exists;
								}
							}
							break;
						case 'type':
							if (param && param.length > 0) {
								let types = param.split(',');
								visible = types.includes(data.type);
							} else {
								visible = true;
							}
							break;
						default:
							visible = true;
					}
				} else {
					visible = data.name.toLowerCase().includes(filterText.toLowerCase());
				}
				return visible;
			},
			onFilterCommand(command) {
				let filterText;
				switch (command) {
					case 'trigger':
						filterText = ':trigger';
						break;
					case 'script':
						filterText = ':script';
						break;
					case 'type':
						filterText = ':type|node';
						break;
				}
				this.filterText = filterText;
			},
			allowDrag(draggingNode) {
				//return draggingNode.parent.parent;

				return true;
			},
			allowDrop(draggingNode, dropNode, type) {
				//
				if (!draggingNode.parent.parent) { //根视图拖动
					return !dropNode.parent.parent && type !== 'inner';
				} else {
					return dropNode.parent.parent || type === 'inner';
				}
			},
			onNodeDrop() {
				this.makeProjectDirty();
				//setTimeout(()=>{
				events.$emit("canvasViewUpdate")
				//},200)
			},
			/**
			 * 点击左侧视图列表
			 */
			handleNodeClick(data, node) {

				this.resetScrollType(data)
				this.resetScrollType(node.data)

				// console.log('handleNodeClick',data,node);
				// console.log(this.getCurrentPath(node))

				this.$store.dispatch('activeComponent', {data, node});
				events.$emit('canvasActiveNodeByTree', this.getCurrentPath(node));

			},
			/**
			 * 获取树的路径，返回格式:0/0/1
			 */
			getCurrentPath(node) {
				let currentPath
				if (node && node.data) {
					let nodeParent = node.parent
					currentPath = [node]
					while (nodeParent && nodeParent.data && typeof nodeParent.data === 'object') {
						currentPath.unshift(nodeParent)
						nodeParent = nodeParent.parent
					}
				}
				let path = []
				for (let item of currentPath) {
					if (item.parent) {
						for (let cNode in item.parent.childNodes) {
							if (item.parent.childNodes[cNode] == item) {
								path.push(cNode)
							}
						}
					}
				}
				path.shift();
				//console.log(path.join("/"))
				return path.join("/");
			},
			toAddView() {
				this.$prompt(this.$t('Input view name'), this.$t('Alert'), {
					confirmButtonText: this.$t('Confirm'),
					cancelButtonText: this.$t('Cancel'),
					inputPattern: /^.{1,64}$/,
					inputErrorMessage: this.$t('Invalid view name')
				})
					.then(({value}) => {
						this.addNode({
							name: value,
							type: 'node'
						});
					})
					.catch(() => {
					});
			},
			toImport(action, mode) {
				selectFile(async files => {
					events.$emit('upload-indicator', true);
					try {
						await this.importView({
							file: files[0],
							action,
							mode,
						});
					} catch (e) {
					}
					events.$emit('upload-indicator', false);
				})
			},
			onImportCommand(importType) {
				let action, needSelectDesign = true;
				switch (importType) {
					case 'view_single':
						action = 1;
						needSelectDesign = false;
						break;
					case 'view_multi':
						action = 2;
						needSelectDesign = false;
						break;
					case 'psd_single':
						action = 3;
						break;
					case 'psd_multi':
						action = 4;
						break;
				}
				if(needSelectDesign){
					this.$refs.selectDesignModeDialog.show(action);
				}else{
					this.toImport(action);
				}
			},
			onSelectDesignMode(mode, action) {
				this.toImport(action, mode);
			},
			onMoreMenu(command, data, node) {
				switch (command) {
					case 'delete':
						this.$confirm(this.$t('Confirm to delete the view'), this.$t('Alert'), {
							confirmButtonText: this.$t('Confirm'),
							cancelButtonText: this.$t('Cancel'),
							type: 'warning'
						}).then(
							() => {
								this.deleteNode({
									node: data,
									parentNode: node.parent.data
								});
							},
							() => {
							}
						)
						break;
					case 'copy':

						this.$confirm(this.$t('Do you copy the behavior of this node'), this.$t('Alert'), {
							confirmButtonText: this.$t('Yes'),
							cancelButtonText: this.$t('No'),
							type: 'warning'
						}).then(
							() => {
								//copyState：1复制行为，2不复制行为
								this.copyNode({
									node: data,
									parentNode: node.parent.data,
									copyState: 1
								});

							},
							() => {
								//copyState：1复制行为，2不复制行为
								this.copyNode({
									node: data,
									parentNode: node.parent.data,
									copyState: 2
								});
							}
						)

						break;
					case 'paste':
						this.pasteNode({
							node: data,
							parentNode: node.parent.data,
							pasteState: 1
						});
						break;
					case 'pasteChild':
						this.pasteNode({
							node: data,
							parentNode: node.parent.data,
							pasteState: 2
						});
						break;
					case 'export':
						this.exportView(data);
						break;
					default:
						if (command.startsWith('add_node_')) {
							const type = command.substr('add_node_'.length);
							this.addNode({
								node: data,
								type,
								name: type,
							});
						}
						break;
				}
			},
			...mapMutations(['copyNode', 'pasteNode', 'deleteNode', 'addNode', 'makeProjectDirty']),
			...mapActions(['exportView', 'importView'])
		}
	};
</script>

<style scoped lang="scss">
	.filter-bar {
		display: flex;
		align-items: center;
	}

	.filter-input {
		flex: 1;
	}

	.more-button {
		margin: 0 3px;
	}
</style>
