
import { ThemeClass } from '/sd:theme-class.js'; 

/**
* Class to create object instance of basic container. It creates basic div container. Most of graphic widgets inherit from this class.
*/
export class BasicContainer {	
	/**
	* Constructor of the BasicContainer
	* @param    {jQuery} xmlObject    	data loaded from XML
	* @param    {String} parentId    	HTML ID of the object, which has to be a parent of constructing object
	* @param    {String} objClass    	Name of the CSS style's class
	* @param    {Integer} itemNumber    Number of object constructing item - if it is null, it means, that item is not numerable
	* @param    {String} objId    		ID of creating object - if itemNumber is not null, then itemNumber will be suffix of the ID
	* @param    {Boolean} standalone    It specifies if Container is simple (false) or referenced with object defined in XML file(true)
	* @param	{String} themeName		Name of choose theme
	*/
	constructor(xmlObject, parentId, objClass = "BasicContainer", itemNumber = null, objId = null, standalone = false, themeName=null) {
		if(objId == null) {
			var str = xmlObject.selector;
			this.id = str.split(" ").pop();
		}
		else {
			this.id = objId;
		}
		if(itemNumber != null)
			this.id += String(itemNumber);

		this.itemNumber = itemNumber;
		this.themeName = themeName;
		this.mainObj = "";
		this.parentId = parentId;
		if(this.parentId != null) {
			this.parentObj = document.getElementById(this.parentId);
			this.createObject((standalone) ? null : ((itemNumber == null) ? xmlObject[0].attributes : xmlObject[itemNumber].attributes));
			this.mainObj.setAttribute("class", objClass);
		}
	}

	/**
	 *  Converts integer time [min] and seconds to HH:MM:SS or HH:MM:SS XM time format 
	 * @param    {Integer} intTime    	Sum of the hours multiplied by 60 and minutes 
	 * @param    {Integer} seconds    	Seconds or null if you don't want seconds in the String
	 * @param    {Integer} clockMode    Clock Mode - AM/PM (if equal to 12) or 24 hours (if equal to 24)
	 * @returns  {String}				Time as a text in format HH:MM:SS or HH:MM:SS XM
	*/
	static convertIntTimeToString(intTime, seconds, clockMode) {
		if(intTime < 1440) {
			var hour_24 = Math.trunc(intTime / 60);
			var minute = intTime % 60;
		}
		else {
			var hour_24 = 0;
			var minute = 0;
		}
		//clock mode
		var hour = (clockMode == 12 && hour_24 > 11) ? hour_24 - 12 : hour_24;
		if(clockMode == 12 && hour == 0)
			hour = 12;
		//convert hour
		var str = String(hour).padStart(2, '0');
		//convert minute
		str += ":" + String(minute).padStart(2, '0');
		if(seconds != null)
			str += ":" + String(seconds).padStart(2, '0');
		//if there is 12h mode - add AM or PM suffix
		if(clockMode == 12)
			str += (hour_24 > 11) ? " PM" : " AM";
		return str;
	}

	/**
	 * Converts String time ("21:34" or "09:34 PM") to Integer time without seconds
	 * @param {String} clockMode 		Mode of clock - 12 for AM/PM or 24 for 24h mode
	 * @param {String} stringTime 		Time in format HH:mm 
	 * @returns {Integer}				Time saved as Integer in 24h convention (hour * 60 + minutes) range of this value is <0;1440>
	 */
	static convertStringTimeToInteger(clockMode, stringTime) {

		var hour=parseInt(stringTime.substring(0,2));
		var minute=parseInt(stringTime.substring(3,5));
		if(clockMode == 12) {
			var dayTime = stringTime.substring(6,8);
			if(dayTime == "PM" && hour <= 12) {
				hour += 12;
			}
			else if(dayTime == "AM" && hour == 12) {
				hour -= 12;
			}
		}
		return (hour * 60 + minute);
	}
	
