
import { SelectableField } from '/sd:selectable-field.js'; 
import { ModbusRequestContainer } from '/sd:modbus-request-container.js'; 
import { Point } from '/sd:point.js';
import { Debug } from '/sd:debug.js'; 

/**
 * class to create instance of Selectable Field. It allows for define field which reacts on Left Mouse Button ("onclick" attribute), and Right Mouse Button ("oncontextmenu" attribute). The field change class if it is selected.
 */
export class EventField extends SelectableField {	
	/**
	 * Constructor
	 * @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} fieldMainClass    	Name of the main CSS style's class
	 * @param	 {String} lmbClickAction		This value is insert inside of onclck="" attribute of HTML field (lmb prefix means Left Mouse Button)
	 * @param	 {String} rmbClickAction		This value is insert inside of oncontextmenu="" attribute of HTML field (rmb prefix means Right Mouse Button)
	 * @param	 {String} selectFunction		This value is insert inside of oncontextmenu="" and onlick="" function supporting unselecting and selecting field
	 * @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    {Collection} valueAttributes 	Collection of event value attributes {"unit": "", "scale": 1.0, "floatSeparator": "dot", "enum": "", "falseText": "", "trueText": ""}
	 * @param 	 {jQuery} enumsDefXmlObject     Data loaded from XML - accept enums definition part only
	 */
	constructor(xmlObject, parentId, fieldMainClass, lmbClickAction = null, rmbClickAction = null, selectFunction = null, itemNumber = null, objId = null, valueAttributes = null, enumsDefXmlObject) {
		super(xmlObject, parentId, fieldMainClass, lmbClickAction, rmbClickAction, selectFunction, itemNumber, objId, false);
		this.point = new Point("unknown", null, null, valueAttributes.scale, valueAttributes.unit, valueAttributes.floatSeparator, valueAttributes.enum, enumsDefXmlObject, null, valueAttributes.falseText, valueAttributes.trueText);
		this.default = true;
		this.startTime = 1500;
		this.stopTime = 1500;
		this.modbusValue = [{"name": "Reg1", "value": 0x85A0}, {"name": "Reg2", "value": 0}];
	}
	
	/**
	 * Bubble sorting of EventFileds Array
	 * @param {Array} dayEvents 		Array of EventField class instances 
	 * @param {Integer} eventsPerDay 	Defined amount of EventField
	 * @returns 
	 */
	static bubbleSortEvents(dayEvents, eventsPerDay) {
		var swapped, anyChange = false;
		var len = eventsPerDay;
		//check if first
		//sort array
		do
		{
			swapped = false;
			for(var i = 1; i < eventsPerDay; i++) {
				if(dayEvents[i - 1].getStartTime() > dayEvents[i].getStartTime()) {
					dayEvents[i - 1].replaceEvent(dayEvents[i]);
					//swap event start time
					swapped = true;
					anyChange = true;
				}
			}
			len--;
		}while(swapped);
		return anyChange;
	}

	/**
	 * Sorts all events in single day
	 * @param {Array} dayEvents 
	 * @param {Integer} eventsPerDay 
	 * @param {Integer} eventsPerDayMax 
	 * @param {Boolean} sendAllEvenIfNotSorted 
	 */
	static dayEventsSorting(dayEvents, eventsPerDay, eventsPerDayMax, sendAllEvenIfNotSorted=false) {
		if(EventField.bubbleSortEvents(dayEvents, eventsPerDay) || sendAllEvenIfNotSorted) {
			EventField.sendMultipleEventsByModbus([dayEvents], 0, 0, 0, (eventsPerDay - 1), eventsPerDay);
			/*for(var j = 0; j < eventsPerDayMax; j++) {
				dayEvents[j].sendCurrentValuesByModbus();
			}*/
		}
	}

