import { BasicContainer } from '/sd:basic-container.js'; 
import { HoverableField } from '/sd:hoverable-field.js'; 
/**
 * class to create instance of context menu. It allows for define container and all context menu positions defined in XML file
 * it needs to define left mouse button actions in window['objId']['localName'], where objId is ContextMenu instance name, and localName are names of all defined in XML ContextMenu options
 */
export class ContextMenu extends BasicContainer {	
	/**
	 * Constructor
	 * @param {jQuery} xmlObject    			Data loaded from XML- contextMenu part supported only
	 * @param {String} parentNode    			Parent node ID of creating contextMenu - it should be the same as HTML body markup ID, "site" as a default
	 * @param {String} objId    				ID of creating contextMenu - it need to be the same as markup in XML file, "contextMenu" as a default
	 * @param {String} optionsClassName 		CSS	class name for each option (position) of context Menu - for hover state CSS class name needs to have prefix equal to optionsClassName and suffix "Selected"
	 * @param {Array(String)} keys				Array of all keys of context menu options types supported by inited context menu 
	 * @param {Array(String)} lmbClickActions	Array of left mouse button click actions of all context menu options
	 */
	constructor(xmlObject, parentNode = "site", objID = "contextMenu", optionsClassName = "ContextMenu", keys = ["event", "field"], lmbClickActions) {
		super(null, parentNode, "BasicContainer", null, objID + "Container", true); 
		this.contextMenuOptionsDestiny = {};
		this.keys = keys;
		this.objID = objID + "Container";
		this.options = new Array();
		this.visibility = false;
		//height of one single option in Context Menu
		this.singleOptionHeight = "24px";

		var count = Math.round(xmlObject[0].attributes['count'].value);
		var objPointer = null;
		var localName = null;
		var markup = null;
		var attributes = null
		//for each defined options
		for(var i = 0; i < count; i++) {
			localName = xmlObject[0].children[i].attributes['id'].value;
			//add next option to Context Menu
			objPointer = new HoverableField(xmlObject[0].children,
				 this.objID,
				  optionsClassName,
				   optionsClassName + "Selected",
				    "window['" + objID + "'].invokeMouseMoveOnOption(" + String(i) +")",
					  "window['" + objID + "'].invokeMouseLeaveOnOption(" + String(i) +")",
					    lmbClickActions[i] + "window['" + objID + "'].setVisibility(false, 'field');return false;",
					    "window['" + objID + "'].setVisibility(false, 'event');",
						 "window['" + objID + "']['" + localName + "'];return false",
						  null,
						   localName);
			window[localName] = objPointer;
			objPointer.setTextValue(window.choosenLexicon.getLexiconMarkupText(xmlObject[0].children[i].localName));
			attributes = xmlObject[0].children[i].attributes;
			
			for(var j = 0; j < attributes.length; j++) {
				markup = attributes[j].localName;
				if(markup != "label") {
					if(this.contextMenuOptionsDestiny[markup] == undefined)
						this.contextMenuOptionsDestiny[markup] = new Array();
					this.contextMenuOptionsDestiny[markup].push(localName);
				}
			}
			this.options.push(objPointer);
			this.mainObj.appendChild(this.options[i].mainObj);
		}
	}

	/**
	 * Adjusts Context Menu container height, to current amount of options
	 * @param {String} type 	Choosed key type ("event" or "field") of showed Context Menu
	 */
	adjustContainerHeight(type) {
		var heightValue = this.singleOptionHeight.replace(/[pxctmin;% ]/g,'');
		var heightUnit = this.singleOptionHeight.replace(/[1234567890; ]/g,'');
		for(var i = 0; i < this.keys.length; i++) {
			if(type == this.keys[i]) {
				this.setStyleValue("height", String(parseFloat(this.contextMenuOptionsDestiny[this.keys[i]].length) * parseFloat(heightValue)) + heightUnit);
			}
		}
	}

	/**
	 * Moves Contex Menu container to indicated position (dedicated for mosuse position capturing)
	 * @param {Integer} X 	X position, where Context Maenu has to be moved
	 * @param {Integer} Y 	Y position, where Context Maenu has to be moved
	 */
	adjustContainerPosition(X, Y) {
		document.getElementById(this.objID).style.setProperty("left", X);
		document.getElementById(this.objID).style.setProperty("top", Y);
	}
	
	/**
	 * Gets visibility status of the ContextMenu 
	 * @returns {Boolean}	True if ContextMenu is shown, false if it is hidden
	 */
	getVisibility() {
		return this.visibility;
	}

	/**
	 * Invokes predefined action "onclick" of the selected option menu
	 * @param {Integer} index 	Index of clicked option in Context Menu
	 */
	invokeMouseLeaveOnOption(index) {
		this.options[index].mouseLeaveAction();
	}

	/**
	 * Invokes predefined action "onmouseover" of the selected option menu
	 * @param {Integer} index 	Index of option, which mouse moved on, in Context Menu
	 */
	invokeMouseMoveOnOption(index) {
		this.options[index].mouseMoveAction();
	}
	
	/**
	 * Sets visibility of Context Menu and move it to proper (X,Y) position
	 * @param {Boolean} value		If true then ContextMenu is shown, if false it is hidden 
	 * @param {String} type			Name of type context menu - it needs to be the same one of markups defined in XML file in context menu options (positions) 
	 */
	setVisibility(value, type) {
		this.visibility = value;
		//options of ContextMenu
		for(var i = 0; i < this.keys.length; i++) {
			for(var j = 0; j < this.contextMenuOptionsDestiny[this.keys[i]].length; j++) {
				document.getElementById(this.contextMenuOptionsDestiny[this.keys[i]][j]).style.setProperty("display", "none");
			}
		}
		if(value) {	//show
			//ContextMenuContainer
			document.getElementById(this.objID).style.setProperty("display", "block");
			//options of ContextMenu
			for(var i = 0; i < this.keys.length; i++) {
				if(type == this.keys[i]) {
					for(var j = 0; j < this.contextMenuOptionsDestiny[this.keys[i]].length; j++) {
						document.getElementById(this.contextMenuOptionsDestiny[this.keys[i]][j]).style.setProperty("display", "block");
					}
				}
			}
			this.adjustContainerHeight(type);
			this.adjustContainerPosition(window.event.clientX, window.event.clientY);
		}
		else {	//hide
			//ContextMenuContainer
			document.getElementById(this.objID).style.setProperty("display", "none");
		}
	}
}

window.ContextMenu = ContextMenu;