var ContextMenu = new class ContextMenu {
	elements: {
		menu: HTMLDivElement;

		items: {
			copy: HTMLDivElement;
			paste: HTMLDivElement;
			cut: HTMLDivElement;
			ghost: HTMLDivElement;
			osc: HTMLDivElement;
			http: HTMLDivElement;
		};
	};

	open: boolean;
	contextHolder: HTMLElement;

	constructor() {
		this.elements = {
			menu: document.querySelector('.contextmenu'),
			items: {
				copy: document.querySelector('.contextmenu').querySelector('.copy'),
				paste: document.querySelector('.contextmenu').querySelector('.paste'),
				cut: document.querySelector('.contextmenu').querySelector('.cut'),
				ghost: document.querySelector('.contextmenu').querySelector('.ghost'),
				osc: document.querySelector('.contextmenu').querySelector('.osc'),
				http: document.querySelector('.contextmenu').querySelector('.http')
			}
		};

		this.open = false;
		this.contextHolder = null;

		window.addEventListener('contextmenu', (ev: MouseEvent) => this.handle(this.elements.menu, ev));
		window.addEventListener('mousedown', (ev: MouseEvent) => {
			if (this.open == true)
				if (ev.target) {
					var target = ev.target as HTMLElement;

					if (
						target.classList.contains('contextmenu') ||
						(target.parentElement != undefined && target.parentElement.classList.contains('contextmenu'))
					) {
					} else {
						this.close();
					}
				} else this.close();
		});
	}

	setItems(items: DropdownItemTypes[]) {
		for (var type in this.elements.items) {
			if (items.includes(<DropdownItemTypes>type)) this.elements.items[type].style.display = 'block';
			else this.elements.items[type].style.display = 'none';
		}
	}

	close() {
		this.elements.menu.style.display = 'none';
		if (this.contextHolder != null) {
			this.contextHolder.classList.remove('context');
			this.contextHolder = null;
		}
		this.open = false;
	}

	handle(menu: HTMLDivElement, ev: MouseEvent) {
		if (ev.target != undefined) {
			var target = ev.target as HTMLElement;

			var types = {
				key: (element: HTMLElement) => {
					if (element.hasAttribute('x') && element.hasAttribute('y')) {
						var keyX = element.getAttribute('x');
						var keyY = element.getAttribute('y');

						var items: DropdownItemTypes[] = [
							'osc',
							'http'
						];
						if (PageHandler.currentPage.keys[keyY][keyX].state.type != 'empty') items.push('copy', 'cut');
						if (PageHandler.currentPage.keys[keyY][keyX].state.type == 'custom') items.push('ghost');
						if (UndeckedClipboard.hasKeyInClipboard()) items.push('paste');

						this.setItems(items);

						this.elements.items.copy.onclick = () => {
							UndeckedClipboard.copyKey(parseInt(keyX), parseInt(keyY));
							this.close();
						};

						this.elements.items.cut.onclick = () => {
							UndeckedClipboard.cutKey(parseInt(keyX), parseInt(keyY));
							this.close();
						};

						this.elements.items.paste.onclick = () => {
							UndeckedClipboard.pasteKey(parseInt(keyX), parseInt(keyY));
							this.close();
						};

						this.elements.items.ghost.onclick = () => {
							UndeckedClipboard.copyGhostKey(parseInt(keyX), parseInt(keyY));
							this.close();
						};

						return items.length > 0;
					}
				}
			};

			for (var type in types)
				if (target.classList.contains(type)) {
					ev.preventDefault();

					var valid = types[type](target);

					if (valid) {
						this.contextHolder = target;
						target.classList.add('context');

						setTimeout(() => {
							this.open = true;
						}, 100);

						menu.style.left = `${ev.pageX}px`;
						menu.style.top = `${ev.pageY - 50}px`;
						menu.style.display = 'block';
					}

					return;
				}
		}
	}
}();

type DropdownItemTypes = 'copy' | 'paste' | 'cut' | 'ghost' | 'osc' | 'http';
