var apikey = null;
var apiversion = 'vnd.ddel.v1';
var isFocused = false;
var curEdit = {};
var curSchedule = {};
var mon_class = "not_reachable";
var tue_class = "not_reachable";
var wed_class = "not_reachable";
var thu_class = "not_reachable";
var fri_class = "not_reachable";
var sat_class = "not_reachable";
var sun_class = "not_reachable";
var timeFormat = "12h";
var ampm = "pm";
var am_class = "not_reachable";
var pm_class = "active";
var SCHEDULES_POLL_TIME = 5000;
var gatewayDate = "";
var gatewayUTC = "";
var hourOffset = 0;
var minuteOffset = 0;
var timeOffset = 0;

// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
  hidden = "mozHidden";
  visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}

/**
 * Init touch and small displays.
 */
function schedulesInit() {
    // check if this is mobile or desktop
    // and load custom js and css files

    if (Modernizr.touch) {
        loadjscssfile("mobile.css", "css");
        isDesktop = false;
    }
    else {
        isDesktop = true;
        loadjscssfile("desktop.css", "css");
    }

    if (Modernizr.touch) {
        clickevent = "touchend";
        pointerStart = "touchstart";
        pointerEnd = "touchend";
        pointerMove = "touchmove";
    }
}

/**
 * Init the base branding of the interface.
 */
function initBranding() {

    var customBrand = false;

    var navName = "Wireless Light";

    if (customBrand) {
        var navName = "CUSTOM <span style=\"position: relative; display: inline-block; bottom: 8px;\">&reg;</span>";
        var brand = '<span class="custom-brand">' + navName + '</span>';
        $(".navbar-inner .brand").html(brand);
    }
}

/**
* Get a TimeString and when it starts with "Wddd" (d = a digit) then it returns an array with selected Weekdays.
*/
function loadRepeatedDays(time) {
	var recurring = [];
	if (time.charAt(0) == "W") {
		var days = parseInt(time.substring(time.indexOf('W')+1,time.indexOf('/')));
		var bin = days.toString(2);
		var leadingZeros = (8 - (bin.length));
		for (i=0;i<leadingZeros;i++) {bin = "0" + bin};

		// bin from utc to local
		bin =  convertWeekBitmapFromUtc(bin, time);

		if (bin[1] == '1') {recurring[recurring.length] = "mon"};
		if (bin[2] == '1') {recurring[recurring.length] = "tue"};
		if (bin[3] == '1') {recurring[recurring.length] = "wed"};
		if (bin[4] == '1') {recurring[recurring.length] = "thu"};
		if (bin[5] == '1') {recurring[recurring.length] = "fri"};
		if (bin[6] == '1') {recurring[recurring.length] = "sat"};
		if (bin[7] == '1') {recurring[recurring.length] = "sun"};
	}
	return recurring;
}

/**
* Get a TimeString and when it starts with "P" or "R" (recurrence for timers).
* Returns the number of executions of that schedule or -1 if number of executions is infinity.
*/
function loadRepetitionsTimer(time) {
	var repetitions = 1;
	if (time.charAt(0) == "R") {
		var ex = time.substring(time.indexOf('R')+1,time.indexOf('/'));
		if (ex == ""){
			repetitions = -1;
		} else {
			repetitions = parseInt(ex);
		}
	}
	return repetitions;
}

/**
 * creates a new Schedule Object and call function to build the html page with it.
 */
function createNewSchedule() {

	curSchedule.activeState = "checked";
	curSchedule.scheduleType ="alarm";
	curSchedule.type_img = "clock.png";
	curSchedule.hour = "12";
	curSchedule.min = "00";
	curSchedule.time = timeToUTC(true,curSchedule.hour,curSchedule.min);
	curSchedule.sceneOrGroup = "scene";
	curSchedule.groupOn = true;
    curSchedule.name = "New Schedule";
	curSchedule.scene = {};
    curSchedule.scene.name = "None";
	curSchedule.group = {};
    curSchedule.group.name = "None";
	curSchedule.transitiontime = 0;
	curSchedule.sceneId = undefined;
	curSchedule.groupId = undefined;
	curSchedule.sceneGroupId = undefined;
	curSchedule.repetitions = 1;
	curSchedule.recurring = [];
	curSchedule.level = 203; // 80%
	curSchedule.old = {};
    curSchedule.old.name = "New Schedule";
	curSchedule.old.scene = {};
	curSchedule.old.scene.name = "None";
	curSchedule.old.time = curSchedule.time;
	curSchedule.old.group = {};
	curSchedule.old.group.name = "None";
	curSchedule.old.transitiontime = 0;
	curSchedule.old.activeState = "checked";
	curSchedule.old.level = 203;

	buildSubPage();
}

/**
 * load a Schedule from Session Storage if available and call function to build html page.
 * Or if no Session Storage available call the RestAPI to load the schedule with given id.
 */
function loadSchedule(id) {
	//if (Modernizr.sessionstorage) {
	if (typeof(Storage) !== "undefined") {
	//sessionStorage.removeItem("curSchedule"); //debug
		// load Schedule from local storage if available
		if (sessionStorage.getItem("curSchedule") != undefined) {
			curSchedule = JSON.parse(sessionStorage.getItem("curSchedule"));
			buildSubPage();
		} else {
			// load Schedule from RestAPI call
			getSchedule(id)
		}
	} else {alert("no Sessionstorage. Please use a new browser.");}
}

function convertFadingTime(seconds) {

	var result = [];
	var sec = seconds%60;
	var min = (seconds - sec)/60;

	if ((sec > 0) && (sec < 5)) { sec = 0; }
	if ((sec > 10) && (sec < 15)) { sec = 10; }
	if ((sec > 20) && (sec < 25)) { sec = 20; }
	if ((sec > 25) && (sec < 30)) { sec = 25; }
	if ((sec > 30) && (sec < 40)) { sec = 30; }
	if ((sec > 40) && (sec < 50)) { sec = 40; }
	if (sec > 50) { sec = 50; }

	if ((min > 5) && (min < 10)) { min = 5; }
	if ((min > 10) && (min < 20)) { min = 10; }
	if ((min > 20) && (min < 30)) { min = 20; }
	if (min > 30) { min = 30; }

	result[0] = min;
	result[1] = sec;

	return result;
}

/**
* convert 24h schedule.time to 12h format
*/
function convert24to12(hour) {
	var curHour12;

	if (hour == "12") {
		curHour12 = "12";
		ampm = "pm";
	} else if (hour == "00" || hour == "24") {
		curHour12 = "12";
		ampm = "am";
	} else if ((parseInt(hour) > 12) && (parseInt(hour) < 24)) {
		curHour12 = parseInt(hour) - 12;
		if ((curHour12 > 0) && (curHour12 < 10)) {
			curHour12 = "0" + curHour12;
		}
		ampm = "pm";
	} else if ((parseInt(hour) > 0) && (parseInt(hour) < 12)) {
		curHour12 = hour;
		ampm = "am";
	}
	return curHour12;
}

