<template>
<div>
    <div class="v-context" v-show="show" :style="style" tabindex="-1" v-on-clickaway="close"  ref="menu" :menu="menu" >
        <ul>
            <li @click="onClickList" @mouseover="onClickList" v-for="item in menuItems" :key="item.code" :id="item.code" :disabled="item.disabled">{{item.lebel}}<Icon :icon="['fabt', 'chevron-right']" class="navIcon" v-if="item.hasChild"/>
            </li>
        </ul>
    </div>
    <div class="v-contextChildOne" v-show="showChildOne" ref="menuChildOne" >
        <ul>
            <li v-for="item in menuLevelOne" :key="item.code">{{item.lebel}}
            </li>
        </ul>
    </div>
</div>

</template>

<script>
import { mixin as clickaway } from 'vue-clickaway'
import { FontAwesomeIcon as Icon } from '@fortawesome/vue-fontawesome'
export default {
	mixins: [clickaway],
	components: {
		Icon
	},
	props: {
		/**
		 * Close the menu on click.
		 * @type {boolean}
		 */
		menu: {
			type: Array,
			default: function () {
				return []
			},
			required: true
		},
		closeOnClick: {
			type: Boolean,
			default: true
		},
		/**
		 * Close the menu automatically on window scroll.
		 * @type {boolean}
		 */
		closeOnScroll: {
			type: Boolean,
			default: true
		}
	},
	computed: {
		/**
		 * Generate the CSS styles for positioning the context menu.
		 * @returns {object|null}
		 */
		style() {
			return this.show
				? { top: `${this.top}px`, left: `${this.left}px` }
				: null
		}
	},
	data() {
		return {
			top: null,
			left: null,
			show: false,
			data: null,
			option: null,
			showChildOne: false,
			menuList: this.menu,
			menuLevelOne: [],
			menuItems: []
		}
	},
	mounted() {
		if (this.closeOnScroll) {
			this.addScrollEventListener()
		}
	},

	beforeDestroy() {
		if (this.closeOnScroll) {
			this.removeScrollEventListener()
		}
	},
	methods: {
		/**
		 * Add scroll event listener to close context menu.
		 */
		addScrollEventListener() {
			window.addEventListener('scroll', this.close)
		},
		/**
		 * Close the context menu.
		 */
		close(emit = true) {
			if (!this.show) {
				return
			}
			this.top = null
			this.left = null
			this.show = false
			if (emit) {
				this.$emit('close')
			}
			this.$refs.menuChildOne.style.top = null
			this.$refs.menuChildOne.style.left = null
			this.showChildOne = false
		},
		/**
		 * Close the menu if `closeOnClick` is set to true.
		 */
		onClickList(e) {
			if (this.menuList[e.target.id - 1]) {
				if (this.menuList[e.target.id - 1].items != null) {
					this.menuLevelOne = this.menuList[e.target.id - 1].items
					this.showChildOne = true
				} else {
					this.menuLevelOne = []
					this.showChildOne = false
					if (this.closeOnClick && (e.type != 'mouseover')) {
						this.close(true)
					}
				}

				var items = document.getElementsByClassName('v-context')[0].children[0].children
				for (var i = 0; i < items.length; ++i) {
					if (items[i].id == e.target.id) {
						var rectDim = items[i].getBoundingClientRect()
					}
				}

				let left = rectDim.left + rectDim.width
				let top = rectDim.top
				let right = null
				let winheight = window.innerHeight
				let winwidth = window.innerWidth
				// For repositioning the context Menu according to the space available

				this.$refs.menuChildOne.style.top = top + 'px'
				this.$refs.menuChildOne.style.left = (left + 5) + 'px'
				this.$refs.menuChildOne.style.right = null
				if (left + rectDim.width > winwidth) {
					right = winwidth - (left - rectDim.width) // - (rectDim.width + 10 + rectDim.width);
					this.$refs.menuChildOne.style.left = null
					this.$refs.menuChildOne.style.top = top + 'px'
					this.$refs.menuChildOne.style.right = (right + 5) + 'px'
				}
			}
		},

		/**
		 * Open the context menu.
		 */
		open(event) {
			this.show = true
			this.menuItems = this.menuList
			for (let i = 0; i < this.menuList.length; i++) {
				if (this.menuList[i].items != null) {
					this.menuItems[i]['hasChild'] = true
				}
			}
			this.$nextTick(() => {
				this.positionMenu(event.clientY, event.clientX)
				this.$el.focus()
				this.$emit('open', event, this.top, this.left)
			})
		},
		/*
		 * Set the context menu top and left positions
		 */
		positionMenu(top, left) {
			let height = window.innerHeight
			let width = window.innerWidth
			// For repositioning the context Menu according to the space available
			if (left + 205 < width) {
				this.top = top
				this.left = left
			} else {
				this.top = top
				this.left = left - 205
			}
			// Here 28 is fixed height of context Menu Items
			let listHeight = 28 * Object.keys(this.menuList).length
			if (top + listHeight > height) {
				this.top = top - listHeight
			}
		},
		/*
		 * Remove the scroll event listener to close the context menu.
		 */
		getContextMenu(menuName, param) {
			let cmHeight = this.$refs[menuName].getBoundingClientRect()
			if (param == 'width') {
				return cmHeight.width
			} else if (param == 'height') {
				return cmHeight.height
			} else if (param == 'left') {
				return cmHeight.left
			} else if (param == 'right') {
				return cmHeight.right
			} else if (param == 'bottom') {
				return cmHeight.right
			}
		},

		removeScrollEventListener() {
			window.removeEventListener('scroll', this.close)
		}
	},
	watch: {
		/**
		 * Add or remove the scroll event listener when the prop value changes.
		 *
		 * @param {boolean} value
		 * @param {boolean} oldValue
		 */

		closeOnScroll(value, oldValue) {
			if (value === oldValue) {
				return
			}
			if (value) {
				this.addScrollEventListener()
			} else {
				this.removeScrollEventListener()
			}
		}
	}
}
</script>

<style lang="scss" >
.v-context,
.v-contextChildOne {
	background: #fff;
	border: 1px solid #bdbdbd;
	box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
		0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
	display: block;
	margin: 0;
	padding: 0;
	position: fixed;
	min-width: 200px;
	z-index: 99999;
	ul {
		list-style: none;
		padding: none;
		position: none;
		margin: 0;
		font-size: 16px;
		li {
			margin: 0;
			text-align: left;
			padding: 5px 5px 5px 12px;
			cursor: pointer;
			.navIcon {
				float: right;
			}
			&:hover {
				background: rgb(233, 233, 233);
			}
			span {
				float: right;
				width: 20px;
				text-align: right;
			}
		}
	}
}
</style>
