<template>
	<el-form class="props-editor" v-if="data&&meta" v-model="data" size="mini" :label-width="labelWidth"
	         label-position="right" @submit.native.prevent>

		<component v-for="(property, key) in meta.props"
		           :key="key"
		           :is="mode + '-input-wrapper'"
		           :editable="editable"
		           :switchable="switchable"
		           :mode="mode"
		           :value="data[key]"
		           :container="data"
		           :property="property"
		           :propertyName="key"
		           @cmd-prop-change="onCmdPropChanged"
		>
			<component
				:is="getInput(property)"
				:container="data"
				:value="data[key]"
				:propertyName="key"
				:property="property"
				:editable="editable"
				:config ="property.input"
				@input="onInput"
			/>
		</component>
	</el-form>
</template>

<script>
	import {
		NumberInput,
		StringInput,
		TextInput,
		EnumInput,
		BooleanInput,
		ColorInput,
		AssetInput,
		NodeSelectInput,
		MapInput,
		DynamicInput,
		Vector2Input,
		SourceInput,
	} from "./inputs";
	import {parseType} from 'props-compute'
	import LinkableInputWrapper from "./inputs/LinkableInputWrapper";
	import CmdInputWrapper from "./inputs/CmdInputWrapper";
	import SampleInputWrapper from "./inputs/SampleInputWrapper";

	const inputMapping = {
		number: 'NumberInput',
		string: 'StringInput',
		text: 'TextInput',
		enum: 'EnumInput',
		boolean: 'BooleanInput',
		color: 'ColorInput',
		asset: 'AssetInput',
		node: 'NodeSelectInput',
		dynamic: 'DynamicInput',
		map: 'MapInput',
		vector2: 'Vector2Input',
		array: 'StringInput',
		source: 'SourceInput',
	};

	export default {
		name: "PropsEditor",
		components: {
			SourceInput,
			DynamicInput,
			MapInput,
			NodeSelectInput,
			AssetInput,
			ColorInput,
			BooleanInput,
			EnumInput,
			NumberInput,
			StringInput,
			TextInput,
			Vector2Input,
			LinkableInputWrapper,
			CmdInputWrapper,
			SampleInputWrapper,
		},
		data() {
			return {}
		},
		props: {
			labelWidth: {
				type: String,
				default: '100px',
			},
			editable: {
				type: Boolean,
				default: true
			},
			switchable: {
				type: Boolean,
				default: false
			},
			mode: {
				type: String,
				default: 'sample',
			},
			data: {
				type: Object,
			},
			meta: {
				type: Object,
			},
		},
		watch: {
			data(v) {

			}
		},
		methods: {
			getInput(property) {
				let {type} = parseType(property.type);
				return inputMapping[type];
			},
			onInput(value, container, propName, oldValue) {
				if (value === undefined) {
					this.$delete(container, propName);
				} else {
					this.$set(container, propName, value);
				}
				this.$emit('input', value, container, propName, oldValue);
			},
			onCmdPropChanged(value, container, propName, oldValue) {
				this.$emit('input', value, container, propName, oldValue);
			},
		}
	}
</script>

<style scoped>

</style>