/**
* convert 12h to 24h format
*/
function convert12to24(h) {
	var curHour24;

	if ((h == "12") && (ampm == "pm")) {
		curHour24 = "12";
	} else if ((h == "12") && (ampm == "am")) {
		curHour24 = "00";
	} else if ((parseInt(h) > 0) && (parseInt(h) < 12) && (ampm == "am")) {
		curHour24 = h;
	} else if ((parseInt(h) > 0) && (parseInt(h) < 12) && (ampm == "pm")) {
		curHour24 = parseInt(h) + 12;
	}
	return curHour24;
}

/**
* build the html page for a given Schedule Object.
*/
function buildSubPage() {
    if (Modernizr.sessionstorage) {
        if (sessionStorage.config) {
            var config = JSON.parse(sessionStorage.config);
			timeFormat = config.config.timeformat;
        }
    }

	var fade = ((curSchedule.transitiontime == 0) || curSchedule.transitiontime === undefined) ? [0,0] : convertFadingTime(parseInt(curSchedule.transitiontime)/10);
	var min = fade[0];
	var sec = fade[1];

	if ((min != 0) && (sec != 0)) {
		returnstring = min + " min " + sec + " s";
	} else {
		if ((min == 0) && (sec == 0)) {
			returnstring = "";
		} else if (min == 0) {
			returnstring = sec +" s";
		} else if (sec == 0) {
			returnstring = min +" min";
		}
	}

	var fadeButtonText = returnstring;

	// load days for recurring alarm: W[0-127]/T...
	if (curSchedule.scheduleType == "alarm") {
		curSchedule.recurring = loadRepeatedDays(curSchedule.time);
		if (curSchedule.recurring.length != 0) {
			mon_class = (containsElement("mon", curSchedule.recurring)) ? "active" : "not_reachable";
			tue_class = (containsElement("tue", curSchedule.recurring)) ? "active" : "not_reachable";
			wed_class = (containsElement("wed", curSchedule.recurring)) ? "active" : "not_reachable";
			thu_class = (containsElement("thu", curSchedule.recurring)) ? "active" : "not_reachable";
			fri_class = (containsElement("fri", curSchedule.recurring)) ? "active" : "not_reachable";
			sat_class = (containsElement("sat", curSchedule.recurring)) ? "active" : "not_reachable";
			sun_class = (containsElement("sun", curSchedule.recurring)) ? "active" : "not_reachable";
		}
	}

	var rowtxt = '<div class="location span6" style="margin:0px; padding:15px 0; max-width:340px;">';
    rowtxt += '<div class="row-fluid" align="center">';
	rowtxt += '<table align="center" border="0" style="width:90%">';
	rowtxt += '<thead><th style="width:50px;"></th><th style="width:120px;"></th><th style="width:50px;"></th></thead>';
    rowtxt += '<tbody style="margin:0;padding:0;">';

	//name
    var n = "24px;";
	if (isSmallDevice){n = "5%;"};
	rowtxt += '<tr><td align="center" colspan="3"><form class="inner-addon right-addon navbar-form"><img style="right:'+n+'" class="glyphicon" src="img/pencil.png"></img><input id="devNameLabelBig" type="text" style="width:220px; margin-left:0px;" maxlength="32" value="' + curSchedule.name + '"></form></td></tr>';

	//timer/alarm switch
	rowtxt += "<tr><td colspan=\"3\"> &nbsp; </td></tr>";
	rowtxt += '<tr><td align="center" colspan=\"3\"><div class="btn-group" role="group">';
	if (curSchedule.scheduleType === "alarm") {
		rowtxt += '<span class="btn active alarmButton" >Alarm</span>';
		rowtxt += '<span class="btn timerButton" >Timer</span>';
	} else {
		rowtxt += '<span class="btn alarmButton" >Alarm</span>';
		rowtxt += '<span class="btn active timerButton" >Timer</span>';
	}
	rowtxt += '</div></td></tr>';
	rowtxt += "<tr><td colspan=\"3\"> &nbsp; </td></tr>";

	//set time
	if (isSmallDevice) {
			rowtxt += '<tr><td colspan="3" style="text-align:center;"><span class="left" style="width:16px;margin-left:-17px;"><img src="img/'+ curSchedule.type_img +'" style="margin-right:10px;"/></span>';
		} else {
			rowtxt += '<tr><td colspan="3" style="text-align:center;"><span class="left" style="width:16px;"><img src="img/'+ curSchedule.type_img +'" style="margin-right:10px;"/></span>';
		}

	//12h am/pm
	if ((timeFormat == "12h") && (curSchedule.scheduleType != "timer")) {
		hourstxt = '<select id="hour" style="width:60px;">';
		hourstxt += '<option>01</option><option>02</option><option>03</option><option>04</option><option>05</option><option>06</option>';
		hourstxt += '<option>07</option><option>08</option><option>09</option><option>10</option><option>11</option><option>12</option>';
		hourstxt += '</select>';

		var part1 = hourstxt.substring(0,hourstxt.indexOf(convert24to12(curSchedule.hour))-1);
		var part2 = hourstxt.substr(hourstxt.indexOf(convert24to12(curSchedule.hour)),hourstxt.length);
		hourstxt = part1 + " selected>" + part2;

		rowtxt += hourstxt;

	} else {
	//24h
		hourstxt = '<select id="hour" style="width:60px;">';
		hourstxt += '<option>00</option><option>01</option><option>02</option><option>03</option><option>04</option><option>05</option><option>06</option>';
		hourstxt += '<option>07</option><option>08</option><option>09</option><option>10</option><option>11</option><option>12</option><option>13</option>';
		hourstxt += '<option>14</option><option>15</option><option>16</option><option>17</option><option>18</option><option>19</option><option>20</option>';
		hourstxt += '<option>21</option><option>22</option><option>23</option>';
		hourstxt += '</select>';

		var part1 = hourstxt.substring(0,hourstxt.indexOf(curSchedule.hour)-1);
		var part2 = hourstxt.substr(hourstxt.indexOf(curSchedule.hour),hourstxt.length);
		hourstxt = part1 + " selected>" + part2;

		rowtxt += hourstxt;
	}

	if (curSchedule.scheduleType === "alarm") {
		rowtxt += '<span class="middle">&nbsp;&nbsp;:&nbsp;&nbsp;</span>';
	} else {
		rowtxt += '<span class="middle">&nbsp;h&nbsp;&nbsp;</span>';
	}

	minutestxt = '<select id="minutes" style="width:60px;">';
	minutestxt += '<option>00</option><option>01</option><option>02</option><option>03</option><option>04</option><option>05</option><option>06</option>';
	minutestxt += '<option>07</option><option>08</option><option>09</option><option>10</option><option>11</option><option>12</option><option>13</option>';
	minutestxt += '<option>14</option><option>15</option><option>16</option><option>17</option><option>18</option><option>19</option><option>20</option>';
	minutestxt += '<option>21</option><option>22</option><option>23</option><option>24</option><option>25</option><option>26</option><option>27</option>';
	minutestxt += '<option>28</option><option>29</option><option>30</option><option>31</option><option>32</option><option>33</option><option>34</option>';
	minutestxt += '<option>35</option><option>36</option><option>37</option><option>38</option><option>39</option><option>40</option><option>41</option>';
	minutestxt += '<option>42</option><option>43</option><option>44</option><option>45</option><option>46</option><option>47</option><option>48</option>';
	minutestxt += '<option>49</option><option>50</option><option>51</option><option>52</option><option>53</option><option>54</option><option>55</option>';
	minutestxt += '<option>56</option><option>57</option><option>58</option><option>59</option>';
	minutestxt += '</select>&nbsp;';

	part1 = minutestxt.substring(0,minutestxt.indexOf('>'+curSchedule.min)); // dont split at the style="width:50px" attribute
	part2 = minutestxt.substr(minutestxt.indexOf('>'+curSchedule.min)+1,minutestxt.length);
	minutestxt = part1 + " selected>" + part2;
	rowtxt += minutestxt;

	if (curSchedule.scheduleType === "alarm") {
		if (timeFormat == "12h") {
			if (ampm == "am") {
				am_class = "active";
				pm_class = "not_reachable";
			} else {
				am_class = "not_reachable";
				pm_class = "active";
			}
			rowtxt += '<span class="right">';
			if (isSmallDevice) {
				rowtxt += '<br /><div style="margin-left:0px;" class="btn-group" role="group"><span class="'+ am_class +' btn am">am</span><span class="'+ pm_class +' btn pm">pm</span></div>';
			} else {
				rowtxt += '<div style="margin-left:5px;margin-bottom:8px;" class="btn-group" role="group"><span class="'+ am_class +' btn am">am</span><span class="'+ pm_class +' btn pm">pm</span></div>';
			}
			rowtxt += '</span></td></tr>';
		} else {
			rowtxt += '<span class="right"></span>';
		}
	} else {
		rowtxt += '<span class="right">min</span></td></tr>';
	}

	//scene/group switch
	rowtxt += "<tr><td colspan=\"3\"> &nbsp; </td></tr>";
	rowtxt += '<tr><td align="center" colspan=\"3\"><div class="btn-group" role="group">';
	if (curSchedule.sceneOrGroup === "scene") {
        rowtxt += '<span class="btn active scenesButton">Scene On</span>';
        rowtxt += '<span class="btn groupButtonOn" >Group On</span>';
        rowtxt += '<span class="btn groupButtonOff" >Group Off</span>';
	} else {
		if (curSchedule.groupOn === true) {
            rowtxt += '<span class="btn scenesButton">Scene On</span>';
            rowtxt += '<span class="btn active groupButtonOn" >Group On</span>';
            rowtxt += '<span class="btn groupButtonOff" >Group Off</span>';
		} else {
            rowtxt += '<span class="btn scenesButton">Scene On</span>';
            rowtxt += '<span class="btn groupButtonOn" >Group On</span>';
            rowtxt += '<span class="btn active groupButtonOff" >Group Off</span>';
		}
	}

	rowtxt += '</div></td></tr>';
	rowtxt += "<tr><td colspan=\"3\"> &nbsp; </td></tr>";

	//scene/group
	if (curSchedule.sceneOrGroup === "scene") {
		rowtxt += '<tr><td style="height:40px; width:72px;"><span class="sceneOrGroup">'+ ((curSchedule.sceneOrGroup == "group") ? "Group" : "Scene")  +'</span></td><td class="groupSceneName">'+ shortenName(curSchedule.scene.name) +'</td><td align="right" class="buttonsceneOrGroup"><a href="schedules_scenes.html?scene='+ curSchedule.sceneId +'"><div style="" class="edit_button">';
		rowtxt += '</div></a></td></tr>';
	} else {
		rowtxt += '<tr><td style="height:40px; width:72px;"><span class="sceneOrGroup">'+ ((curSchedule.sceneOrGroup == "group") ? "Group" : "Scene") +'</span></td><td class="groupSceneName">'+ shortenName(curSchedule.group.name) +'</td><td align="right" class="buttonsceneOrGroup"><a  href="schedules_groups.html?group='+ curSchedule.groupId +'"><div style="" class="edit_button">';
		rowtxt += '</div></a></td></tr>';
	}

	//fade

	if (curSchedule.sceneOrGroup === "scene") {
		rowtxt += '<tr class="fadeRow hidden"><td style="height:40px">';
		rowtxt +=  '<span class="fader">Fade</span></td><td class="fadeButtonText">'+ fadeButtonText +'</td><td class="buttonFader" align="right"><a href="schedules_fade.html"><div class="edit_button fadeButton" style=""></div></a>';
		rowtxt += '</td></tr>';
	} else {
		rowtxt += '<tr class="fadeRow"><td style="height:40px">';
		rowtxt +=  '<span class="fader">Fade</span></td><td class="fadeButtonText">'+ fadeButtonText +'</td><td class="buttonFader" align="right"><a href="schedules_fade.html"><div class="edit_button fadeButton" style=""></div></a>';
		rowtxt += '</td></tr>';
	}

	//level
	if (curSchedule.sceneOrGroup === "group" && curSchedule.groupOn === true) {
		rowtxt += '<tr class="levelRow"><td style="height:40px">';
		rowtxt +=  '<span class="">Level</span></td><td class="level">' + mapLevelToPercent(curSchedule.level) + ' %</td><td class="" align="right"><a href="schedules_level.html"><div class="edit_button" style=""></div></a>';
		rowtxt += '</td></tr>';
		//colorloop
		//rowtxt += '<tr class="colorloopRow"><td style="height:40px">';
		//rowtxt +=  '<span class="">Colorloop</span></td><td class="colorloop">' + curSchedule.colorloop + ' </td><td class="" align="right"><a href="schedules_colorloop.html"><div class="edit_button" style=""></div></a>';
		//rowtxt += '</td></tr>';
	} else {
		rowtxt += '<tr class="levelRow hidden"><td style="height:40px">';
		rowtxt +=  '<span class="">Level</span></td><td class="level">' + mapLevelToPercent(curSchedule.level) + ' %</td><td class="" align="right"><a href="schedules_level.html"><div class="edit_button" style=""></div></a>';
		rowtxt += '</td></tr>';
		//rowtxt += '<tr class="colorloopRow hidden"><td style="height:40px">';
		//rowtxt +=  '<span class="">Colorloop</span></td><td class="colorloop">' + curSchedule.colorloop + ' </td><td class="" align="right"><a href="schedules_colorloop.html"><div class="edit_button" style=""></div></a>';
		//rowtxt += '</td></tr>';
	}

	//repeat
	rowtxt += '<tr><td colspan="3" style="height:40px">';
	if (curSchedule.scheduleType === "alarm") {
		rowtxt += '<span class="repeat">Repeat</span>';
		rowtxt += '</td></tr>';
		if (isSmallDevice) {
			rowtxt += '<tr><td style="height:63px;" align="center" class="daysRepeat" colspan=\"3\"><div class="btn-group" role="group"><span class="mo btn '+mon_class+'">Mo</span> <span class="tu btn '+tue_class+'">Tu</span> <span class="we btn '+wed_class+'">We</span> <span class="th btn '+thu_class+'">Th</span> <span class="fr btn '+fri_class+'">Fr</span></div><br />';
			rowtxt += '<div class="btn-group" role="group"><span class="sa btn '+sat_class+'">Sa</span> <span class="su btn '+sun_class+'">Su</span></div></td></tr>';
		} else {
			rowtxt += '<tr><td style="height:63px;" align="center" class="daysRepeat" colspan=\"3\"><div class="btn-group" role="group"><span class="mo btn '+mon_class+'">Mo</span> <span class="tu btn '+tue_class+'">Tu</span> <span class="we btn '+wed_class+'">We</span> <span class="th btn '+thu_class+'">Th</span> <span class="fr btn '+fri_class+'">Fr</span> <span class="sa btn '+sat_class+'">Sa</span> <span class="su btn '+sun_class+'">Su</span></div></td></tr>';
		}
	} else {
		rowtxt += '<span class="repeat"></span>';
		rowtxt += '</td></tr>';
		rowtxt += '<tr><td style="height:63px;" align="center" class="daysRepeat" colspan=\"3\">&nbsp;</td></tr>';
	}

	//status
	rowtxt += "<tr><td colspan=\"3\"> &nbsp; </td></tr>";
	if (curSchedule.activeState === "checked") {
		rowtxt += '<tr><td colspan="3"><span class="statusText" style="float:left;margin-top:5px;">Schedule enabled</span>';
        rowtxt += '<span style="width:60px;float:right;" class="btn btn_enable eenabled" >Disable</span>';
	} else {
		rowtxt += '<tr><td colspan="3"><span class="statusText not_reachable" style="float:left;margin-top:5px;">Schedule disabled</span>';
        rowtxt += '<span style="width:60px;float:right;" class="btn btn_enable ddisabled" >Enable</span>';
	}
	rowtxt += '</td></tr>';
	rowtxt += "<tr><td colspan=\"3\"> &nbsp; </td></tr>";

	//delete
	var scheduleURL = getURLParameter("schedule");
	if ((scheduleURL === null) || (scheduleURL == "undefined")) {
		rowtxt += '<tr><td><div style="width:73px;"></div></td>';
	} else {
        rowtxt += '<tr><td><span class="btn btn-danger deleteButton" style="margin: 15px 0px;">Delete</span></td>';
	}

	//apply/done
    rowtxt += '<td colspan="2"align="right"><span class="btn btn-primary saveButton" style="margin: 15px 0px;">Apply</span>&nbsp;&nbsp;&nbsp;<span class="btn actionButton doneButton" style="margin: 15px 0px;">Cancel</span></td></tr>';
	rowtxt += '</div>';
	rowtxt += '</div>';

	pageLightList.innerHTML = "";
    pageLightList.innerHTML += rowtxt;

    adjustLightNames();
}

