var isEditing = false; // user holds key etc
var isSending = false; // push state request busy
var isDesktop = false;
var pointerStart = "mousedown";
var pointerEnd = "mouseup";
var pointerMove = "mousemove";

var APP_LIGHT_LIST_SCREEN = 0;
var APP_EDIT_LEVEL_SCREEN = 1;
var APP_EDIT_COLOR_SCREEN = 2;

// global screen (a page may have multiple screens)
var curScreen = APP_LIGHT_LIST_SCREEN;

// global edit object
var TYPE_NONE = 0;
var TYPE_LIGHT = 1;
var TYPE_GROUP = 2;
var TYPE_SCENE = 3;

var ACTION_CALL_SCENE = 0;
var ACTION_STORE_SCENE = 1;
var ACTION_REMOVE_SCENE = 2;
var ACTION_SET_NAME = 3;

var POLL_DELAY = 5000;

var curEdit = {
	level: 0,
	hue: 0,
	sat: 0,
	// the object to edit (light, group, scene)
	obj: undefined
};

//for multidevices whitechannel
var curEdit2 = {
	level: 0,
	// the object to edit (light, group, scene)
	obj: undefined
};

var apikey = null;
var apiversion = 'vnd.ddel.v1';

//list of sorted groups used by index.html and edit_groups.html
var groupssequenceleft = [];
var groupssequenceright = [];

// window.onerror = function(msg, url, linenumber) {
	// document.write(msg + ', ' + url + ': ' + linenumber);
	// alert(msg + ', ' + url + ': ' + linenumber);

	// if (jQuery) {
	//     var ak = apikey || '0';
	//     jQuery.post("/api/" + ak + "/js_error_log", { msg: msg, url: url, line: linenumber });
	// }
// };

/**
 * Detects if the device is running Android.
 * @returns {Boolean} true if Android was detected, false if not
 */
function isAndroid() {
	var ua = navigator.userAgent;
	if( ua.indexOf("Android") >= 0 ) {
		return true;
	}
	return false;
}

/**
 * Detects the Android version.
 * @returns {Number|undefined} version like 4.0, 2.3 or undefined if detection failed
 */
function androidVersion() {
	var ua = navigator.userAgent;
	if(ua.indexOf("Android") >= 0) {
		var androidversion = parseFloat(ua.slice(ua.indexOf("Android")+8));
		if (androidversion !== NaN) {
			return androidversion;
		}
	}

	return undefined;
}

/**
 * Logout the user from webapp.
 */
function logout() {
	localStorage.removeItem('apikey');
	window.location.href = '/pwa/login.html';
}

/**
 * Clears the alerts div.
 *
 * @param {*=} selector of the alert div which shall be cleared. default is #alerts (optional)
 */
function clearAlert(container) {
	if (typeof(container) === 'undefined') {
		container = '#alerts';
	}
	$(container).html('');
}

/**
 * General show alert helper.
 *
 * @param {string} alert alert-success, alert-info, alert-error, alert-warning
 * @param {string} text the alert message
 * @param {*=} selector of the div in which the alert shall be shown. default is #alerts (optional)
 */
function showAlert(alert, text, container) {
	if (typeof(container) === 'undefined') {
		container = '#alerts';
	}

	var d = new Date();
	var timestr = "";

	if (container != "#connectClientAlert") {
		timestr = d.toUTCString();
	}

	var txt = "";

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

	setTimeout(function() {
		$(container).html(txt).scrollintoview();
	}, 250);
}

function getURLParameter(name) {
  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null
}