	/**
	 * Checks if startTime and stopTime overlaps on existed event
	 * @param {Array(EventField)} dayEvents 	Array of evants in selected day
	 * @param {Integer} eventIndex	 			Event index, wich has to be excluded from the checking
	 * @param {Integer} eventsPerDay 			Events count in the day
	 * @param {Integer} startTime 				Start time of new event
	 * @param {Integer} stopTime 				Stop time of new event
	 * @returns {Integer}						index of event which time is overlapsed by new time range; -1 if it doesn't overlap
	 */
	static checkTimeOverlapsOnNotDefaultEvent(dayEvents, eventIndex, eventsPerDay, startTime, stopTime) {
		for(var i = 0; i < eventsPerDay; i++) {
			if(i != eventIndex && dayEvents[i].getDefault() == false && ((dayEvents[i].getStartTime() <= startTime && dayEvents[i].getStopTime() > startTime) || (dayEvents[i].getStartTime() < stopTime && dayEvents[i].getStopTime() >= stopTime) || (dayEvents[i].getStartTime() >= startTime && dayEvents[i].getStopTime() <= stopTime))) {
				console.log("New time range overlaps on event index: " + String(i));
				return i;
			}
		}
		return -1;
	}

	/**
	 * Decodes startTime and default (and current value for boolean type of event) from this.modbusValue[0].value, which is binded with Modbus Register, and if event is "numeric" or "enum" it also decodes value from this.modbusValue[1].value
	 */
	decodeModbusValues() {
		var register1Value = parseInt(this.modbusValue[0].value);
		this.setDefault((register1Value & 0x8000) > 0);
		if(this.getPointType() == "boolean") {
			this.setStartTime(register1Value & 0x3FFF);
			this.point.setValue(((register1Value & 0x4000) > 0) ? true : false);
		}
		else {
			this.setStartTime(register1Value & 0x7FFF);
			this.point.setValue((this.getPointType() == "numeric") ? parseFloat(this.modbusValue[1].value) * this.getScale() : parseInt(this.modbusValue[1].value));
		}
		//if start time is higher than 23:59
		if(this.getStartTime() >= 1440)
			this.setStopTime(1500);
	}
	

	/**
	 * Deletes any default event, which are duplicates
	 * @param {Array} allDayEvents 		Array of EventField objects in sepecific day
	 * @param {Integer} eventsPerDay 	Count of events per day
	 * @param {String} type				Type of the schedule
	 * @returns {Boolean}				True if there was any change, and false if not
	 */
	static deleteDuplicateEvents(allDayEvents, eventsPerDay, type) {
		var reorder = false;
		//sort events in day
		EventField.bubbleSortEvents(allDayEvents, eventsPerDay);
		//find event to delete
		for(var i=1; i < (eventsPerDay); i++) {
			if(allDayEvents[i - 1].getStartTime() == 1500) {
				break;
			}
			if((allDayEvents[i - 1].getDefault() && allDayEvents[i - 1].getStartTime() < 1500) && (allDayEvents[i - 1].getStartTime() == allDayEvents[i].getStartTime())) {//delete
				reorder = EventField.setEvent(allDayEvents, (i - 1), eventsPerDay, 1500, 1500, true, 0, type);
			}
			else if((allDayEvents[i].getDefault() && allDayEvents[i].getStartTime() < 1500) && (allDayEvents[i - 1].getStartTime() == allDayEvents[i].getStartTime())) { // delete
				reorder = EventField.setEvent(allDayEvents, i, eventsPerDay, 1500, 1500, true, 0, type);
			}
		}
		return reorder;
	}

	/**
	 * Looking on all available events, how much of them are default and free to use
	 * @param {Array} events 			Array of EventField
	 * @param {Integer} eventsPerDay 	max events
	 * @param {Integer} newStartTime 	Start Time of verified new event
	 * @param {Integer} newEndTime 		End time of verified new event
	 * @returns {Integer}				Quantity of free to use default 
	 */
	static freeEventsQuantity(events, eventsPerDay, newStartTime=null, newEndTime=null) {
		var quantity = 0;
		for(var i = 0; i < eventsPerDay; i++) {
			if(events[i].getDefault() && ((events[i].getStartTime() == 1500) || (events[i].getStartTime() == newStartTime && events[i].getStopTime() == newEndTime))) {
				quantity++;
			}
		}
		return quantity;
	}