function shortenName(name) {
	if (name.length > 18) {
		name = name.substr(0,17) + "...";
	}
	return name;
}

/**
* adds html to the schedules index page.
*/
function showSchedules(schedules) {
	if (Modernizr.sessionstorage) {
        if (sessionStorage.config) {
            var config = JSON.parse(sessionStorage.config);
			timeFormat = config.config.timeformat;
        }
    }

    var rowtxt="";
	var key = 1;
	var schedule = {};
	var time = "";

	rowtxt += '<div class="location span6" style="margin-left:0px;">';
	rowtxt += '<div class="row-fluid">';
	rowtxt += '<table border="0" id="schedulesTable">';
    rowtxt += '<tbody>';
	for(key in schedules) {
		schedule = schedules[key];
		schedule.id = key;
		time = schedule.time;
		if((time.charAt(0) == "P") || (time.charAt(0) == "R")) {
			schedule.type = "timer";
		} else {
			schedule.type = "alarm";
		}

		rowtxt += scheduleToHtml(schedule);

	}
	rowtxt += '</tbody>';
    rowtxt += '</table>';
	if (Modernizr.localstorage && localStorage.getItem("de-gw-swVersion") != undefined) {
		var swVersion = localStorage.getItem("de-gw-swVersion");
        rowtxt += '<div class="button-toolbar pull-right"><a href="schedules_submenu.html?v=' + swVersion + '"><span class="btn actionButton btn-primary" >Create Schedule</span></a>';
        rowtxt += '<a class="btn" href="/index.html?v=' + swVersion + '">Done</a></div>';
	} else {
        rowtxt += '<div class="button-toolbar pull-right"><a href="schedules_submenu.html"><span class="btn actionButton btn-primary" >Create Schedule</span></a>';
        rowtxt += '<a class="btn" href="/index.html">Done</a></div>';
	}
	rowtxt += '</div>';
	rowtxt += '</div>';

	$("#pageLightList").html("");
	$("#pageLightList").html(rowtxt);

	adjustLightNames();
}


