<template>
	<div class="behavior">
		<split-panes>
			<split-panes splitpanes-min="10" :splitpanes-size="10" horizontal>
				<process-list @edit-meta="onEditMeta" @delete-meta="onDeleteMeta" :data="processTree[0].children"
				              class="background full-size" splitpanes-min="20"
				              :splitpanes-size="20"/>
				<process-list @edit-meta="onEditMeta" @delete-meta="onDeleteMeta" :data="processTree[1].children"
				              class="background full-size" splitpanes-min="20"
				              :splitpanes-size="80"/>
			</split-panes>
			<div class="center full-size background" splitpanes-min="20" :splitpanes-size="70">
				<div class="top-bar">
					<edit-path :processStack="processStack" @pop="onPop"/>
					<!--<el-button icon="el-icon-search" circle plain size="mini" @click="onClickSearch"></el-button>-->
				</div>
				<!--<div class="operate-bar">
					<el-button-group>
						<el-button size="mini" icon="el-icon-zoom-out" @click="setScale(-0.1)"/>
						<el-button size="mini" @click="setScale(0)">1:1</el-button>
						<el-button size="mini" icon="el-icon-zoom-in" @click="setScale(0.1)"/>
					</el-button-group>
				</div>-->
				<board ref="board"
				       @select-process-node="onSelectProcessNode"
				       @edit-process="editProcess"
				       @transform="onClickTransform"
				       @edit-meta="onEditMeta"/>
			</div>
			<div class="properties background full-size" splitpanes-min="20" :splitpanes-size="20">
				<properties-editor ref="properties"/>
			</div>
		</split-panes>
		<meta-editor-dialog ref="metaEditorDialog" @input="onSaveMeta"/>
	</div>
</template>

<script>
	import {mapState, mapMutations, mapGetters, mapActions} from 'vuex'
	import Board from "./Board";
	import SplitPanes from 'splitpanes'
	import ProcessList from "./ProcessList";
	import PropertiesEditor from "./PropertiesEditor";
	import EditPath from "./Board/EditPath";
	import Process from "./Board/Process";
	import MetaEditorDialog from "./MetaEditorDialog";

	export default {
		name: "BehaviorEditor",
		components: {MetaEditorDialog, PropertiesEditor, EditPath, ProcessList, Board, SplitPanes,},
		props: [],
		data() {
			return {
				metaInEditing: null,
			}
		},
		computed: {
			processContext() {
				const {processPackages, customProcessMap} = this.$store.getters;
				return [
					processPackages,
					customProcessMap,
				]
			},
			...mapState({
				data: state => state.project.data,
				behavior: state => state.behavior.currentBehavior,
				processStack: state => state.behavior.processStack,
				lastProcess: state => state.behavior.lastProcess,
			}),
			...mapGetters([
				'processTree',
			]),
		},
		methods: {
			resolveProcess(id) {
				for (let context of this.processContext) {
					if (context[id]) {
						return context[id];
					}
				}
			},
			edit(path, index = 0) {
				this.behavior_startEdit({
					originData: this.data,
					behavior: path[0].process,
				});

				this.clearProcessStack();

				let parent;
				for (let i = 0; i <= index; i++) {
					const item = path[i];
					let subProcess = new Process(parent, item.process, this.resolveProcess);
					this.pushProcessStack(subProcess);
					parent = subProcess;
				}
				this.editProcess(parent, false);
			},
			onSelectProcessNode(process) {
				this.$refs.properties.edit(process);
			},
			editProcess(process, editStack = true) {
				if (editStack) {
					this.pushProcessStack(process);
				}
				this.$refs.board.edit(process, this.resolveProcess);
				this.$refs.properties.edit();
			},
			onPop(index) {
				this.popProcessStack(index + 1);
				let process = this.processStack[this.processStack.length - 1];
				this.$refs.board.edit(process, this.resolveProcess, this.lastProcess);
				this.$refs.properties.edit();
			},
			onEditMeta(meta, parentMeta) {
				this.metaInEditing = meta;
				this.$refs.metaEditorDialog.edit(meta, parentMeta);
			},
			onDeleteMeta(meta) {
				const requirePaths = this.$store.getters.metaInUse(meta.id);
				if (requirePaths.length > 0) {
					let metas = requirePaths.map(path => {
						return path.map(meta => `<b>${(meta.name || meta.meta) + (meta.alias ? '[' + meta.alias + ']' : '')}</b>`).join(' > ')
					}).join('<br>');
					this.$alert(metas, this.$t('Meta is in use, can not delete'), {
						dangerouslyUseHTMLString: true,
					})
						.catch((e) => {
						});
				} else {
					this.$confirm(this.$t('Are you sure to delete this meta'), this.$t('Alert'), {
						confirmButtonText: this.$t('Delete'),
						cancelButtonText: this.$t('Cancel'),
						type: 'warning'
					}).then(() => {
						this.deleteProcessMeta({meta});
					}).catch((e) => {
					});
				}
			},
			onSaveMeta(meta) {
				let oldMetaID = this.metaInEditing.id;
				for (let key in meta) {
					this.metaInEditing[key] = meta[key];
				}
				this.metaInEditing = null;
				if (oldMetaID !== meta.id) {
					this.updateProcesses({
						targetMetaID: oldMetaID,
						replaceMetaID: meta.id,
					});
				}
				this.$refs.board.updateProcessNode(meta.id);
			},
			onClickTransform(process, parentMeta) {
				const {isInline} = process.meta;
				const inlineType = this.$t(isInline ? 'Common' : 'Inline');
				this.$confirm(this.$t('Are you sure to transform process?', {inlineType}), this.$t('Alert'))
					.then(() => {
						this.switchProcessInlineType({process, parentMeta});
					}).catch(e => {
				})
			},
			...mapMutations([
				'behavior_startEdit',
				'updateProcesses',
				'deleteProcessMeta',
				'updatePropsEditable',
				'clearProcessStack',
				'pushProcessStack',
				'popProcessStack',
				'setScale',
				'switchProcessInlineType',
			]),
			...mapGetters([
				'metaInUse',
			]),
		}
	}
</script>

<style scoped>

</style>