/**
 * 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);
	}
}

function lightControlInit() {
	// 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";
	}
}

function setIsEditing(val) {
	isEditing = val;
}

function setIsSending(val) {
	isSending = val;
}

// map 0-255 level range into 0-100% range
function mapLevelToPercent(obj) {
	if (!obj || !obj.state) {
		return;
	}

	if (obj.state.bri === undefined) {
		obj.state.bri = 0;
	}

	obj.levelPercent = Math.ceil(100 * (obj.state.bri / 255));

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

// map 0-254 level range into 0-100% range
function mapSatToPercent(obj) {
	if (!obj || !obj.state) {
		return;
	}

	if (obj.state.sat === undefined) {
		obj.state.sat = 0;
	}

	obj.satPercent = Math.ceil(100 * (obj.state.sat / 254));

	if (obj.satPercent > 100) {
		obj.satPercent = 100;
	}
}

// map color temperatre range into 0-100% range
function mapCtToPercent(obj) {
	if (!obj || !obj.state) {
		return;
	}

	if (!obj.ctMin) {
		obj.ctMin = 153;
	}

	if (!obj.ctMax) {
		obj.ctMax = 500;
	}

	if (obj.state.ct === undefined) {
		obj.state.ct = obj.ctMin;
	}

	obj.ctPercent = (obj.state.ct - obj.ctMin) / (obj.ctMax - obj.ctMin) * 100;

	if (obj.ctPercent > 100) {
		obj.ctPercent = 100;
	}
}

/**
 * Sends a new state to a group or light.
 * @param  {object} obj holds all values which shall be modified
 */
function pushObjState(obj) {

	var out = {};
	var putUrl = "";

	if (obj.id === undefined) {
		return false;
	}

	out.id = obj.id;

	if (obj.on !== undefined)
		out.on = obj.on;

	if (obj.hue !== undefined)
		out.hue = obj.hue;

	if (obj.bri !== undefined)
		out.bri = obj.bri;

	if (obj.sat !== undefined)
		out.sat = obj.sat;

	if (obj.ct !== undefined)
		out.ct = obj.ct;

	if (obj.xy !== undefined)
		out.xy = obj.xy;

	if (obj.automode !== undefined)
		out.automode = obj.automode;

	if (obj.transitiontime !== undefined)
		out.transitiontime = obj.transitiontime;

	if (obj.name !== undefined)
		out.name = obj.name;

	if (obj.location !== undefined)
		out.location = obj.location;

	if (obj.type === TYPE_LIGHT) {
		putUrl = '/api/' + apikey + '/lights/' + obj.id + '/state';
	}
	else if (obj.type === TYPE_GROUP) {
		putUrl = '/api/' + apikey +  '/groups/' + obj.id + '/action';
	}
	else if (obj.type === TYPE_SCENE) {
		if (obj.action === ACTION_CALL_SCENE) {
			putUrl = '/api/' + apikey + '/groups/' + obj.rgid + '/scenes/' + obj.sid + '/recall';
		}
		else {
			console.log("unsupported scene action");
			return false;
		}
	}
	else {
		console.log("unsupported obj type");
		return false;
	}

	setIsSending(true);

	$.ajax({
		url: putUrl,
		type: 'PUT',
		contentType: 'application/json; charset=utf-8',
		data: JSON.stringify(out),
		dataType: 'json',
		cache: false,
		headers: { 'Accept': apiversion },
		success: function(data) {
			setIsSending(false);
		},
		error: function(jqXHR, textStatus, errorThrown) {
			setIsSending(false);
			if (jqXHR.status === 202) {
				// Accepted
				return;
			}

			console.log("textStatus:", textStatus + ' ' + errorThrown);
			console.log(jqXHR.responseText);
			console.log("sending state failed");
		},
		statusCode: {
			200: function(data) {
				setIsSending(false);
			}
		},
		timeout: 8000
	});

	return true;
}