/**
* Schedule to html for the schedules index page.
*/
function scheduleToHtml(schedule) {

    var reachableClass = (schedule.status == "enabled") ? " " : "not_reachable ";
    var txt = "";
	var type_img = "";
	var textcolor = "#e0e0e0";

	if (schedule.type == "alarm") {
		if (reachableClass == " ") {
			type_img = "clock_enabled.png"
		} else {
			textcolor = "rgba(255, 255, 255, 0.5)";
			type_img = "clock_disabled.png"
		}
	} else {
		if (reachableClass == " ") {
			type_img = "hourglass_enabled.png"
		} else {
			textcolor = "rgba(255, 255, 255, 0.5)";
			type_img = "hourglass_disabled.png"
		}
	}

    txt += "<tr class=\"light_item " + reachableClass + "\" data-sid=\"" + schedule.id + "\">";
	txt += "<td width=\"26px\" style=\"min-width:26px;\"><img src=\"/img/" + type_img + "\"></td>";

	txt += "<td ></td>";
	txt += "<td>" + schedule.name + "<br /><span id=\"spanSchedule" + schedule.id + "\" style=\"font-size:0.8em;color:"+ textcolor +";\">" + displayTime(schedule) + "</span></td>";

	txt += "<td class=\"edit_button\" data-sid=\"" + schedule.id + "\" ></td></tr>";
	txt += "<tr><td colspan=\"4\">&nbsp;</td></tr>";

    return txt;
}

/**
 * Helper to adjust the size of the name field to not exceed the table size.
 */
function adjustLightNames() {
    $('tr.light_item').each(function(index) {
		var maxwidth = $(this).innerWidth() - 180;
		$('.light_item td:nth-child(3)').each(function(index) {
			$(this).css('max-width', maxwidth + 'px');
		});
    });
}

/**
 * Displays all available groups with scenes in schedules_scenes.html
 */
function displayGroupsWithScenes(scenes,gname,gid,currentGid,currentSid) {
	var rowtxt="";
	curSchedule.scene = {};
	curSchedule.scene.name = "None";
	for(key in scenes) {
		var scene = scenes[key];
		rowtxt += '<option value="' +gid+':'+key+ '">' + gname + ' - ' + scene.name + '</option>';
	}

	$("#scenesSelect").append(rowtxt);
	if (currentSid != undefined) {
		$('#scenesSelect').val(currentGid+":"+currentSid);
	}
}

/**
 * Displays all available groups in schedules_groups.html
 */
function displayGroups(groups, groupId) {
	var rowtxt="";
	curSchedule.group = {};
	curSchedule.group.name = "None";
	for(key in groups) {
		if (groups[key].type !== 'LightGroup')
            continue;
		if (groups[key].hidden === false) {
			var group = groups[key];
			rowtxt += '<option value="' +key+ '">' + group.name + '</option>';
		}
	}

	$("#groupSelect").append(rowtxt);
	if (groupId != undefined) {
		$('#groupSelect').val(groupId);
	}
}