	/**
	 * Searches first default event (even if it is used as space between 2 used events) in array of EventField
	 * @param {Array} events 		Array of EventField objects
	 * @param {Integer} startIndex 	Index which will be veryfied as a first - no indexes before this value will be checked
	 * @returns {Integer}			Returns index of first default event or -1 if there is no free default events
	 */
	static findFirstDefaultEvent(events, startIndex=0) {
		for(var i = startIndex; i < events.length; i++) {
			if(events[i].getDefault()) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Searches first free (startTime is equal to 1500 or (startTime and endTime are equal to newStartTime and newEndTime)) and default event in array of EventField
	 * @param {Array} events 			Array of EventField objects
	 * @param {Integer} startIndex 		Index which will be veryfied as a first - no indexes before this value will be checked
	 * @param {Integer} newStartTime	New Start Time
	 * @param {Integer} newEndTime		New End time
	 * @returns {Integer}				Returns index of first free default event or -1 if there is no free default events
	 */
	static findFirstFreeDefaultEvent(events, startIndex=0, newStartTime, newEndTime) {
		for(var i = startIndex; i < events.length; i++) {
			if(events[i].getDefault() && ((events[i].getStartTime() == 1500) || (events[i].getStartTime() == newStartTime && events[i].getStopTime() == newEndTime))) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Searches the clostest (TimeRange) and default event in array of EventField
	 * @param {Array} events 			Array of EventField objects
	 * @param {Integer} newStartTime	New Start Time
	 * @returns {Integer}				Returns index of the clostest free default event or -1 if the clostest is no default event
	 */
	static findTheClostestDefaultEvent(events, newStartTime) {
		for(var i = 0; i < events.length; i++) {
			if(events[i].getDefault() && ((events[i].getStartTime() <= newStartTime) && events[i].getStopTime() >= newStartTime)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Gets event number of day
	 * @returns {Integer}	Day number
	 */
	getDayOfWeek() {
		return parseInt(this.id.substring(12, 13));
	}

	/**
	 * Gets decimal places
	 * @returns {Integer}	Day number
	 */
	getDecimlPlaces() {
		return this.point.getDecimlPlaces();
	}

	/**
	 * Gets default state
	 * @returns {Boolean}	Default value
	 */
	getDefault() {
		return this.default;
	}

	/**
	 * Returns index of events with defined startTime, stopTime and default value
	 * @param {Array} allDayEvents 		Array of all events in the single day
	 * @param {Integer} eventsPerDay 	Events count per day
	 * @param {Integer} startTime 		Searching startTime
	 * @param {Integer} stopTime  		Searching stopTime
	 * @param {Boolean} def 		 	Searching default value
	 * @returns {Integer}				Event index or -1 if no event meets the criteria
	 */
	static getEventIndexByValues(allDayEvents, eventsPerDay, startTime, stopTime, def) {
		for(var i=0; i < eventsPerDay; i++) {
			if(allDayEvents[i].getStartTime() == startTime && allDayEvents[i].getStopTime() == stopTime && allDayEvents[i].getDefault() == def) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * Gets false text value
	 * @returns {String}	False text of the point
	 */
	getFalseText() {
		return this.point.getFalseText();
	}
	
	/**
	 * Gets starting Modbus register address of EventField
	 * @returns {Integer}		Register address
	 */
	getModbusRegisterAddress() {
		return this.point.getModbusRegisterAddress();
	}
	
	/**
	 * Gets type of the point
	 * @returns {String}		Type of the point ("numeric", "enum", "boolean" or "unknown")
	 */
	getPointType() {
		return this.point.getPointType();
	}
	
	/**
	 * Gets scale of the numeric point
	 * @returns {Float}		Scale value
	 */
	getScale() {
		return this.point.getScale();
	}

	/**
	 * 
	 * @returns Gets start time of the event
	 * @returns {Integer}		Start time value - sum of hour in range <0-23> multiplied by 60, and minutes (MIN 0 MAX value is 1440 if equal to 1500 then it means that event is default)
	 */
	getStartTime() {
		return parseInt(this.startTime);
	}

	/**
	 * Gets current state of the event
	 * @returns {Boolean}	Current state of the event
	 */
	getState() {
		return this.point.getState();
	}

	/**
	 * Gets start time of the event
	 * @returns {Integer}		Start time value - sum of hour in range <0-23> multiplied by 60, and minutes (MIN 0 MAX value is 1440 if equal to 1500 then it means that event is default)
	 */
	getStopTime() {
		return parseInt(this.stopTime);
	}
	
	/**
	 * Gets true text value
	 * @returns {String}	True text of the point
	 */
	getTrueText() {
		return this.point.getTrueText();
	}
	
	/**
	 * Gets unit of the numeric point
	 * @returns {String}	Unit of the numeric point
	 */
	getUnit() {
		return this.point.getUnit();
	}
	
	/**
	 * Gets current value of the event field
	 * @returns {Object} 	Value of the numeric point
	 */
	getValue() {
		return this.point.getValue();
	}

	/**
	 * Gets value, which is able to send over Modbus TCP
	 * @returns {Integer}	Coded/Rescaled value to send over Modbus TCP
	 */
	getValueToSendOverModbusTcp() {
		var result = Array();
		var objPointer = (this.getStartTime() & 0x3FFF) | (Math.round(this.getDefault()) << 15);
		if(this.getDefault() == true)
			objPointer |= 0x8000;
		if(this.getPointType() == "numeric"|| this.getPointType() == "enum") {
			result.push(objPointer);
			objPointer = this.point.getValueToSendOverModbusTcp();
			result.push(objPointer);
		}
		else if(this.getPointType() == "boolean") {
			if(!this.getDefault()) {
				objPointer |= (this.getValue() == true) ? 0x4000 : 0x0000;//if true then 14-bit true
			}
			result.push(objPointer);
		}
		else {
			console.log("EventField: getValueToSendOverModbusTcp(): scheduler type " + String(this.getPointType()) + " not supported!");
			return null;
		}
		return result;
	}
	
	/**
	 * Gets current value multiplied by scale fixed to decimalPlaces, with replaced floatSeparator with unit (or true/false text or Enum Label) of the event field
	 * @returns {String} 	Value of the event field
	 */
	getValueWithFacets() {
		return this.point.getValueWithFacets();
	}

	/**
	 * Removes Modbus register address of EventField
	 * @param {ModbusRequestContainer} modbusRequestContainer    	ModbusRequestContainer instance, where the register was inited 
	 */
	removeModbusRegisterAddress(modbusRequestContainer) {
		if(this.getModbusRegisterAddress() != null) {
			this.point.removeModbusRegisterAddress(modbusRequestContainer);
			this.modbusValue[0].value = 0x85DC;//Default MSB and 1500 value
		}
	}

	/**
	 * Replaces this event with event from argument
	 * @param {FieldEvent} event 	Choosen event to replace with this event
	 */
	replaceEvent(event) {
		var temp;
		//default
		temp = this.getDefault();
		this.setDefault(event.getDefault());
		event.setDefault(temp);
		//startTime
		temp = this.getStartTime();
		this.setStartTime(event.getStartTime());
		event.setStartTime(temp);
		//stopTime
		temp = this.getStopTime();
		this.setStopTime(event.getStopTime());
		event.setStopTime(temp);
		//type
		temp = this.getPointType();
		this.setPointType(event.getPointType());
		event.setPointType(temp);
		//value
		temp = this.getValue();
		this.point.setValue(event.getValue());
		event.point.setValue(temp);
	}

	/**
	 * Sends this event value, default state and startTime over Modbus TCP
	 */
	sendCurrentValuesByModbus() {
		var registers = this.getValueToSendOverModbusTcp();
		console.groupCollapsed("sendCurrentValuesByModbus()");
		var decAddr = new Array;
		for(var j=0; j < registers.length; j++) {
			decAddr[j] = this.getModbusRegisterAddress() + j;
		}
		ModbusRequestContainer.sendValuesOverModbusTcp(decAddr, registers);
		console.groupEnd();
	}

	/**
	 * Sends multiple events of multiple days by Modbus to device
	 * @param {Array(Array(EventField))} daysEvents 	2 dimensional array of events in days of week
	 * @param {Integer} startDayIndex 					Start index of choosen days - not less than 0, and lower or equal to endDayIndex
	 * @param {Integer} endDayIndex 					End index of choosen days - not less than startDayIndex, and less than 7
	 * @param {Integer} startEventIndex 				Start index of choosen events in day - not less than 0, and lower or equal to endEventIndex
	 * @param {Integer} endEventIndex					End index of choosen events in day not less than startEventIndex, and less than maxEventsCount
	 * @param {Integer} maxEventsCount					Max count of events per day
	 */
	static sendMultipleEventsByModbus(daysEvents, startDayIndex, endDayIndex, startEventIndex, endEventIndex, maxEventsCount) {
		//Criterias
		if(startDayIndex > endDayIndex) {
			console.log("startDayIndex is greater than endDayIndex - action declined!!!");
			return false;
		}
		if(startDayIndex < 0 ) {
			console.log("startDayIndex is lower than 0 - action declined!!!");
			return false;
		}
		if(endDayIndex >= 7 ) {
			console.log("endDayIndex is grater or equal 7 - action declined!!!");
			return false;
		}
		if(startEventIndex > endEventIndex) {
			console.log("startEventIndex is greater than endEventIndex - action declined!!!");
			return false;
		}
		if(startEventIndex < 0 ) {
			console.log("startEventIndex is lower than 0 - action declined!!!");
			return false;
		}
		if(startEventIndex >= maxEventsCount ) {
			console.log("startEventIndex is grater or equal maxEventsCount - action declined!!!");
			return false;
		}
		//Logic
		var registers;
		var request = new Array();
		var values = new Array();
		var addresses = new Array();
		//for each day
		for(var day = startDayIndex; day <= endDayIndex; day++) {
			//for each event
			for(var event = startEventIndex; event <= endEventIndex; event++) {
				registers = daysEvents[day][event].getValueToSendOverModbusTcp();
				for(var j=0; j < registers.length; j++) {
					request.push({action: "set", what: "mbt", id: (daysEvents[day][event].getModbusRegisterAddress() + j), val: registers[j]});
					addresses.push(daysEvents[day][event].getModbusRegisterAddress() + j);
					values.push(registers[j]);
				}
			}
		}
		Debug.traceTable(["value", "decimalAddress"], [values, addresses], "Send " + String(request.length) + "x values into Holding Registers");
		ModbusRequestContainer.sendRequestToDevice(request, null, null, "Sending " + String(request.length) + "x values into Holding Registers error", null, true);
		return true;
	}

	/**
	 * Selects the field and changes CSS class to selected class
	 * @override 
	 */
	selectField() {
		this.setStyleValue("border", "1px solid #EEAE2B");
		this.selected = true;
	}

	/**
	 * Sets decimal places
	 * @param {Integer} value 	Value between 0 and 3
	 * @returns {Boolean}		True if value was set, False if not.
	 */
	setDecimalPlaces(value) {
		return this.point.setDecimalPlaces(value);
	}

	/**
	 * Sets default
	 * @param {Boolean} value 	New default value
	 */
	setDefault(value) {
		this.default = value;
	}

	/**
	 * Sets all basic paraneters to chosen event
	 * @param {Array(EventField)} dayEvents 	Array of all events in the day
	 * @param {Integer} index 					Index of edited event
	 * @param {Integer} eventsCount 			Max count of events
	 * @param {Integer} startTime 				New startTime <0;1500>
	 * @param {Integer} stopTime 				New stopTime <0;1500>
	 * @param {Boolean} def 					New default valu
	 * @param {Object} value 					New value
	 * @param {String} type						Type of event
	 * @returns {Boolean}						True if event was able to set; False ifindex is higher than events count
	 */
	static setEvent(dayEvents, index, eventsCount, startTime=null, stopTime=null, def=null, value=null, type="numeric") {
		if(index < eventsCount) {
			if(startTime != null) {
				dayEvents[index].setStartTime(startTime);
			}
			if(stopTime != null) {
				dayEvents[index].setStopTime(stopTime);
			}
			if(def != null)
				dayEvents[index].setDefault(def);
			if(value != null) {
				if(type != "boolean")
					dayEvents[index].setValue(value);
				else
					dayEvents[index].setState(value);
			}
			Debug.traceTable(["value", "type", "startTime", "stopTime", "def"], [value, type, startTime, stopTime, def], "event[" + String(index) + "].setEvent(...)");
			return true;
		}
		else 
			return false;
	}
	
	/**
	 * Sets starting Modbus register address of EventField
	 * @param {ModbusRequestContainer} modbusRequestContainer    	ModbusRequestContainer instance, where the register will be inited 
	 * @param {Integer} address										New starting Modbus register address
	 * @returns {Boolean} 											True if new address is in the range of AAC20 Modbus register addresses; False if new address is out of range AAC20 Modbus register addresses
	 */
	setModbusRegisterAddress(modbusRequestContainer, address) {
		var reg2 = true;
		if(this.getPointType() == "numeric" || this.getPointType() == "enum") {
			modbusRequestContainer.removeRegister(address + 1);
			if(address >= 1000 && address < 2999) {
				modbusRequestContainer.initRegister(address + 1, this.modbusValue[1], "int", "all", null, "object");
				reg2 = true;
			}
			else
				reg2 = false;
		}
		if(reg2)
			var reg1 = this.point.setModbusRegisterAddress(modbusRequestContainer, address, this.modbusValue[0], "int", "all", null, "object");
		return (reg1 && reg2);
	}

	/**
	 * Sets new scheduler type information for event
	 * @param {String} type 		New type of scheduler - it mus be equal to "numeric", "boolean", "enum" or "unknown"
	 * @returns {Boolean} 			True if type was "numeric", "boolean", "enum" or "unknown"; False in other cases; 
	 */
	setPointType(type) {
		return this.point.setPointType(type);
	}

	/**
	 * Sets start time in Event
	 * @param {Integer} stopTime	Value in range <0, 1440> and 1500
	 * @returns {Boolean} 			True if input value is in range <0, 1440>, and it was set; False if value is out of range and it wasn't set 
	 */
	setStartTime(startTime=0) {
		if(startTime >= 0 && startTime <= 1440 || startTime == 1500) {
			this.startTime = (startTime == 1440) ? 1500 : startTime;
			return true;
		}
		else
			return false;
	}

	/**
	 * Sets stop time in Event
	 * @param {Integer} stopTime	Value in range <0, 1440> and 1500
	 * @returns {Boolean} 			True if input value is in range <0, 1440>, and it was set; False if value is out of range and it wasn't set 
	 */
	setStopTime(stopTime=1500) {
		if(stopTime >= 0 && stopTime <= 1440 || stopTime == 1500) {
			this.stopTime = (stopTime == 1440) ? 1500 : stopTime;
			return true;
		}
		else
			return false;
	}
	
	/**
	 * Sets state - it is saved in current state value
	 * @param {Boolean} value 	Value to set
	 */
	setState(value) {
		this.point.setState(value);
	}
	
	/**
	 * Sets current value as a text to HTML object 
	 * @override
	 */
	setTextValue() {
		if(this.mainObj != "") {
			this.mainObj.innerHTML = (this.getValue() == null) ? String(this.getValue()) : this.getValueWithFacets();
		}
	}
	
	/**
	 * Sets value - it is saved in current value
	 * @param {Object} value 	Value to set
	 */
	setValue(value) {
		this.point.setValue(value);
		this.setTextValue();
	}

	/**
	 * Unselects the field and changes CSS class to main class
	 * @override
	 */
	unselectField() {
		this.setStyleValue("border", "1px solid #000000");
		this.selected = false;
	}

	/**
	 * Updates height of EventField HTML representation
	 */
	updateHeight() {
		if(this.getPointType() == "numeric" || this.getPointType() == "enum" || this.getPointType() == "boolean") {
			if(this.getDefault()) {
				this.setStyleValue("display", "none");
			}
			else {
				var stopTime = (this.stopTime == 1500) ? 1440 : this.stopTime;
				this.setStyleValue("top", (this.startTime * 20.0 / 60.0));
				this.setStyleValue("height", ((stopTime - this.startTime) * 20.0 / 60.0) - 2.0);
				this.setStyleValue("display", "block");
			}
		}
	}

	/**
	 * Returns index, which should be assigned to an event with providen startTime in specific day
	 * @param {Array} allDayEvents 		Array of all events in the single day
	 * @param {Integer} eventsPerDay 	Events count per day
	 * @param {Integer} startTime 		Providen startTime
	 * @returns {Integer}				Index, which shoud be assigned to an event with providen startTime in specific day
	 */
	static verifyIndexShouldBeByStartTime(allDayEvents, eventsPerDay, startTime) {
		for(var i=0; i < eventsPerDay; i++) {
			if(allDayEvents[i].getStartTime() > startTime) {
				return i;
			}
		}
		return -1;
	}
}