function checkShowSensors() {
	var config = JSON.parse(sessionStorage.getItem("config"));

	if (config != null && config != undefined) {
		var json = config.sensors;
		var flsNBFound = false;
		var lightFound = false;

		for (var sid in json) {
			var sensor = json[sid];

			if (!sensor.type || !sensor.modelid) {
				continue;
			}

			if (!flsNBFound && sensor.modelid.indexOf("FLS-NB") !== -1) {
				flsNBFound = true;
			}

			if (sensor.type.indexOf("ZHALight") !== -1) {
				lightFound = true;
			}

			if (lightFound && flsNBFound)
				break;
		}

		if (flsNBFound) {
			$('.sensorsMenuItem').removeClass('hidden');
		} else {
			$('.sensorsMenuItem').addClass('hidden');
		}

		if (/*!flsNBFound &&*/ lightFound) {
			$('.daylightControlMenuItem').removeClass('hidden');
		} else {
			$('.daylightControlMenuItem').addClass('hidden');
		}
	}
	setTimeout(checkShowSensors, POLL_DELAY);
}

/**
 * Activate or deactivate Rules associated with this group
 * parameter status = ["enabled" | "disabled"]
 */
function changeRulesStatus(status, gid) {
	let config = null;
	try {
		config = JSON.parse(sessionStorage.getItem('config'));
	} catch(e) {
		console.log(e)
	}

	if (!config)
		return;

	const rules = config.rules || [];
	const daylightRules = _.filter(rules, x => x.name && x.name.indexOf('__delight') === 0);

	for (r in config.rules) {
		const rule = config.rules[r];
		if (!rule)
			continue;

		// only daylight control rules
		if (!rule.name || rule.name.indexOf('__delight') !== 0)
			continue;

		const actions = rule.actions || [];
		const conditions = rule.conditions || [];

		let sid = null;
		let sensorType = null;

		for (c in conditions) {
			const addr = conditions[c].address || '';
			if (addr.indexOf('/sensors') === -1)
				continue;

			sid = addr.split('/')[2];
			if (sid && sid in config.sensors) {
				sensorType = config.sensors[sid].type;
				break;
			}
		}

		if (!sid)
			continue;

		if (!sensorType)
			continue;

		let changed = false;
		for (a in actions) {
			const addr = actions[a].address || '';
			if (addr.indexOf('groups/' + gid + '/') !== -1) {
				changed = true;
				if (rule.status !== status)
					setTimeout(sendUpdateRuleRest(r, status), 200);
				break;
			}
		}
		if (changed) {
			if (status === 'enabled') {
				if (sensorType === 'ZHALightLevel') {
					$('.LightSensor[data-gid="'+ gid +'"]').html("&#9728; ");
				} else if (sensorType === 'ZHAPresence') {
					$('.PresenceSensor[data-gid="'+ gid +'"]').html("&#9852; ");
				}
			} else {
				if (sensorType === 'ZHALight') {
					$('.LightSensor[data-gid="'+ gid +'"]').html("&#9788; ");
				} else if (sensorType === 'ZHAPresence') {
					$('.PresenceSensor[data-gid="'+ gid +'"]').html("&#9853; ");
				}
			}
		}
	}
}

function sendUpdateRuleRest(rid, status) {
	$.ajax({
		url: 'api/' + apikey + '/rules/' + rid,
		dataType: 'json',
		type: 'PUT',
		cache: false,
		contentType: 'application/json; charset=utf-8',
		headers: { 'Accept': apiversion },
		data: '{"status":"' + status + '"}',
		success: function(json) {
			console.log(status + " sensor rule " + rid);
		},
		error: function(jqXHR, textStatus, errorThrown) {
		   getFullConfiguration();
				console.log("textStatus:", textStatus + ' ' + errorThrown);
				console.log(jqXHR.responseText);
		}
	});
}

$(document).ready(function() {

	if ('initApi' in window) {
		initApi();
	} else {
		console.log('api not initialized');
	}

	checkShowSensors();

	//append version number to all links
	var swVersion = "";
	if (Modernizr.localstorage && localStorage.getItem("de-gw-swVersion") != undefined) {
		swVersion = localStorage.getItem("de-gw-swVersion");
	}
	$('a').each(function(){
		if ($(this).attr('href') !== undefined) {
			var url = (($(this).attr('href')).indexOf("html") != -1) ? $(this).attr('href') : "none";
			if (url != "none") {
				$(this).attr('href',url + "?v="+swVersion);
			}
		}
	});
});