/**
 * Get Scenes for a given group.
 */
function getScenesforGroup(groups, gid, sid) {
	for(key in groups) {
		var group = groups[key];
		loadAllScenesFromGroup(key,group.name, gid, sid);
	}
}

/**
* api/<apikey>/schedules
*/
function getSchedules() {

	if (hidden !== 'undefined') {
        if (document[hidden] === true) {
            console.log('don\'t update while browser window is hidden');
            setTimeout(getSchedules, SCHEDULES_POLL_TIME);
            return;
        }
    }

    $.ajax({
        url: 'api/' + apikey + '/schedules',
        dataType: 'json',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        headers: { 'Accept': apiversion },
        data: '',
        success: function(json, status, xhr) {

			curEdit.obj = json;

			// make available for caching
			if (Modernizr.sessionstorage) {
				sessionStorage.schedules = xhr.responseText;
			}

			showSchedules(curEdit.obj);

			setTimeout(function(){getDateTimeFromGW(true)}, SCHEDULES_POLL_TIME);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            switch (jqXHR.status) {
            case 403:
              window.location.assign("/pwa/login.html");
              break;

            case 404: // not found go back
              window.location.assign("/");
              break;

            default:
              setTimeout(getSchedules, 3000);
              showAlert('alert-error', '<b>Error!</b> Loading data, retry in three seconds ...');
              break;
            }
        },
		timeout: 10000
    });
}

/**
 * Saves the current State of the Schedule Settings given by the User Interface to the Schedule Object.
 */
function saveCurrentState() {
	if ($('.btn_enable').hasClass('ddisabled')) {
        curSchedule.status = "disabled";
	} else {
        curSchedule.status = "enabled";
	}
    curSchedule.activeState = (curSchedule.status == "enabled") ? "checked" : "";
	curSchedule.name = $('#devNameLabelBig').val();

	curSchedule.sceneOrGroup = $('.scenesButton').hasClass('active') ? "scene" : "group";
	curSchedule.groupOn = $('.groupButtonOn').hasClass('active') ? true : false;

	//set time and type
	curSchedule.min = $('#minutes').val();
	curSchedule.scheduleType = $('.alarmButton').hasClass('active') ? "alarm" : "timer";
	if (curSchedule.transitiontime === undefined) {
		curSchedule.transitiontime = 0;
	}
	if (curSchedule.scheduleType == "alarm") {
		curSchedule.type_img = "clock.png"
	} else {
		curSchedule.type_img = "hourglass.png"
	}

	if ((timeFormat == "24h") || (curSchedule.scheduleType == "timer")) {
		curSchedule.hour = $('#hour').val();
	} else {
	    curSchedule.hour = convert12to24($('#hour').val());
	}

	if (curSchedule.recurring === undefined){
		curSchedule.recurring = [];
	}
	//timer
	if (curSchedule.scheduleType == "timer") {
		curSchedule.repetitions = 1;
		curSchedule.time = "PT" + curSchedule.hour + ":" + curSchedule.min + ":00";
	//alarm
	} else {
		var weekBitmap = "0";
		if ($('.mo').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};
		if ($('.tu').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};
		if ($('.we').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};
		if ($('.th').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};
		if ($('.fr').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};
		if ($('.sa').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};
		if ($('.su').hasClass('active')) {weekBitmap += "1"} else {weekBitmap += "0"};

		var weekBitmapUTC = convertUtcWeekBitmap(weekBitmap);
		var daysDezimalUTC = parseInt(weekBitmapUTC, 2);

		if (weekBitmapUTC != "00000000") {
			var timeStringUTC = "W" + daysDezimalUTC.toString() + "/T" + timeToUTC(false,curSchedule.hour,curSchedule.min);
		} else {
			var timeStringUTC = timeToUTC(true,curSchedule.hour,curSchedule.min);
		}

		curSchedule.time = timeStringUTC;
		curSchedule.recurring = loadRepeatedDays(curSchedule.time);
	}
	if (curSchedule.group === undefined) {
		var group = {};
		group.name = "None";
		curSchedule.group = group;

	}
	if (curSchedule.scene === undefined) {
		var scene = {};
		scene.name = "None";
		curSchedule.scene = scene;
	}

	if (curSchedule.level === undefined) {
		curSchedule.level = 203 ;
	}

}

/**
 * Convert the weekbitmap to UTC
 */
function convertUtcWeekBitmap(weekBitmap) {

	var result = "0";
	var h = 0;
	var t = 0;

	if (curSchedule.hour == "00" && curSchedule.min == "00") {
		// alarm will trigger at midnight between the chosen day and next day
		h = 24;
	} else {
		h = parseInt(curSchedule.hour);
	}

	t = ( h * 60 ) + parseInt(curSchedule.min);

	if ((t + timeOffset) < 0) {
		//move days to left
		for (var c = 2; c < 8; c++) {
			if (weekBitmap[c] == "0") {
				result += "0";
			} else {
				result += "1";
			}
		}
		result += weekBitmap[1];
		return result;
	} else if ((t + timeOffset) > 1439) {
		//move days to right
		result += weekBitmap[7];
		for (var c = 1; c < 7; c++) {
			if (weekBitmap[c] == "0") {
				result += "0";
			} else {
				result += "1";
			}
		}
		return result;
	}
	return weekBitmap;
}

/**
 * Convert the weekbitmap from UTC
 */
function convertWeekBitmapFromUtc(weekBitmap, time) {
	var result = "0";
	var hour = time.substr(time.indexOf('T')+1, 2);
	var min = time.substr(time.indexOf('T')+4, 2);
	var t = (parseInt(hour) * 60) + parseInt(min);

	if ((t - timeOffset) <= 0) {
		//move days to left
		for (var c = 2; c < 8; c++) {
			if (weekBitmap[c] == "0") {
				result += "0";
			} else {
				result += "1";
			}
		}
		result += weekBitmap[1];
		return result;

	} else if ((t - timeOffset) > 1440) {
		//move days to right
		result += weekBitmap[7];
		for (var c = 1; c < 7; c++) {
			if (weekBitmap[c] == "0") {
				result += "0";
			} else {
				result += "1";
			}
		}
		return result;
	}
	return weekBitmap;
}