	/**
	* Creates object in HTML file
	* @param    {NamedNodeMap} attributes   List of attributes of the HTML object loaded from XML 
	*/
	createObject(attributes) {
		this.mainObj = document.createElement("div");
		this.mainObj.setAttribute("id", this.id);
		if(this.parentObj != null) {
			this.parentObj.appendChild(this.mainObj);
			this.createThemeSchema();
			if(attributes != null)
				this.readAllStylesFromAttributes(attributes);
		}
	}
	
	/**
	* Ivokes request to ThemeClass object instance to load styles defined in XML file to the instance of BasicContainer
	*/
	createThemeSchema() {
		window.theme.setTheme(this.id);
	}

	/**
	 * Decodes day number from id
	 * @param 	{String} id     ID of schedule event field or hour field
	 * @returns {Integer} 		Day number (if day is Monday then returns 1, if Sunday then returns 7)
	 */
	static decodeDayNumber(id) {
		return (id != null) ? ((id.indexOf("Event") >= 0) ? parseInt(id.substring(12,13)) : parseInt(id.substring(15,16))) : null;
	}

	/**
	 * Decodes field number from hour field id
	 * @param 	{String} id     ID of schedule hour field
	 * @returns {Integer} 		Event number (if first then returns 0)
	 */
	static decodeFieldNumber(id) {
		if(id.indexOf("Event") >= 0) {
			return parseInt(id.substring(18,19));
		}
		else {
			if(String(id).length == 21)
				return parseInt(id.substring(20,21));
			else if(String(id).length == 22)
				return parseInt(id.substring(20,22));
			else {
				console.log("BasicContainer: decodeFieldNumber() - bad id!")
				return null;
			}

		}
	}
	
	/**
	 * Gets element id
	 * @returns {String}		ID
	 */
	getId() {
		return this.id;
	}
	
	/**
	* Static method gets item number of the HTML object read from its ID
	* @param    {String} id   		ID of HTML object 
	* @param    {String} prefix   	Text prefix of ID of HTML object 
	* @returns	{Integer}			Returns item number
	*/
	static getItemNumber(id, prefix) {
		var k = 0;
		for(var i = prefix.length; i < (prefix.length + 5); i++) {
			for(var j = 0; j < 10; j++)
				if(id[i] == String(j))
					break;
			if(j == 10)
				break;
			else 
				k++;
		}
		return id.substring(prefix.length, prefix.length + k);
	}
	
	/**
	* Gets CSS style value from its name
	* @param    {String} name   	Name of the CSS style
	* @returns	{String}			Returns CSS style value
	*/
	getStyleValue(name) {
		return document.getElementById(this.id).style.getPropertyValue(name);
	}
	
	/**
	* Reads all supported by ThemeClass attributes of the HTML object read from XML file, and sets them in the HTML object of the BasicContainer
	* @param    {NamedNodeMap} attributes   List of attributes of the HTML object loaded from XML 
	*/
	readAllStylesFromAttributes(attributes) {
		var availibleStylesToChangeFromXml = ThemeClass.availibleStylesToChangeFromXml();
		var availibleStylesToChangeCss = ThemeClass.availibleStylesToChangeCss();
		for(var i = 0; i < availibleStylesToChangeFromXml.length; i++) {
			if(attributes[availibleStylesToChangeFromXml[i]] != undefined) {
				this.setStyleValue(availibleStylesToChangeCss[i], attributes[availibleStylesToChangeFromXml[i]].value);
			}
		}
	}
	
	/**
	* Sets CSS style value in indicated CSS style name in the HTML object of the BasicContainer
	* @param    {String} name    Name of CSS style 
	* @param    {String} value   Value of CSS style to set 
	*/
	setStyleValue(name, value) {
		document.getElementById(this.id).style.setProperty(name, value);
	}
	
	/**
	* Removes CSS style from the HTML object of the BasicContainer
	* @param    {String} name    Name of CSS style 
	*/
	setRemoveStyle(name) {
		this.mainObj.style.removeProperty(name);
	}
}