/**
* api/<apikey>/schedules/<id>
*/
function getSchedule(id) {
    $.ajax({
        url: 'api/' + apikey + '/schedules/' + id,
        dataType: 'json',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        headers: { 'Accept': apiversion },
        data: '',
        success: function(json, status, xhr) {
			curSchedule = json;
			curSchedule.id = id;
			var cmdAddress = curSchedule.command.address;
			var bri = curSchedule.command.body.bri;

			curSchedule.activeState = (curSchedule.status == "enabled") ? "checked" : "";

			if ((curSchedule.time.charAt(0) == "P") || (curSchedule.time.charAt(0) == "R")) {
				curSchedule.scheduleType = "timer";
				curSchedule.hour = (curSchedule.time).substr((curSchedule.time).indexOf('T')+1,2);
				curSchedule.min = (curSchedule.time).substr((curSchedule.time).indexOf('T')+4,2);
				curSchedule.repetitions = loadRepetitionsTimer(curSchedule.time);
				curSchedule.recurring = [];
			} else {
				curSchedule.repetitions = 1;
				curSchedule.scheduleType = "alarm";

				var hoursMinutes = timeFromUTC((curSchedule.time).substr((curSchedule.time).indexOf('T')+1,2),(curSchedule.time).substr((curSchedule.time).indexOf('T')+4,2),false);
				curSchedule.hour = hoursMinutes.substring(0,hoursMinutes.indexOf(':'));
				curSchedule.min = hoursMinutes.substring(hoursMinutes.indexOf(':')+1,hoursMinutes.length);
			}

			curSchedule.type_img = (curSchedule.scheduleType == "alarm") ? "clock.png" : "hourglass.png";
			curSchedule.sceneOrGroup = (cmdAddress.indexOf("scenes") > -1) ? "scene" : "group";
			curSchedule.transitiontime = curSchedule.command.body.transitiontime;
			//bri level
			if (bri === undefined || bri == null) {
				curSchedule.level = 203;
			} else {
				curSchedule.level = bri;
			}

			curSchedule.old = {};
			curSchedule.old.name = curSchedule.name;
			curSchedule.old.transitiontime = curSchedule.transitiontime;
			curSchedule.old.activeState = curSchedule.activeState;
			curSchedule.old.time = curSchedule.time;
			curSchedule.old.level = curSchedule.level;

			if (curSchedule.sceneOrGroup === "scene") {
				curSchedule.sceneGroupId = (/\d+/.exec(cmdAddress.substring(cmdAddress.indexOf("groups")+7,cmdAddress.indexOf("/scenes"))))[0];
				curSchedule.sceneId = (/\d+/.exec(cmdAddress.substring(cmdAddress.indexOf("scenes")+7,cmdAddress.length)))[0];
				//load scene from rest api call
				loadScene(curSchedule.sceneGroupId,curSchedule.sceneId);
			} else {
				curSchedule.groupOn = ((curSchedule.command.body.on) == true) ? true : false;
				curSchedule.groupId = (/\d+/.exec(cmdAddress.substring(cmdAddress.indexOf("groups")+7,cmdAddress.length)))[0];
				curSchedule.sceneId = undefined;
				//load group from rest api call
				loadGroup(curSchedule.groupId);
			}
        },
        error: function(jqXHR, textStatus, errorThrown) {
            switch (jqXHR.status) {
            case 403:
              window.location.assign("/pwa/login.html");
              break;

            case 404: // not found go back
              window.location.assign("/");
              break;

            default:
              setTimeout(getSchedule, 3000);
              showAlert('alert-error', '<b>Error!</b> Loading data, retry in three seconds ...');
              break;
            }
        },
		timeout: 10000
    });
}

/**
* api/<apikey>/groups/<group_id>/scenes/<scene_id>
*/
function loadScene(gid,sid) {
    $.ajax({
        url: 'api/' + apikey + '/groups/' + gid + '/scenes/' + sid,
        dataType: 'json',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        headers: { 'Accept': apiversion },
        data: '',
        success: function(json, status, xhr) {
			var scene = {};
			if (json.state == 1) {
				scene.name = "None";
				curSchedule.sceneId = undefined;
			} else {
				scene.name = json.name;
			}
			scene.name = json.name;
			curSchedule.scene = scene;
			curSchedule.old.scene = curSchedule.scene;
			curSchedule.old.group = {};
			curSchedule.old.group.name = "None";
			buildSubPage();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            var scene = {};
			scene.name = "None";
			curSchedule.scene = scene;
			curSchedule.old.scene = curSchedule.scene;
			curSchedule.sceneId = undefined;
			buildSubPage();
        },
		timeout: 10000
    });
}

/**
* api/<apikey>/groups/<group_id>
*/
function loadGroup(gid) {

    $.ajax({
        url: 'api/' + apikey + '/groups/' + gid,
        dataType: 'json',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        headers: { 'Accept': apiversion },
        data: '',
        success: function(json, status, xhr) {
			var group = {};
			if (json.state == 1) {
				group.name = "None";
				curSchedule.groupId = undefined;
			} else {
				group.name = json.name;
			}
			curSchedule.group = group;
			curSchedule.old.group = curSchedule.group;
			curSchedule.old.scene = {};
			curSchedule.old.scene.name = "None";
			buildSubPage();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            var group = {};
			group.name = "None";
			curSchedule.group = group;
			curSchedule.old.scene = curSchedule.scene;
			curSchedule.groupId = undefined;
			buildSubPage();
        },
		timeout: 10000
    });
}

/**
* api/<apikey>/groups
*/
function getAllGroups(getScenes, groupId, sceneId) {

    $.ajax({
        url: 'api/' + apikey + '/groups',
        dataType: 'json',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        headers: { 'Accept': apiversion },
        data: '',
        success: function(json, status, xhr){
			if (getScenes === false) {
				displayGroups(json, groupId);
			} else {
				getScenesforGroup(json, groupId, sceneId);
			}
        },
        error: function(jqXHR, textStatus, errorThrown) {
            switch (jqXHR.status) {
            case 403:
              window.location.assign("/pwa/login.html");
              break;

            case 404: // not found go back
              window.location.assign("/");
              break;

            default:
              break;
            }
        },
		timeout: 10000
    });
}

/**
* api/<apikey>/groups/<group_id>/scenes
*/
function loadAllScenesFromGroup(gid,gname,currentGid,currentSid) {

    $.ajax({
        url: 'api/' + apikey + '/groups/' + gid + '/scenes',
        dataType: 'json',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        headers: { 'Accept': apiversion },
        data: '',
        success: function(json, status, xhr){
			displayGroupsWithScenes(json,gname,gid,currentGid,currentSid);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            switch (jqXHR.status) {
            case 403:
              window.location.assign("/pwa/login.html");
              break;

            case 404: // not found go back
              window.location.assign("/");
              break;

            default:
              break;
            }
        },
		timeout: 10000
    });
}

/**
 * POST /api/<apikey>/schedules
 */
function sendScheduleRestAPI() {
	var body = "";
	var on = false;
	var on = false;
	var bri = 0;

	if ($('.groupButtonOn').hasClass('active')){
		on = true; bri = curSchedule.level;
	}

	body += '{"name":"'+ $('#devNameLabelBig').val() +'",';
	body += '"time":"'+ curSchedule.time +'",';
    body += '"status":"'+ curSchedule.status.toLowerCase() +'",';
    body += '"autodelete":false,';

	if (curSchedule.sceneOrGroup == "group") {
		body += '"command":{"address":"/api/'+ apikey +'/groups/'+ curSchedule.groupId +'/action",';
		if (curSchedule.groupOn == false && curSchedule.transitiontime == 0) {
			body += '"body":{"on":'+ on +',"transitiontime":'+ curSchedule.transitiontime +'},';
		} else {
			body += '"body":{"on":'+ on +',"bri":'+ bri +',"transitiontime":'+ curSchedule.transitiontime +'},'; //set bri
		}
	} else {
		body += '"command":{"address":"/api/'+ apikey +'/groups/'+ curSchedule.sceneGroupId +'/scenes/'+ curSchedule.sceneId +'/recall",';
		body += '"body":{},';
	}
	body += '"method":"PUT"}}';

    $.ajax({
        url: '/api/' + apikey + '/schedules',
        type: 'POST',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        data: body,
        dataType: 'json',
        success: function(data) {
            setTimeout(function(){window.open("schedules.html","_self")},200);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log("textStatus:", textStatus + ' ' + errorThrown);
            console.log(jqXHR.responseText);
        },
        timeout: 10000
    });
}

/**
 * PUT /api/<apikey>/schedules/<id>
 */
function updateScheduleRestAPI() {
	var id = curSchedule.id;
	var body = "";
	var on = false;
	var bri = 0;
	if ($('.groupButtonOn').hasClass('active')){on = true; bri = curSchedule.level;}

	body += '{"name":"'+ $('#devNameLabelBig').val() +'",';
	body += '"time":"'+ curSchedule.time +'",';
    body += '"status":"'+ curSchedule.status.toLowerCase() +'",';
    body += '"autodelete":false,';

	if (curSchedule.sceneOrGroup == "group") {
		body += '"command":{"address":"/api/'+ apikey +'/groups/'+ curSchedule.groupId +'/action",';
		if (curSchedule.groupOn == false && curSchedule.transitiontime == 0) {
			body += '"body":{"on":'+ on +',"transitiontime":'+ curSchedule.transitiontime +'},';
		} else {
			body += '"body":{"on":'+ on +',"bri":'+ bri +',"transitiontime":'+ curSchedule.transitiontime +'},'; //set bri
		}
	} else {
		body += '"command":{"address":"/api/'+ apikey +'/groups/'+ curSchedule.sceneGroupId +'/scenes/'+ curSchedule.sceneId +'/recall",';
		body += '"body":{},';
	}
	body += '"method":"PUT"}}';

    $.ajax({
        url: '/api/' + apikey + '/schedules/' +id,
        type: 'PUT',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        data: body,
        dataType: 'json',
        success: function(data) {
            setTimeout(function(){window.open("schedules.html","_self")},200);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log("textStatus:", textStatus + ' ' + errorThrown);
            console.log(jqXHR.responseText);
        },
        timeout: 10000
    });
}

/**
 * DELETE /api/<apikey>/schedules/<id>
 */
function deleteScheduleRestAPI() {
	var id = curSchedule.id

    $.ajax({
        url: '/api/' + apikey + '/schedules/' + id,
        type: 'DELETE',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function(data) {
			setTimeout(function(){window.open("schedules.html","_self")},200);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log("textStatus:", textStatus + ' ' + errorThrown);
            console.log(jqXHR.responseText);
        },
        timeout: 10000
    });
}

var triggerTo;
/**
 * Helper Function to display Alerts
 */
function showAlert(alert, text, container) {

    if (typeof(container) === 'undefined') {
        container = '#alerts';
    }

    var d = new Date();
    var timestr = d.toUTCString();
    var txt = "";

    txt += '<div style="" class="alert ' + alert + '">';
    txt += text;
    txt += ' <span class="pull-right hidden-phone">';
    txt += '</span></div>';

	if (container === '#trigger-info') {
		clearTimeout(triggerTo);
		console.log("clear TO " + triggerTo);
		setTimeout(function() {
			$(container).html(txt).scrollintoview();
		}, 250);

		triggerTo = setTimeout(function() {
		console.log("TO " + triggerTo + " called");
		clearTimeout(triggerTo);
		console.log("clear TO " + triggerTo);
			$(container).html(txt).fadeOut(1000, function() {
				$(this).children().remove();
				$(this).css('display','block');
			});
		}, 8000);
		console.log("start TO " + triggerTo);
	} else {
		setTimeout(function() {
			$(container).html(txt).scrollintoview();
		}, 250);
	}
}

/**
 * Check if an array contains the given element.
 */
function containsElement(element,array) {
    for (var i = 0; i < array.length; i++) {
        if (array[i] === element) {
            return true;
        }
    }
    return false;
}

/**
* convert the input hour and minutes to utc time.
*/
function timeToUTC(createDate, hour, minute) {

	var year = parseInt(gatewayDate.substr(0,4));
	var month = parseInt(gatewayDate.substr(5,2)) - 1; // month [0..11]
	var day = parseInt(gatewayDate.substr(8,2));

	var date = new Date(year,month,day,hour,minute,0,0);

	var y = date.getUTCFullYear();
	var m = date.getUTCMonth() + 1; // month [0..11]
	var d = date.getUTCDate();

	var h = (date.getUTCHours()  < 10) ? "0" + date.getUTCHours() : date.getUTCHours();
	var min = (date.getUTCMinutes()  < 10) ? "0" + date.getUTCMinutes() : date.getUTCMinutes();
	var monthUTC = (m  < 10) ? "0" + m : m;
	var dayUTC = (d  < 10) ? "0" + d : d;

	if (createDate === true) {
		return y + "-" + monthUTC + "-" + dayUTC + "T" + h + ":" + min + ":00";
	} else {
		return h + ":" + min + ":00";
	}
}

/**
* convert the input UTC hour and UTC minutes to local time. Output format = "hh:mm"
*/
function timeFromUTC(hour, min, fromIndexPage) {
    if (Modernizr.sessionstorage) {
        if (sessionStorage.config) {
            var config = JSON.parse(sessionStorage.config);
			timeFormat = config.config.timeformat;
        }
    }

	var hoursMinutes = (parseInt(hour)*60) + parseInt(min);
	var hoursMinutesPlusOffset = (hoursMinutes - timeOffset);

	if (hoursMinutesPlusOffset < 0) {
		hoursMinutesPlusOffset = 1440 + hoursMinutesPlusOffset;
	} else if (hoursMinutesPlusOffset > 1440) {
		hoursMinutesPlusOffset = hoursMinutesPlusOffset - 1440 ;
	}

	var hourLocal = 0;
	if (hoursMinutesPlusOffset != 0) {
		hourLocal = Math.floor(hoursMinutesPlusOffset / 60);
	}
	if (hourLocal == 24) {
		hourLocal = 0;
	}
	var minLocal = hoursMinutesPlusOffset%60;

	if ((hourLocal.toString()).length < 2) {
		hourLocal = "0" + hourLocal;
	}
	if ((minLocal.toString()).length < 2) {
		minLocal = "0" + minLocal;
	}

	if (timeFormat == "12h") {
		 if (fromIndexPage == true) {
			hourLocal = convert24to12(hourLocal);
		} else {
			hourLocal = (hourLocal);
		}
	}
	return hourLocal + ":" + minLocal;
}

/**
* Checks if the time in the Schedule Object is below actual time.
*/
function checkTimeInPast() {
	var result = false;
	var hour = gatewayDate.substr(11,2); // TODO: this time could be to old. Get actual time.
	var min = gatewayDate.substr(14,2);

	if (curSchedule.hour < hour) {
		result = true;
	} else if (curSchedule.hour == hour) {
		if (curSchedule.min <= min) {
			result = true;
		}
	}
	return result;
}

/**
* Displays formatted time for the schedules index page.
*/
function displayTime(schedule) {
	var txt = "";
	var time = schedule.time;
	var hour = time.substr(time.indexOf('T')+1,2);
	var min = time.substr(time.indexOf('T')+4,2);

	if (schedule.type == "alarm") {
		if (timeFormat == "12h") {
			txt += timeFromUTC(hour,min,true) + ' ' + ampm + ' ';
		} else {
			txt += timeFromUTC(hour,min,true) + ' ';
		}
		if (time.charAt(0) == 'W'){
			var days = loadRepeatedDays(time);
			if (days.length != 0 && isSmallDevice) {
				txt += '<br />';
			} else {
				txt += '&nbsp;&nbsp;';
			}
			for (d in days) {
				txt += "<span>" + days[d].substr(0,1).toUpperCase() + days[d].substr(1,1) + " </span>";
			}
		}
	} else {
		// timer

		var starttime = schedule.starttime;
		var duration = schedule.time;
		var startdate = new Date(starttime + "Z"); // Z is for Zulu (important for some browsers)
		var now = new Date(gatewayUTC + "Z");

		var durHour = duration.substr(duration.indexOf('T')+1,2);
		var durMin = duration.substr(duration.indexOf('T')+4,2);
		var dur = (parseInt(durHour)*60)+parseInt(durMin) // duration in minutes

		if (schedule.status == "disabled") {
			if (durHour != 0) {
				txt += durHour + ' h ';
			}
			txt += durMin + ' min';
		} else {

			var diff = (Math.abs(now - startdate))/1000; //seconds

			time = (Math.floor(diff/60));

			diff = (parseInt(dur) - parseInt(time));

			min = diff%60;
			hour = (diff - min)/60;
			txt += 'in ';

			if (min == 0 && hour == 0) {
				min = 1;
			}

			if (hour > 0) {
				txt += hour + " h " ;
			}
			if (min <= 1 && hour == 0) {
				txt += "< " + min + " min" ;
			} else {
				txt += min + " min" ;
			}
		}

	}

	return txt;
}

$(document).on('keydown', '.navbar-form #devNameLabelBig', function(event) {
	if(event.keyCode == 13) {
		if (event.target.nodeName === "INPUT") {
			isFocused = false;
			event.target.blur();
			event.preventDefault();
			return false;
		}
	}
});

/**
 * map 0-255 level range into 0-100% range
 */
function mapLevelToPercent(level) {

    if (level === undefined) {
        return 0;
    }

    var levelPercent = Math.ceil(100 * (level / 255));

    if (levelPercent > 100) {
        levelPercent = 100;
    }

	return levelPercent;
}

/**
 * Get /api/<apikey>/config/
 */
function getDateTimeFromGW(showIndexPage) {

    $.ajax({
        url: '/api/' + apikey + '/config',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function(json) {
			clearAlert(); // all new
			timeFormat = json.timeformat;
			gatewayDate = json.localtime;
			gatewayUTC = json.UTC;

			var y = gatewayDate.substr(0,4);
			var m = gatewayDate.substr(5,2);
			var d = gatewayDate.substr(8,2);
			var h = gatewayDate.substr(11,2);
			var min = gatewayDate.substr(14,2);

			var gwDate = new Date(y,parseInt(m)-1,d,h,min,0,0);

			timeOffset = gwDate.getTimezoneOffset();

			if (showIndexPage === true) {
				if (timeFormat === "12h") {
					$('#gatewayTime').html('Gateway time is ' + convert24to12(h) + ":" + min + " " + ampm);
				} else {
					$('#gatewayTime').html('Gateway time is ' + h + ":" + min);
				}
				getSchedules();

			} else {
				var scheduleId = getURLParameter("schedule");

				if (scheduleId !== null){
					//if editbutton of a schedule was clicked
					loadSchedule(scheduleId);
				} else {
					//if new schedule was clicked
					createNewSchedule();
				}
			}
        },
        error: function(jqXHR, textStatus, errorThrown) {
		    if (jqXHR.status == 0 || textStatus == "timeout") {
                // try from beginning on (also to clear the alert box on success)
                setTimeout(function(){getDateTimeFromGW(true)}, 1000);
                return;
            }
            console.log("textStatus:", textStatus + ' ' + errorThrown);
            console.log(jqXHR.responseText);
        },
        timeout: 10000
    });
}

function getCurrentGWtimeAndCheckTime(scheduleURL) {
	$.ajax({
        url: '/api/' + apikey + '/config',
        type: 'GET',
        cache: false,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function(json) {
			gatewayDate = json.localtime;
			gatewayUTC = json.UTC;

			var h = gatewayDate.substr(11,2);
			var min = gatewayDate.substr(14,2);

			var hUTC = gatewayUTC.substr(11,2);
			var minUTC = gatewayUTC.substr(14,2);

			hourOffset = parseInt(hUTC) - parseInt(h);
			minuteOffset =  parseInt(minUTC) - parseInt(min);
			timeOffset = (hourOffset * 60) + minuteOffset;

			if ((scheduleURL === null) || (scheduleURL == "undefined")) {
				//create new schedule
				if (curSchedule.sceneOrGroup == "group") {
					if (curSchedule.groupId === undefined) {
						showAlert('alert-error', '<b>Error!</b> No group selected.','#schedule-alerts');
					} else {
						if ((checkTimeInPast() === true) && (curSchedule.recurring.length == 0) && (curSchedule.scheduleType == "alarm")) {
							showAlert('alert-error', '<b>Error!</b> Time lies in the past and no weekday selected.','#schedule-alerts');
						} else {
							sendScheduleRestAPI();
						}
					}
				} else {
					if (curSchedule.sceneId === undefined) {
						showAlert('alert-error', '<b>Error!</b> No scene selected.','#schedule-alerts');
					} else {
						if ((checkTimeInPast() === true) && (curSchedule.recurring.length == 0) && (curSchedule.scheduleType == "alarm")) {
							showAlert('alert-error', '<b>Error!</b> Time lies in the past and no weekday selected.','#schedule-alerts');
						} else {
							sendScheduleRestAPI();
						}
					}
				}
			} else {
				// update schedule
				if (curSchedule.sceneOrGroup == "group") {
					if (curSchedule.groupId === undefined) {
						showAlert('alert-error', '<b>Error!</b> No group selected.','#schedule-alerts');
					} else {
						if ((checkTimeInPast() === true) && (curSchedule.recurring.length == 0) && (curSchedule.scheduleType == "alarm")) {
							showAlert('alert-error', '<b>Error!</b> Time lies in the past and no weekday selected.','#schedule-alerts');
						} else {
							updateScheduleRestAPI();
						}
					}
				} else {
					if (curSchedule.sceneId === undefined) {
						showAlert('alert-error', '<b>Error!</b> No scene selected.','#schedule-alerts');
					} else {
						if ((checkTimeInPast() === true) && (curSchedule.recurring.length == 0) && (curSchedule.scheduleType == "alarm")) {
							showAlert('alert-error', '<b>Error!</b> Time lies in the past and no weekday selected.','#schedule-alerts');
						} else {
							updateScheduleRestAPI();
						}
					}
				}
			}
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log("textStatus:", textStatus + ' ' + errorThrown);
            console.log(jqXHR.responseText);
        },
        timeout: 10000
    });
}