styles/client.js Script Source View


/// <reference path="jquery.mobile-1.0b1.min.js" />
/// <reference path="jquery-1.6.4.min.js" />
/// <reference path="json2.min.js" />
confirmAsync = function (msg, callback) { callback(confirm(msg)); }
promptAsync = function (msg, input, callback) { callback(prompt(msg, input)); }
var guid_empty = "00000000-0000-0000-0000-000000000000";

function loadPref(key) {
	if(window.NC)return window.NC.getPrefString(key);
	else return localStorage[key];
}
function savePref(key, val) {
	if (window.NC) window.NC.savePrefString(key, val);
	else localStorage[key] = val;
}

var dewPointMode = (loadPref("dewPointMode") == "t");

$("<option value='5'>5 Minutes</option><option value='10'>10 Minutes</option><option value='15'>15 Minutes</option><option value='30'>30 Minutes</option><option value='60'>1 Hour</option><option value='120'>2 Hour</option><option value='240'>4 Hour</option><option value='480'>8 Hour</option><option value='720'>12 Hour</option><option value='1440'>24 Hour</option><option value='2880'>48 Hour</option>").appendTo(".apns_pause_choice");
$("<option value='0'>Just once</option><option value='600'>Every 10 Minutes</option><option value='900'>Every 15 Minutes</option><option value='1800'>Every 30 Minutes</option><option value='3600'>Every Hour</option><option value='7200'>Every 2 Hour</option><option value='14400'>Every 4 Hour</option><option value='28800'>Every 8 Hour</option>").appendTo(".rn_timespan_choice");
var rnc_open, rnc_detected, rnc_oor, rnc_cap2, rnc_toowet, rnc_toodry, rnc_toohot, rnc_toocold, rnc_toobright, rnc_toodark;

var allTagManager = (loadPref("allTagManager") == "t");
if (allTagManager) $(".allTagManagerHide").hide();
var WSROOT;
if (!window.NC) {
	
	if (window.location.href.indexOf("http://")==0 && window.location.host != "localhost") {
		window.location.replace(window.location.href.replace("http://", "https://"));
	}

	if (!$.mobile.gradeA()) window.location.href = "/eth/ie_not_supported.html";
	//WSROOT = (window.location.origin.indexOf("my") != -1) ? "/" : "https://www.mytaglist.com/";
	WSROOT = "/";
} else {
	if (window.NC.setTagManagerChoices)
		$("#mainHeader").hide();
	
	if (window.NC.getWsRoot)
		WSROOT = window.NC.getWsRoot();
	else
		WSROOT = "https://my.wirelesstag.net/";

	//WSROOT = "/";
	$(".web_only").hide();
	if (!window.NC.iftttConn) $("#ifttt_conn").hide();

	$(".android_only").show();
	$("#btnMNRegisterAgain").click(function () {
		window.NC.clearMNToken(loginEmailAddress);
		window.NC.registerMN(loginEmailAddress);
	});
}

$(".titleTooltip").click(function () {
	var btn = $(this);
	popup(btn[0].title, btn);
	return false;
});

if (location.hash.lastIndexOf("#applet-",0)==0) location.hash = "";

var VALID_EMAIL_REGEX = "^\\S+@\\S+\\.\\S+$"; //"^[^\\W][+a-zA-Z0-9\\_\\-\\.]+([+a-zA-Z0-9\\_\\-\\.]+)*\\@[-a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)*\\.[a-zA-Z]{2,4}$";
//var notificationRun = false;
var notificationQueue = new Array();
var taglist_cache = {};
var uuid2tag = {};
var tagEventStates = { 0: ["Disarmed", "c"], 1: ["Armed", "a"], 2: ["Moved", "e"], 3: ["Opened", "e"], 4: ["Closed", "a"], 5: ["Detected", "e"], 6: ["Timed Out", "a"], 7: ["Stabilizing...", "b"], 8: ["Carried Away", "b"], 9: ["In Free Fall", "p"] };
var rhEventStates = { 0: ["", "c"], 1: ["", "c"], 2: ["Normal RH", "c"], 3: ["Too Dry", "r"], 4: ["Too Humid", "f"], 9: ["", "c"] };
var capEventStates = { 0: ["", "c"], 1: ["", "c"], 2: ["Normal Moisture", "c"], 3: ["Too Dry", "r"], 4: ["Too Wet", "f"], 9: ["", "c"] };
var lightEventStates = { 0: ["", "c"], 1: ["", "c"], 2: ["Normal Light", "c"], 3: ["Too Dark", "b"], 4: ["Too Bright", "e"], 9: ["", "c"] };
var analogEventStates = { 0: ["", "c"], 1: ["", "c"], 2: ["Normal Voltage", "c"], 3: ["Too Low", "b"], 4: ["Too High", "e"], 9: ["", "c"] };
var vocEventStates = { 0: ["", "c"], 1: ["", "c"], 2: ["Normal VOC", "c"], 3: ["Low VOC", "b"], 4: ["VOC Too High", "e"], 9:["","c"] };
var tempEventStates = { 0: ["", "c"], 1: ["Normal", "c"], 2: ["Too Hot", "p"], 3: ["Too Cold", "b"], 9: ["", "c"] };
var autoRetry = true;
var lastOffline = false;
var clearNotificationJSTimer = null;
var beep_looping = false;
var maxFreqOffset = 20000;
function isMobile() {
	if (window.NC) return true;
	var ua = navigator.userAgent.toLowerCase();
	if (ua.indexOf("iphone") != -1 || ua.indexOf("ipod") != -1 || ua.indexOf("ipad") != -1 || ua.indexOf("android") != -1 || ua.indexOf("blackberry") != -1) {
		return true;
	}
	return false;
}
var device_transition = "fade"; // isMobile() ? "slide" : "fade";
String.prototype.format = function () {
	var formatted = this;
	for (var i = 0; i < arguments.length; i++) {
		var regexp = new RegExp('\\{' + i + '\\}', 'gi');
		formatted = formatted.replace(regexp, arguments[i]);
	}
	return formatted;
};
function reviveOptions(btn, wid) {
	var menu = $('<select id="_reviveOptionFor" data-native-menu="false" data-context-menu=1><option value="1">Search every 5 minutes</option><option value="2">Search every 10 minutes</option><option value="3">Search every 15 minutes</option><option value="4">Search every 20 minutes</option><option value="6">Search every 30 minutes</option><option value="12">Search every hour</option><option value="24">Search every two hour</option></select>');
	var tag = taglist_cache[wid];
	var holder = $("#updateIntervalFor-" + wid);
	menu.appendTo(holder).selectmenu();
	menu.val(tag.reviveEvery).selectmenu("refresh").selectmenu("open");

	menu.change(function () {
		var oldhtml = show_finding(btn, "Configuring...");
		$.ajax({
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn, null, exception.message); restore_finding(btn, oldhtml); },
			url: WSROOT + "ethClient.asmx/SetReviveEvery",
			data: "{id: " + tag.slaveId + ", multiple:" + $(this).val() + "}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				restore_finding(btn, oldhtml);
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				restore_finding(btn, oldhtml);
				popup_error(xhr, null, null, exception.message);
			}
		});
		return false;
	});

}

var ifttt_prov_code = null;
function ifttt_conn(conn_id) {
	if (window.NC && window.NC.iftttConn)
	{
		window.NC.iftttConn(conn_id);
	}
	else {
	/*
		if (ifttt_prov_code == null) {
			$.ajax({
				url: WSROOT + "ethClient.asmx/GetIFTTTProvisionalAccessCode",
				data: "{}",
				success: function (retval, textStatus) {
					ifttt_prov_code = retval.d;
					window.location.href = "https://ifttt.com/connect/" + conn_id + "?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + '/eth/index.html') + "&code=" + ifttt_prov_code;
				},
				error: function (xhr, textStatus, exception) {
					//popup_error(xhr, null, null, exception.message);
					console.log(exception.message);
					window.location.href = "https://ifttt.com/connect/" + conn_id + "?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + '/eth/index.html');
				}
			});
		} else {
			window.location.href = "https://ifttt.com/connect/" + conn_id + "?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + '/eth/index.html') + "&code=" + ifttt_prov_code;
		}
		*/
		window.location.href = "https://ifttt.com/connect/" + conn_id + "?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + '/eth/index.html');
	}
}
function setRssiMode(wid, enable, btn) {
	var tag = taglist_cache[wid];
	var oldhtml = show_finding(btn, "Configuring...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/SetLowPowerWOR",
		data: "{id: " + tag.slaveId + ", enable:" + enable + "}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) { popup_error(xhr, btn, null, exception.message); restore_finding(btn, oldhtml); }
	});
}

function rssiModeOptions(btn, wid) {
	var tag = taglist_cache[wid];
	var menu = $('<select id="_rssiMode" data-native-menu="false" data-context-menu=1><option value="false" title="Makes tag responsive to user commands but drains battery quicker. Initially chosen to facilitate setup." {0}>Setup Mode</option><option title="Improves battery life at the expense of slightly longer delay in tag responding to user command." value="true" {1}>Low Power Mode</option></select>'.format(
		tag.rssiMode ? '' : 'selected', tag.rssiMode ? 'selected' : ''));
	var holder = $("#moreBtnFor-" + wid);
	menu.appendTo(holder).selectmenu().selectmenu("open");
	menu.change(function () {
		if ($(this).val()=="true") {
			if (window["localStorage"] != null) {
				if (loadPref("mytaglist.rssimode.nowarning")) {
					setRssiMode(wid, true, btn);
				} else {
					var dialog= $("#rssi-mode-warning-dialog");
					if (dialog.data('simpledialog')) {
						dialog.simpledialog('open');
					} else {
						var html = "<div style='padding: 15px;'>Low Power Mode will dramatically increase tag's battery life, but expect longer delay for each user command (such as 'beep' or 'arm',) especially ";
						html += "immediately following another user command to another tag. If you wait about 5~10 seconds before sending the next command to a different tag, the delay should be similar to Setup Mode."; 
						html += "<fieldset data-role='controlgroup'><input type='checkbox' id='rssi-mode-goahead' checked><label for='rssi-mode-goahead'>No problem</label>";
						html += "<input type='checkbox' id='rssi-mode-dont-warn'><label for='rssi-mode-dont-warn'>Do not show this warning again</label></fieldset>";
						html += "<a rel='close' data-role='button' data-theme='b' href='#'>OK</a></div>";

						dialog.simpledialog({
							'mode': 'blank',
							'useDialog': false,
							'useDialogForceFalse': true, 
							'prompt': false,
							'forceInput': false,
							'useModal': true,
							pickPageTheme: 'c',
							'fullHTML': html							
						});
					}
					dialog.data('simpledialog').options.onClosed = function () {
						if ($("#rssi-mode-goahead").is(":checked")) {
							setRssiMode(wid, true, btn);
							if ($("#rssi-mode-dont-warn").is(":checked"))
								savePref("mytaglist.rssimode.nowarning", "true");
						}
					};
				}
			} else {
				setRssiMode(wid, true, btn);
			}
		} else {
			setRssiMode(wid, false, btn);
		}
		return false;
	});
}
function rebootTm(btn) {
	$.ajax({
		url: WSROOT + "ethClient.asmx/RebootTagManager",
		error: function (xhr, textStatus, exception) { popup_error(xhr, btn, null, exception.message); },
		success: function (retval) {
			popup("Please wait 30~60 seconds while your tag manager reconnects to the Internet.", btn);
		}
	});
}

function undeleteChoice(btn) {
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/GetDeletedTagList",
		success: function (retval) {
			if (retval.d.length == 0) {
				popup("No tag to undelete", btn);
			} else {
				$("#undeleteChoice").children().remove();
				var html = '<select id="_undeleteChoice" onchange="undelete($(this)); return false" data-native-menu="false" data-context-menu=1><option value="choose-one" data-placeholder="true">Choose a tag to undelete...</option>';
				for (var i = 0; i < retval.d.length; i++)
					html += ('<option value="{0}">{1} :{2}</option>').format(retval.d[i].uuid, retval.d[i].name, UserFriendlyTimeSpanString(retval.d[i].deleted));
				html += "</select>";
				$(html).appendTo("#undeleteChoice").selectmenu().selectmenu("open");
			}
		}
	});
}

var should_run_comet = true;
function NC_onPause() {
	should_run_comet = false;
	stopComet();
}
function NC_onResume() {
	should_run_comet = true;
	//alert("NC_onResume");
	createTagList();
	//$("#indexPage").trigger("pageshow");
	/*if(!getNextUpdate_xhr){
		getNextUpdate();
	}*/
}
function popupMN(title, detail, mac) {

	var html = "<div class='ui-error-debug ui-body-e'><h1>" + title + "</h1>" + detail;
	if (mac) {
		html += (' <a href="#" style="font-size:16pt; float: right; margin-right: 30px" data-ajax=0 onclick="$(\'#tagmanager_menu\').val(\'{0}\').selectmenu(\'refresh\').trigger(\'change\'); return false;">View...</a>').format(mac);
		var p=$(html+"</div>");
		p.appendTo($.mobile.pageContainer);
		$.mobile.pageContainer.click(function() {p.fadeOut(400,function() {$(this).remove();});});
	} else {
		var p=$(html+"</div>");
		p.appendTo($.mobile.pageContainer);
		$.mobile.pageContainer.click(function() {p.fadeOut(400,function() {$(this).remove();});});
		setTimeout(function() {p.fadeOut(400,function() {$(this).remove();});},(2000+title.length*50+detail.length*35));
	}
}

function scrollToView(element) {
	if (element == null || element.offset() == null) return;
	var offset = element.offset().top;
	if (!offset) return;
    var visible_area_start = $(window).scrollTop();
    var visible_area_end = visible_area_start + window.innerHeight;
	if (offset < visible_area_start) {
		$('html,body').animate({ scrollTop: offset - window.innerHeight / 20 }, 1000);
	}
	else if (offset + element.height() > visible_area_end) {
		$('html,body').animate({ scrollTop: offset + element.height() - window.innerHeight * 0.95 }, 1000);
	}
}
function focusOnTagOnly(uuid) {
	$(".ui-collapsible-contain").trigger("collapse");
	scrollToView($("#collapsible-" + uuid2tag[uuid].wid).trigger("expand"));
}
var tagToFocus = NaN;		// wid
function focusOnTag() {
	if(!isNaN(tagToFocus)) {
		window.setTimeout(function() {
			scrollToView($("#collapsible-"+tagToFocus).trigger("expand"));
			tagToFocus=NaN;
		},0);
	} 
}
function MN_onMessage(payload)
{
	if (payload == null) return;
	if (payload.uuid) {
		tagToFocus = uuid2tag[payload.uuid].wid;
	} else {
		if (allTagManager)
			tagToFocus = findTagFromSlaveIdAndMac(payload.slaveid, payload.mac).wid;
		else
			tagToFocus = payload.slaveid;
	}

    if (allTagManager || payload.mac == null || payload.mac == $("#tagmanager_menu").val())
    {
	    //popupMN(payload.alert, payload.detail, null);
	    if ($("#collapsible-" + tagToFocus).length > 0) {
	        focusOnTag();
	        if (!getNextUpdate_xhr) {
	            $.ajax({
	                url: WSROOT + "ethClient.asmx/GetTagForSlaveId",
	                data: "{slaveid: " + tagToFocus + "}",
	                headers: allTagManager ? { 'X-Set-Mac': payload.mac } : null,
	                success: function (retval, textStatus) {
	                    retval.d.notificationJS = null;
	                    updateTag(retval.d);
	                },
	                error: function (xhr, textStatus, exception) {
	                    popup_error(xhr, btn, null, exception.message);
	                }
	            });
	        }
		} 
		if (!window.MN) {		// if in Android, the push message is already displayed.
			if (payload.alert)
				popupMN(payload.alert, payload.detail);			
		}
    } else {
    	if (payload.alert)
			popupMN(payload.alert, payload.detail, payload.mac);		// in order to display "View" link.
	}

	if (payload.apnsSound && !window.MN) {
		play_ogg(payload.apnsSound);
	}
}
var loginEmailAddress;
function MN_onRegistered(event)			   // oldToken, newToken, type, phoneName
{
	if (event.isUpdate) {
		$.ajax({
			url: WSROOT + "ethMobileNotifications.asmx/UpdateToken",
			data: JSON.stringify(event),
			success: function (retval) {
				window.NC.storeMNToken(loginEmailAddress, event.newToken);
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, $.mobile.pageContainer);
			}
		});

	} else {
		promptAsync("Please pick a name for this device: ", event.phoneName, function (phoneName) {
			if (phoneName == null) return;
			event.phoneName = phoneName;
			//alert("MN_onRegistered " + JSON.stringify(event));
			$.ajax({
				url: WSROOT + "ethMobileNotifications.asmx/UpdateToken",
				data: JSON.stringify(event),
				success: function (retval) {
					window.NC.storeMNToken(loginEmailAddress, event.newToken);
					alert("This device '" + event.phoneName + "' can now receive tag notifications.");
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, $.mobile.pageContainer);
				}
			});
		});
	}
}
function MN_onUnregistered(event)	  // oldToken, type
{
	//alert("MN_onRegistered " + JSON.stringify(event));
	$.ajax({
		url: WSROOT + "ethMobileNotifications.asmx/RemoveToken",
		data: JSON.stringify(event),
		error: function (xhr, textStatus, exception) {
			popupDebug(xhr, $.mobile.pageContainer);
		}
	});
	window.NC.clearMNToken(loginEmailAddress);
}
function beep_once(vibrate_only) {
	if (window.NC) {
		window.NC.vibrate(1200);
		if (!vibrate_only)
			window.NC.beep();
		if (beep_looping) setTimeout(function () { beep_once(vibrate_only); }, 2000);
	} else {
		audioElement.volume = vibrate_only ? 0 : 1;
		audioElement.play();
	}
	return true;
}

//document.addEventListener("deviceready", function () { alert("deviceready"); }, false);
//document.addEventListener("pause", function () { alert("pause"); }, false);
//document.addEventListener("resume", function () { $("#indexPage").trigger("pagehide"); $("#indexPage").trigger("pageshow"); }, false);
//document.addEventListener("offline", function () { alert("offline"); }, false);
//document.addEventListener("online", function () { alert("online"); }, false);

$.fn.resetRoundedEdges = function () {
	if (this.length) {
		var set = this.children(":jqmData(role='collapsible')");
		set.find("a:eq(0), .ui-btn-inline:eq(0)").removeClass("ui-corner-tl ui-corner-tr ui-corner-bl ui-corner-br");
		set.jqmData("collapsible-last", false);

		set.first().find("a").eq(0).addClass("ui-corner-tl");
		set.first().find(".ui-btn-inline").eq(0).addClass("ui-corner-tr");
		set.last().find(".ui-btn-inline").eq(0).addClass("ui-corner-br");
		set.last().find("a").eq(0).addClass("ui-corner-bl");
		set.last().jqmData("collapsible-last", true);
	}
}
function escapeHtml(unsafe) {
	if (unsafe.indexOf("°") != -1) return unsafe;
	if (unsafe.indexOf("<b>") != -1) return unsafe;
	return unsafe
		.replace(/&/g, "&")
		.replace(/</g, "<")
		.replace(/>/g, ">")
		.replace(/"/g, """)
		.replace(/'/g, "'");
}
function popup(msg, btn, detail) {
	detail = detail || "";
	$(".ui-error").remove();
	if (btn !=null && btn.length==0) btn = null;
	var p=null;
	if (btn != null){
		if (btn.offset().top < 0) btn = btn.parent();
		p = $("<div class='ui-error ui-overlay-shadow ui-body-e ui-corner-all'><h1>" + escapeHtml(msg) + "</h1>" + escapeHtml( detail )+ "</div>")
							.css({ "top": btn.offset().top - 20 });
	}else{
		p = $("<div class='ui-error-debug ui-body-e'><h1>" + escapeHtml(msg) + "</h1>" + escapeHtml(detail )+ "</div>").css({ "top":0 });
		// : { "top": "40%", "position": "fixed" }
	}
	p.appendTo($.mobile.pageContainer);
	$.mobile.pageContainer.click(function () { p.fadeOut(400, function () { $(this).remove(); }); });
	setTimeout(function () { p.fadeOut(400, function () { $(this).remove(); }); }, (2000 + msg.length * 50 + detail.length * 35));
}
function popupDebug(xhr, btn) {
	if (btn.offset().top < 0) btn = btn.parent();
	var err = eval("(" + xhr.responseText + ")");
	$("<div class='ui-error-debug ui-body-e ui-corner-all'><h1>" + escapeHtml(err.Message )+ "</h1></div>")
						.css({ "top": btn.offset().top + 75 })
						.appendTo($.mobile.pageContainer)
						.click(function () { $(this).fadeOut(400, function () { $(this).remove(); }) });
}
function btnText(btn) {
	return btn.parent().find(".ui-btn-text").text();
}
function btnIconSpan(btn) {
	return btn.parent().find(".ui-icon");
}
function set_finding_text(btn, text) {
	var btn_text = btn.parent().find(".ui-btn-text");
	btn_text[0].innerHTML = text;
}
function show_finding(btn, finding_label) {
	if (btn == null) return;
	try {
		btn.button('disable');
		btn.blur();
	} catch (e) {
		try {
			btn.selectmenu('disable');
		} catch (e) {
			btn.addClass("ui-disabled");
			btn.attr('disabled', true);
		}
	}
	if (!btn.is("a")) btn = btn.parent();
	var btn_text = btn.find(".ui-btn-text");
	var oldhtml = btn_text.html();

	if (finding_label != "." && btn_text[0])
		btn_text[0].innerHTML = finding_label || "Finding...";

	var btn_icon = btn.find(".ui-icon");
	try{
		btn_icon.data("old_class", btn_icon[0].className);
		btn_icon.addClass("ui-icon-gear spin");
	}catch(e){}
	return oldhtml;
}
function restore_finding(btn, oldhtml) {
	if (btn == null) return;
	try {
		btn.button('enable');
		btn.focus();
	} catch (e) {
		try {
			btn.selectmenu('enable');
		} catch (e) {
			btn.removeClass("ui-disabled");
			btn.attr('disabled', false);
		}
	}
	if (!btn.is("a")) btn = btn.parent();
	if(oldhtml)
		btn.find(".ui-btn-text")[0].innerHTML = oldhtml;
	//btn.parent().find(".ui-icon").removeClass("ui-icon-gear spin");
	var btn_icon = btn.find(".ui-icon");
	try {
		btn_icon[0].className = btn_icon.data("old_class");
	} catch (e) { }
}

$.ajaxSetup({
	type: "POST",
	contentType: "application/json; charset=utf-8",
	data: "{}",
	cache: false,
	dataType: "json",
	xhrFields: {
		withCredentials: true
	},
	error: function (xhr, textStatus, exception) {
		try {
			popupDebug(xhr, $.mobile.pageContainer);
		} catch (e) {
			//popup("Unknown Error: " + xhr, $.mobile.pageContainer);
		}
	}
});

function popup_error(xhr, btn, tmgr, client_message, no_redirect_to_login) {
	try {
		if(!no_redirect_to_login && location.pathname.indexOf("signin.html") == -1 && location.pathname.indexOf("activate.html") == -1 && (
			(client_message != null && client_message.toLowerCase().indexOf("unauthorized") != -1) || xhr.responseText.toLowerCase().indexOf("unauthorized") != -1 || xhr.responseText.toLowerCase().indexOf("authentication failed") != -1) )
		{
			location.replace(window.location.pathname.indexOf("signin.html")!=-1 ? "signin.html" : "signin.html?ReturnUrl=" + encodeURIComponent(window.location.pathname + window.location.search));
			return;
		}

		if (xhr.responseText.length > 0) {
			var err = eval("(" + xhr.responseText + ")");
			if(tmgr)
				popup(tmgr+" "+err.Message, btn);
			else
				popup(err.Message, btn);
		}
		else if (xhr.statusText == "error") {
			popup("Please make sure your "+(window.NC?"phone":"laptop")+" is connected to the Internet", btn/*, JSON.stringify(xhr)*/);
			//popup(JSON.stringify(xhr), btn);
		}
		else {
			popup(xhr.statusText, btn);
		}
	} catch (e) {
		if (client_message) popup(client_message);
		else popup("Unknown Error: " + JSON.stringify(xhr), btn);
	}
}
function armDisarm(btn, id) {
	var tag = taglist_cache[id];
	switch (btn.val()) {
		case "1":
			armit(btn, tag); break;
		case "2":
			disarmit(btn, tag); break;
		case "4":
			msOptions(btn, tag); break;
	}
}
function armit(btn, tag) {
	var oldhtml = show_finding(btn, "Arming...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/Arm",
		data: "{id: '" + tag.slaveId + "', door_mode_set_closed: true}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
function disarmit(btn, tag) {
	var oldhtml = show_finding(btn, "Disarming...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/Disarm",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
// verb be either "Arm" or "Disarm"
function doArmSome(verb) {
	var selected = [];
	for (var id in taglist_cache) savePref(taglist_cache[id].uuid + "selected_for_arm", "0");
	$('#multi-stat-choices').find('input:checked').each(function () {
		var tag = taglist_cache[$(this).val()];
		selected.push(tag);
		savePref(tag.uuid + "selected_for_arm","1");
	});
	if (selected.length > 0) {
		var btn = $("#armdisarm-all");
		var oldhtml = show_finding(btn, verb+"ing...");
		if (allTagManager) {
			var ncalls = 0;
			for (var i = 0; i < tmgrs_cache.length; i++) {
				var slaveids = selected.filter(function (tag) { return tag.mac == tmgrs_cache[i].mac; }).map(function (tag) { return tag.slaveId; });
				if (slaveids.length == 0) continue;
				ncalls++;
				$.ajax({
					url: WSROOT + "ethClient.asmx/" + verb + "Some",
					data: JSON.stringify({ ids: slaveids, autoRetry: true }),
					headers: { 'X-Set-Mac': tmgrs_cache[i].mac },
					success: function (retval, textStatus) {
						for (var i = 0; i < retval.d.length; i++) {
							updateTag(retval.d[i]);
						}
					},
					context: tmgrs_cache[i],
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, this.name + ": ", exception.message);
					},
					complete: function () {
						ncalls--;
						if (ncalls == 0) {
							restore_finding(btn, oldhtml);
						}
					}
				});
			}
		} else {
			$.ajax({
				url: WSROOT + "ethClient.asmx/" + verb + "Some",
				data: JSON.stringify({ ids: selected.map(function (tag) { return tag.slaveId; }), autoRetry: true }),
				success: function (retval, textStatus) {
					restore_finding(btn, oldhtml);
					$.each(taglist_cache, function (id, tag) { tag._updated = false; });
					for (var i = 0; i < retval.d.length; i++) {
						updateTag(retval.d[i]);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, null, null, exception.message);
					restore_finding(btn, oldhtml);
				}
			});
		}
	}
}
function armDisarmAll(btn) {
	switch (btn.val()) {
		case "1":
			all_tag_action(btn, "ArmAll", "Arming..."); break;
		case "2":
			all_tag_action(btn, "DisarmAll", "Disarming..."); break;
		case "3":
		case "4":
			var html = "<div style='padding: 15px'><b>Choose Tags:</b><fieldset data-role='controlgroup' id='multi-stat-choices'>";
			for (var id in taglist_cache) {
				var tag = taglist_cache[id];
				if ((tag.isMsTag && tag.rev != 0x4E) || tag.isPIR || tag.isReed) {
					html += "<input type='checkbox' name='view-tag' id='view-tag-{0}' {2} value='{0}'><label for='view-tag-{0}'>{1}</label>".format(id, tag.name,
						loadPref(tag.uuid + "selected_for_arm") == "1" ? "checked" : "");
				}
			}
			html += "</fieldset><a onclick='doArmSome(\"" + (btn.val() == "3" ? "Arm" : "Disarm") + "\")' rel='close' data-role='button' data-theme='a' href='#' id='simpleclose'>"
				+ (btn.val() == "3" ? "Arm" : "Disarm") + "</a></div>";

			if (btn.data('simpledialog')) {
				btn.data('simpledialog').options.fullHTML = html;
				btn.simpledialog('refresh').simpledialog('open');
			} else {
				btn.simpledialog({
					'mode': 'blank',
					'useDialog': false,
					'useDialogForceFalse': true, 
					'prompt': false,
					'forceInput': false,
					'useModal': true,
					pickPageTheme: 'c',
					'fullHTML': html
				});
			}
			break;

	}
}

function all_tag_action(btn, action, finding_text) {
	var oldhtml = show_finding(btn, finding_text);
	if (allTagManager) {
		var ncalls = 0;
		for (var i = 0; i < tmgrs_cache.length; i++) {
			if(!tmgrs_cache[i].online)continue;
			ncalls++;
			$.ajax({
				url: WSROOT + "ethClient.asmx/" + action,
				data: "{autoRetry: " + autoRetry + "}",
				headers: { 'X-Set-Mac': tmgrs_cache[i].mac },
				success: function (retval, textStatus) {
					for (var i = 0; i < retval.d.length; i++) {
						updateTag(retval.d[i], true);
					}
				},
				context: tmgrs_cache[i],
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, null, this.name + ": ", exception.message);
				},
				complete: function () {
					ncalls--;
					if (ncalls == 0) {
						restore_finding(btn, oldhtml);
					}
				}
			});
		}
	} else {
		$.ajax({
			url: WSROOT + "ethClient.asmx/" + action,
			data: "{autoRetry: " + autoRetry + "}",
			success: function (retval, textStatus) {
				restore_finding(btn, oldhtml);

				$.each(taglist_cache, function (id, tag) { tag._updated = false; });
				for (var i = 0; i < retval.d.length; i++) {
					updateTag(retval.d[i]);
				}
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, null,null,exception.message);
				restore_finding(btn, oldhtml);
			}
		});
	}
}
function UserFriendlyCountString(count){
	if(count<1000)return count;
	else if(count<1e6)return (count/1000).toFixed(1)+"k";
	else return (count/1e6).toFixed(2)+"M";
}
function UserFriendlyTimeSpanString(filetime) {
	if (filetime == 0) return "(never updated)";
	var lastComm = new Date((filetime / 10000) - 11644473600000);
	var now = new Date();
	var diff = now.getTime() - lastComm.getTime() + serverTime2LocalTime;
	var daysDifference = Math.floor(diff / 1000 / 60 / 60 / 24);
	if (daysDifference >= 1) return daysDifference + " days ago";
	var hoursDifference = Math.floor(diff / 1000 / 60 / 60);
	if (hoursDifference >= 1) return hoursDifference + " hours ago";
	var minDifference = Math.floor(diff / 1000 / 60);
	if (minDifference >= 1) return minDifference + " min ago";
	else return Math.round(diff / 1000) + " sec ago";
}
function signalToBars(tag) {
	var dBm = tag.signaldBm + 15 * Math.log10(255 / tag.txpwr);
	if (dBm <= -115) return 0;
	else if (dBm < -90) return 1;
	else if (dBm < -83) return 2;
	else if (dBm < -76) return 3;
	else if (dBm < -69) return 4;
	else return 5;
}
function setTheme(btn, theme) {
	btn.attr("data-theme", theme).removeClass("ui-btn-up-a ui-btn-up-b ui-btn-up-c ui-btn-up-d ui-btn-up-e ui-btn-up-f ui-btn-up-p ui-btn-up-r ui-btn-hover-a ui-btn-hover-b ui-btn-hover-c ui-btn-hover-d ui-btn-hover-e ui-btn-hover-f ui-btn-hover-p ui-btn-hover-r")
			.addClass("ui-btn-up-" + theme);
}
/*function updateTagList(btn) {
	var oldhtml = show_finding(btn.children(0));
	$.ajax({
		url: WSROOT + "ethClient.asmx/UpdateAll",
		data: "{autoRetry: false}",
		success: function (retval, textStatus) {
			for (var i = 0; i < retval.d.length; i++) {
				updateTag(retval.d[i]);
			}
			restore_finding(btn.children(0), oldhtml);
		},
		error: function (xhr, textStatus, exception) {
			restore_finding(btn.children(0), oldhtml);
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
*/
function resetit(btn, wid) {
	var tag = taglist_cache[wid];
	var oldhtml = show_finding(btn);
	$.ajax({
		url: WSROOT + "ethClient.asmx/ResetTag",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
function reqPostback(btn, wid) {
	var tag = taglist_cache[wid];
	var oldhtml = show_finding(btn);
	$.ajax({
		url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml); 
		}
	});
}
var snapshot_cache = {};
function prependSnapshots(tag, snapshots) {
	var htmlBefore = "", htmlAfter = "";
	var prevDateString = null;
	var cache = snapshot_cache[tag.uuid];

	for (var i = 0; i < snapshots.length; i++) {
		var fn = snapshots[i];
		var timestamp = fileTimeToDate(fn.replace(/v|t/, ""));
		var dateString = timestamp.toLocaleDateString();

		if (dateString == cache.firstDateString) {
			htmlAfter += htmlFromSnapshot(tag, fn, timestamp);
		} else {
			if (prevDateString != dateString) {
				htmlBefore += ('<h5 class="snapshot-date">{0}</h5>').format(dateString);
				prevDateString = dateString;
			}
			htmlBefore += htmlFromSnapshot(tag, fn, timestamp);
		}
	}
	cache.latestDateTime = snapshots[0].replace(/v|t/,"");
	cache.firstDateString = fileTimeToDate(fn.replace(/v|t/, "")).toLocaleDateString();

	$(htmlAfter).insertAfter($("#snapshots-"+tag.slaveId).find(".snapshot-date").eq(0))
	$("#snapshots-" + tag.slaveId).prepend(htmlBefore).trigger("create");
}
function snapshotLoadNewer(tag) {
	if (!snapshot_cache[tag.uuid].latestDateTime) return;  // no snapshot at all. 
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/GetNewSnapshots2",
		data: JSON.stringify({ slaveId: tag.slaveId, newerThan: snapshot_cache[tag.uuid].latestDateTime, includeVideos: true }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			prependSnapshots(tag, retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null,exception.message);
		}
	});
}
function recordVideo(btn, wid) {
	var second = btn.val();
	var tag = taglist_cache[wid];

	var oldhtml = show_finding(btn, "Capturing...");
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/RecordVideo",
		data: JSON.stringify({ slaveId: tag.slaveId, second: second }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			prependSnapshots(tag, retval.d);			
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});

}
function startTimeLapse(btn, wid) {
	var tag = taglist_cache[wid];
	var oldhtml = show_finding(btn, "Starting...");
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/RecordTimeLapse",
		data: JSON.stringify({ slaveId: tag.slaveId, minute: btn.val() }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			prependSnapshots(tag, [retval.d]);
			$("#start-lapse-" + wid).hide(); $("#stop-lapse-" + wid).show();
		},
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function stopTimeLapse(btn, wid) {
	var tag = taglist_cache[wid];
	var oldhtml = show_finding(btn, "Stopping...");
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/StopTimeLapse",
		data: JSON.stringify({ slaveId: tag.slaveId}),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			prependSnapshots(tag, [retval.d]);
			$("#stop-lapse-" + wid).hide(); $("#start-lapse-" + wid).show();
		},
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}

function snapshot(btn, wid) {
	var tag = taglist_cache[wid];
	var oldhtml = show_finding(btn, "Taking...");
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/Snapshot",
		data: JSON.stringify({slaveId: tag.slaveId, number: 1}),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			prependSnapshots(tag, retval.d);
		},
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});

}
function disableZmod(btn, id) {
	var oldhtml = show_finding(btn, "Disabling...");
	var tag = taglist_cache[id];
	$.ajax({
		url: WSROOT + "ethClient.asmx/DisableZmod",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});

}
function enableZmod(btn, id) {
	var oldhtml = show_finding(btn, "Enabling...");
	var tag = taglist_cache[id];
	$.ajax({
		url: WSROOT +  "ethClient.asmx/EnableZmod" ,
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
/*			var rom = retval.d;
			if (rom != null) {
				popup("Air quality sensor {0}, taking baseline readings...".format(
					Array.from(rom, function (byte) {
						return ('0' + (byte & 0xFF).toString(16)).slice(-2);
					}).join('-')
				), btn);

			} else {
				popup("Taking baseline readings...", btn);
			}
			*/
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
function ctrlZmod(btn, id) {
	if (btn.val() == "0") {
		disableZmod(btn, id);
	} else if (btn.val() == "1") {
		if (confirm("The sensor will perform a baseline measurement when turning on. For accuracy, this must be done at a time of the day with the freshest air, or after you have placed the sensor outdoor or next to an open window. Continue?")) {
			enableZmod(btn, id);
		}
	} else if (btn.val() == "2") {
		vocOptions(btn, id);
	}
}
function togglelight(btn, id) {
	if (btn.val() == "1") {
		lightOn(btn, id);
	} else {
		lightOff(btn, id);
	}
}

function togglebeep(btn, id) {
	var tag = taglist_cache[id];
	var oldhtml = btnText(btn);
	if (oldhtml == 'Beep') {
		var menu;
		if (tag.isMsTag || tag.hasALS)
			menu = $('<select id="_beepOptionFor" data-native-menu="false" data-context-menu=1><option value=1001 selected>Until moved</option><option value=5>5 times</option><option value=10>10 times</option><option value=15>15 times</option><option value=20>20 times</option><option value=30>30 times</option><option value=1000>Until stopped</option><option value=-1>Stop beep</option></select>');
		else
			menu = $('<select id="_beepOptionFor" data-native-menu="false" data-context-menu=1><option value=5>5 times</option><option value=10>10 times</option><option value=15 selected>15 times</option><option value=20>20 times</option><option value=30>30 times</option><option value=1000>Until stopped</option><option value=-1>Stop beep</option></select>');

		var holder = btn.parent(); 
		menu.appendTo(holder).selectmenu();
		menu.val(tag.beepDurationDefault).selectmenu("refresh").selectmenu("open");
		
		menu.change(function () {
			if ($(this).val() == "-1") {
				genericSingleTagAction(btn, tag, "StopBeep", "Finding...");
			} else {
				oldhtml = show_finding(btn);
				$.ajax({
					url: WSROOT + "ethClient.asmx/Beep",
					data: "{id: '" + tag.slaveId + "', beepDuration: '" + $(this).val() + "'}",
					headers: allTagManager?{ 'X-Set-Mac': tag.mac }:null ,
					success: function (retval, textStatus) {
						restore_finding(btn, oldhtml);
						updateTag(retval.d);
					},
					error: function (xhr, textStatus, exception) {
						restore_finding(btn, oldhtml);
						popup_error(xhr, btn, null, exception.message);
					}
				});
			}
			return false;
		});

	} else if (oldhtml == "Stop Beep") {
		oldhtml = show_finding(btn);
		$.ajax({
			url: WSROOT + "ethClient.asmx/StopBeep",
			data: "{id: '" + tag.slaveId + "'}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				restore_finding(btn, "Beep");
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				restore_finding(btn, oldhtml);
				popup_error(xhr, btn, null, exception.message);
			}
		});
	}
	else if (oldhtml == "Update") {
		oldhtml = show_finding(btn);
		$.ajax({
			url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
			data: "{id: '" + tag.slaveId + "'}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				restore_finding(btn, oldhtml);
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn, null, exception.message);
				restore_finding(btn, oldhtml);
			}
		});
	}
	else if (oldhtml == "Calibrate Radio") {
		calFreqOffset(btn, tag);
	}
	else if (oldhtml == "Migrate") {
		oldhtml = show_finding(btn);
		$.ajax({
			url: WSROOT + "ethClient.asmx/RetryMigrateWirelessConfig",
			data: "{id: '" + tag.slaveId + "'}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				restore_finding(btn, tag.hasBeeper ? "Beep" : "Update");
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				restore_finding(btn, oldhtml);

				if (xhr.responseText.length > 0) {
					var err = eval("(" + xhr.responseText + ")");
					if (err.ExceptionType.indexOf("MigrationFailedException") != -1) {

						btn.simpledialog({
							mode: 'bool',
							'useDialog': false,
							'useDialogForceFalse': true, 
							prompt: "The tag did not respond to old wireless settings. It may have already completed migration. Do you want to try switching to the new wireless setting? If tag does not respond afterwards, switch back to the old setting from 'More...(>)', 'use old settings' and retry migration.",
							useModal: true, forceInput: true, cleanOnClose: true,
							'buttons': {
								'Yes, switch to the new setting': {
									click: function () {
										tag.migrationPending = false;
										SaveTagInfo(tag, btn);
									}, icon: "forward"
								},
								'No, I will migrate it later.': {
									click: function () {
									}, icon: "back"
								}
							}
						});

						return;
					}
				}
				popup_error(xhr, btn, null, exception.message);
			}
		});
	}
}
function calFreqOffset(btn, tag) {
	oldhtml = show_finding(btn);
	$.ajax({
		url: WSROOT + "ethClient.asmx/CalibrateFrequencyOffset",
		data: "{id: '" + tag.slaveId + "', readFlash: false}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, tag.hasBeeper ? "Beep" : "Update");
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			restore_finding(btn, oldhtml);
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
var marks = new Array();
function validate(event) {
	var mark_id = event.target.name + "_mark";
	var mark = $("#" + mark_id);
	if (mark.length == 0)
		mark = $("<label for=" + event.target.name + " id=" + mark_id + "> </label>").insertAfter(event.target);

	if (event.data.match) {
		if (event.target.value == $(event.data.match).val()) {
			mark.removeClass().addClass("ok");
		} else {
			mark.removeClass().addClass("error");
			popup(event.data.message, null); //$(event.target));
		}
	} else {
		if ((new RegExp(event.data.regex)).test(event.target.value)) {
			if (event.data.remote) {
				var write_retval_to = event.data.remote_retval;
				$.ajax({
					url: WSROOT + event.data.remote,
					data: "{" + event.target.name + ": '" + event.target.value + "'}",
					success: function (retval, textStatus) {
						mark.removeClass().addClass("ok");
						if (write_retval_to) {
							if ($(write_retval_to).val().length == 0)
								$(write_retval_to).val(retval.d);
						}
					},
					error: function (xhr, textStatus, exception) {
						mark.removeClass().addClass("error");
						popup_error(xhr, null, /*$(event.target),*/ null, exception.message, true);
					}
				});
			} else
				mark.removeClass().addClass("ok");

		} else {
			mark.removeClass().addClass("error");
			popup(event.data.message, null);// $(event.target));
		}
	}
}


function tag_manager_action(btn, action, data, onCompleteOne, onCompleteAll, onFailure) {
	var oldhtml = show_finding(btn, "Configuring...");
	if (allTagManager) {
		var ncalls = 0;
		for (var i = 0; i < tmgrs_cache.length; i++) {
			ncalls++;
			$.ajax({
				url: WSROOT + "ethClient.asmx/" + action,
				data: data,
				headers: { 'X-Set-Mac': tmgrs_cache[i].mac },
				success: function (retval) {
					onCompleteOne(retval);
					ncalls--;
					if (ncalls == 0) {
						restore_finding(btn, oldhtml);
						if (onCompleteAll) onCompleteAll();
					}
				},
				context: tmgrs_cache[i],
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, null, this.name + ": ",exception.message);
					ncalls--;
					if (ncalls == 0) {
						restore_finding(btn, oldhtml);
						if (onCompleteAll) onCompleteAll();
					}
					if (onFailure) onFailure();
				}
			});
		}
	} else {
		$.ajax({
			url: WSROOT + "ethClient.asmx/" + action,
			data: data,
			success: function (retval) {
				if(onCompleteOne) onCompleteOne(retval);
				if (onCompleteAll) onCompleteAll();
				restore_finding(btn, oldhtml);
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, null, null, exception.message);
				restore_finding(btn, oldhtml);
				if (onFailure) onFailure();
			}
		});
	}
}
var selectedTagManager;

function selectTagManager(mac, btn) {
	if (mac == "ALL")
	{
		savePref("allTagManager", "t"); allTagManager = true;
		$(".allTagManagerHide").hide();
		refreshNewMac();		// forces update the tag list.

	} else {
		savePref("allTagManager", "f"); allTagManager = false;
		$(".allTagManagerHide").show();
		selectedTagManager = mac;

		var new_wsRoot =  tmgrs_cache[tmgrs_index[mac]].wsRoot;

		var oldhtml = show_finding(btn, "Loading...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			url: new_wsRoot + "ethAccount.asmx/SelectTagManager",
			data: JSON.stringify({ "mac": selectedTagManager }),
			error: function (xhr, textStatus, exception) {
				if (new_wsRoot != WSROOT && new_wsRoot != (location.origin+WSROOT)) {
					$.ajax({
						url: WSROOT + "ethAccount.asmx/SelectTagManager",
						data: JSON.stringify({ "mac": selectedTagManager }),
						complete: function () { location.replace(new_wsRoot + "eth/signin.html"); }
					});
				} else {
					location.replace(new_wsRoot + "eth/signin.html"); 
				}				
			},
			success: function (retval, textStatus) {
				if (new_wsRoot != WSROOT && new_wsRoot != (location.origin + WSROOT)) {
					if (window.NC && window.NC.refreshNewMac)
						window.NC.refreshNewMac();
					location.replace(new_wsRoot + "eth/index.html"); 
				} else
					refreshNewMac();		// forces update the tag list.
			}
		});
	}
}
$("#indexPage").live("pageinit", function () {

	$("#tagmanager_menu").change(function () {
		var btn = $(this);
		selectTagManager($(this).val(), btn);
	});
	
	$("#rxFilterChoice").change(function () {
		var btn = $(this);
		var rxFilter = $(this).val();
		tag_manager_action(btn, "SetRXFilter", "{filter:" + rxFilter + "}", null, function () {
			updateMaxFreqOffset(rxFilter);
			$.each(taglist_cache, function (id, tag) { updateTag(tag) });
		});
	});
	var previous_interval;
	$("#updateInterval").focus(function () {
		previous_interval = this.value;
	}).change(function () {
		var btn = $(this);
		var newInterval = $(this).val();
		tag_manager_action(btn, "SetPostbackInterval", "{sec:" + newInterval + ",autoRetry: true}", function (retval, textStatus) {
			tmSetting.postbackInterval = newInterval;
			for (var i = 0; i < retval.d.length; i++) {
				updateTag(retval.d[i]);
			}
		}, null, function(){
			$("#updateInterval").val(previous_interval).selectmenu("refresh");
		});
	});
});

var serverTime2LocalTime = 0;

var updateSecIntervalID = 0;

$("#indexPage").live("pagecreate", function () {
	try{
		document.body.addEventListener("online", function () {
			NC_onResume();
		}, false);
	}catch(e){}

	updateSecIntervalID = setInterval(function () {

		$.each(taglist_cache, function (id, tag) {
			updateAgoString(tag);
		});
	}, 2000);

	//	clearInterval(updateSecIntervalID);
});


var focus_lost=false;
document.addEventListener("visibilitychange",(event) => {
	if(document.visibilityState=="visible") {
		if(!focus_lost||!should_run_comet||$.mobile.activePage.attr("id")!="indexPage") return;
		if(getNextUpdate_xhr==null)
			createTagList();		// this will restart tag comet
	} else {
		if(getNextUpdate_xhr) {		// since indexPage.pagebeforehide set should_run_comet = false, this means the blur was called as a result of tab change not click-based jqm page change.
			focus_lost=true;
			$.each(getNextUpdate_xhr,function(i,xhr) {
				xhr.abort();
				console.log("aborted comet")
			});
			getNextUpdate_xhr=null;
		}
	}
});

$("#indexPage").live('pagebeforehide', function () {
	if (window.NC && window.NC.enablePageSwipe) window.NC.enablePageSwipe(false);
	should_run_comet = false;
	stopComet();
});

var needRefreshTagManagers = true;
var tmgrs_cache = []; var tmgrs_index = {};
var tmgrs_dbids = {};

function refreshTagManagerDropDown(tmgrs) {
	if (tmgrs == null) return;
	tmgrs_cache = tmgrs;

	if (window.NC && window.NC.setTagManagerChoices)
	{
		var tm_names = [], tm_macs = [], tm_wsRoot=[];
		for (var i = 0; i < tmgrs.length; i++) {
			tmgrs_index[tmgrs[i].mac] = i;
			if (tmgrs[i].selected) selectedTagManager = tmgrs[i].mac;
			tm_names[i] = tmgrs[i].name + (tmgrs[i].online ? "" : " (Offline)"); 
			tm_macs[i] = tmgrs[i].mac;
			tm_wsRoot[i] = tmgrs[i].wsRoot;
		}
		if (window.NC.setTagManagerChoices2)
			window.NC.setTagManagerChoices2(JSON.stringify(tm_names), JSON.stringify(tm_macs), JSON.stringify(tm_wsRoot), selectedTagManager, allTagManager);
		else
			window.NC.setTagManagerChoices(JSON.stringify(tm_names), JSON.stringify(tm_macs), selectedTagManager, allTagManager);
	}
	else {

		var html = "";
		
		for (var i = 0; i < tmgrs.length; i++) {
			tmgrs_index[tmgrs[i].mac] = i;
			html += ('<option {0} value="{1}">{2}{3}</option>').format(!allTagManager && tmgrs[i].selected ? "selected" : "", tmgrs[i].mac, tmgrs[i].name, tmgrs[i].online ? "" : " (Offline)");
			if (tmgrs[i].selected) selectedTagManager = tmgrs[i].mac;
		}
		if (tmgrs.length > 1) {
			html += '<option ' + (allTagManager ? "selected" : "") + ' value="ALL">All Tag Managers</option>';
			$("#tagmanager_choice").show();
			$('#tagmanager_menu').html(html).selectmenu('refresh');
		} else {
			$("#tagmanager_choice").hide();
		}
	}


}
$("#referral_link").click(function () {
	window.open(WSROOT + "referral.html", "_blank", "width=700, height=750");
});
var scannedWeMo = [];
$("#WeMoLinkForm").bind("submit", function (event) {
	event.preventDefault();
	var btn = $("#WeMoLink_submitBtn");
	var oldhtml = show_finding(btn, "Updating...");
	var npending = 0;
	scannedWeMo.forEach(function (p) {
		if (p.slaveId == 0 && $("#wemo-entry-" + p.mac).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "WeMoLink.asmx/Associate",
				data: JSON.stringify({ WeMo: p }),
				success: function (retval, textStatus) {
					//updateTag(retval.d);		// needed?
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		} else if (p.slaveId != 0 && !$("#wemo-entry-" + p.mac).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "ethClient.asmx/DeleteTag",
				data: "{id: " + p.slaveId + "}",
				success: function (retval, textStatus) {
					var tag = taglist_cache[p.slaveid];
					/*if (tag) {
						delete nest_watcher[tag.thermostat.nest_auth][tag.thermostat.nest_id];
					}*/
					$("#collapsible-" + p.slaveId).remove();
					$("#taglist").resetRoundedEdges();
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		}
	});
	if (npending == 0)
		$.mobile.changePage("#indexPage", { transition: device_transition }, true);

});

var scannedHoneywellThermostats = [];
$("#addHoneywellBtn").bind("click", function (event) {
	event.preventDefault();
	var btn = $(this);
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "HoneywellLink.asmx/ScanThermostats",
		data: "{}",
		success: function (retval, textStatus) {
			scannedHoneywellThermostats = retval.d;
			var html = '<fieldset data-role="controlgroup" data-theme="c">';
			scannedHoneywellThermostats.forEach(function (p) {
				html += "<input type='checkbox' name='honeywell-entry' id='honeywell-entry-{0}' {2} value='{0}' /><label for='honeywell-entry-{0}'>{1}</label>".format(
					p.device_id, p.name + (p.renamed_to ? " (renamed to " + p.renamed_to + ")" : "") + (p.is_online ? ", online" : ", offline"), p.slaveId != 0 ? "checked" : "");
			});
			html += "</fieldset>";
			$("#edit-honeywell-link-choices").html(html).trigger('create');
			$("#honeywellLinkForm").show();
		},
		error: function (xhr, textStatus, exception) {
			//popupDebug(xhr, btn);
			honeywellLogin(btn);
		}
	});
});

$("#honeywellLinkForm").bind("submit", function (event) {
	event.preventDefault();
	var btn = $("#honeywellLink_submitBtn");
	var oldhtml = show_finding(btn, "Updating...");
	var npending = 0;
	scannedHoneywellThermostats.forEach(function (p) {
		if (p.slaveId == 0 && $("#honeywell-entry-" + p.device_id).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "HoneywellLink.asmx/Associate2",
				data: JSON.stringify({ honeywell: p, username: $("#honeywell-username").val()||null, password: $("#honeywell-password").val()||null}),
				success: function (retval, textStatus) {
					if (--npending == 0) {
						$("#honeywellLinkForm").hide();
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		} else if (p.slaveId != 0 && !$("#honeywell-entry-" + p.device_id).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "ethClient.asmx/DeleteTag",
				data: "{id: " + p.slaveId + "}",
				success: function (retval, textStatus) {
					$("#collapsible-" + p.slaveId).remove();		// not wid because scanning Honeywell is not accessible in all tag manager mode. 
					$("#taglist").resetRoundedEdges();
					if (--npending == 0) {
						$("#honeywellLinkForm").hide();
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		}
	});
	if (npending == 0)
		$.mobile.changePage("#indexPage", { transition: device_transition }, true);

});
function doScanHoneywellTCC() {
	localStorage["honeywell-username"] = $("#honeywell-username").val();
	localStorage["honeywell-password"] = $("#honeywell-password").val();

	var btn = $("#addHoneywellBtnTCC");
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "HoneywellLink.asmx/ScanThermostatsTCC",
		data: JSON.stringify({ username: $("#honeywell-username").val(), password: $("#honeywell-password").val() }),
		success: function (retval, textStatus) {
			scannedHoneywellThermostats = retval.d;
			var html = '<fieldset data-role="controlgroup" data-theme="c">';
			scannedHoneywellThermostats.forEach(function (p) {
				html += "<input type='checkbox' name='honeywell-entry' id='honeywell-entry-{0}' {2} value='{0}' /><label for='honeywell-entry-{0}'>{1}</label>".format(
					p.device_id, p.name + (p.renamed_to ? " (renamed to " + p.renamed_to + ")" : "") + (p.is_online?", online":", offline"), p.slaveId != 0 ? "checked" : "");
			});
			html += "</fieldset>";
			$("#edit-honeywell-link-choices").html(html).trigger('create');
			$("#honeywellLinkForm").show();
		},
		error: function (xhr, textStatus, exception) {
			popupDebug(xhr, btn);
		}
	});
}
$("#addHoneywellBtnTCC").bind("click", function (event) {
	event.preventDefault();
	var btn = $(this);
	if (btn.data('simpledialog')) {
		btn.simpledialog('open');
	} else {
		var html = "<div style='padding: 20px; width: 450px;'><h2 class=honeywell>Login to Honeywell Total Connect Comfort</h2>";
		html += "<div data-role='fieldcontain'><label for='honeywell-username'>Email Address:</label><input type='email' id='honeywell-username'></div>";
		html += "<div data-role='fieldcontain'><label for='honeywell-password'>Password:</label><input type='password' id='honeywell-password'></div>";

		html += "<button onclick='doScanHoneywellTCC()' rel='close' data-role='button' data-icon='arrow-r' data-theme='r' href='#'>Login</button><a rel='close' data-role='button' data-theme='c' href='#'>Cancel</a></div>";
		btn.simpledialog({
			'mode': 'blank',
			'useDialog': false,
			'useDialogForceFalse': true, 
			'prompt': false,
			'forceInput': false,
			'useModal': true,
			pickPageTheme: 'c',
			'fullHTML': html
		});

		$("#honeywell-username").val(localStorage["honeywell-username"]);
		$("#honeywell-password").val(localStorage["honeywell-password"]);

	}
});


var scannedCam = [];
$("#DropcamLinkForm").live("submit", function (event) {
	event.preventDefault();
	var btn = $("#DropcamLink_submitBtn");
	var oldhtml = show_finding(btn, "Updating...");
	var npending = 0;
	scannedCam.forEach(function (p) {
		if (p.slaveId == 0 && $("#cam-entry-" + p.uuid).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "DropCamLink.asmx/Associate",
				data: JSON.stringify({ cam: p }),
				success: function (retval, textStatus) {
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		} else if (p.slaveId != 0 && !$("#cam-entry-" + p.uuid).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "ethClient.asmx/DeleteTag",
				data: "{id: " + p.slaveId + "}",
				success: function (retval, textStatus) {
					var tag = taglist_cache[p.slaveid];
					$("#collapsible-" + p.slaveId).remove();
					$("#taglist").resetRoundedEdges();
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		}
	});
	if (npending == 0)
		$.mobile.changePage("#indexPage", { transition: device_transition }, true);
});


function doScanDropCam() {
	localStorage["dropcam-username"] = $("#dropcam-username").val();
	localStorage["dropcam-password"] = $("#dropcam-password").val();

	var btn = $("#addDropcamBtn");
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "DropCamLink.asmx/ScanDropCam",
		data: JSON.stringify({ username: $("#dropcam-username").val(), password: $("#dropcam-password").val() }),
		success: function (retval, textStatus) {
			scannedCam = retval.d;
			var html = '<fieldset data-role="controlgroup" data-theme="c">';
			scannedCam.forEach(function (p) {
				html += "<input type='checkbox' name='cam-entry' id='cam-entry-{0}' {2} value='{0}' /><label for='cam-entry-{0}'>{1}</label>".format(
					p.uuid, p.name + (p.renamed_to ? " (renamed to " + p.renamed_to + ")" : "") + " (" + (p.streaming?"Online)":"Offline)"), p.slaveId != 0 ? "checked" : "");
			});
			html += "</fieldset>";
			$("#edit-dropcam-link-choices").html(html).trigger('create');
			$("#DropcamLinkForm").show();
		},
		error: function (xhr, textStatus, exception) {
			popupDebug(xhr, btn);
		}
	});
}
$("#addDropcamBtn").live("click", function(event){
	event.preventDefault();
	var btn = $(this);
	if (btn.data('simpledialog')) {
		btn.simpledialog('open');
	} else {
		var html = "<div style='padding: 20px; width: 450px;'><h2 class=dropcam>Log in to Dropcam</h2>";
		html += "<div data-role='fieldcontain'><label for='dropcam-username'>Email:</label><input type='email' id='dropcam-username'></div>";
		html += "<div data-role='fieldcontain'><label for='dropcam-password'>Password:</label><input type='password' id='dropcam-password'></div>";
		html += "<button onclick='doScanDropCam()' rel='close' data-role='button' data-theme='t' href='#'>Log In</button><a rel='close' data-role='button' data-theme='c' href='#'>Cancel</a></div>";
		btn.simpledialog({
			'mode': 'blank',
			'prompt': false,
			'useDialog': false,
			'useDialogForceFalse': true, 
			'forceInput': false,
			'useModal': true,
			pickPageTheme: 'd',
			'fullHTML': html
		});

		$("#dropcam-username").val(localStorage["dropcam-username"] );
		$("#dropcam-password").val(localStorage["dropcam-password"]);

	}
});
function MN_onWeMoDiscovering() {
	$("#addWeMoBtnSpan").show();
	$("#noWemoHelpText").hide();
	$("#addWeMoBtn").bind("click", function (event) {
		popup("Still working to configure WeMo device(s) found. Please try clicking this button a few seconds later.");
	});
}
function MN_onWeMoDiscovered(phoneID, homeId, phoneKey) {
	$("#addWeMoBtnSpan").show();
	$("#noWemoHelpText").hide();
	$("#addWeMoBtn").unbind("click").bind("click", function (event) {
		event.preventDefault();
		var btn = $(this);
		var oldhtml = show_finding(btn, "Loading...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			url: WSROOT + "WeMoLink.asmx/ScanWeMo",
			data: JSON.stringify({homeID: homeId, phoneID: phoneID,phoneKey: phoneKey}),
			success: function (retval, textStatus) {
				scannedWeMo = retval.d;
				var html = '<fieldset data-role="controlgroup" data-theme="c">';
				scannedWeMo.forEach(function (p) {
					html += "<input type='checkbox' name='wemo-entry' id='wemo-entry-{0}' {2} value='{0}' /><label for='wemo-entry-{0}'>{1}</label>".format(
						p.mac, p.friendlyName + (p.renamed_to ? + " (renamed to " + p.renamed_to + ")" : ""), p.slaveId != 0 ? "checked" : "");
				});
				html += "</fieldset>";
				$("#edit-WeMo-link-choices").html(html).trigger('create');
				$("#WeMoLinkForm").show();
			},
			error: function (xhr, textStatus, exception) {
				popupDebug(xhr, btn);
			}
		});

	});
}
var MN_registered = false;
var initial_open_dialog = true;
function prompt_iOSapp() {
	if ((navigator.userAgent.indexOf("iPhone") != -1 || navigator.userAgent.indexOf("iPad") != -1) && !localStorage["iosapp.nowarning"] && !window.NC) {
		if ( window.location.search.length == 0 && window.location.hash.length == 0) {
			$("<div id='app_link' class='ui-error-debug ui-body-a'><h3>Install the WirelessTag iPhone/iPad app?</h3><h3><a class='ui-body-a' href='http://itunes.apple.com/us/app/wireless-tag-list/id508973799' data-ajax=0>Yes</a>    <a href='#' data-ajax=0 onclick=\"$('#app_link').remove(); localStorage['iosapp.nowarning'] = true; return false;\" class='ui-body-a' >No thanks</a></h3></div>").appendTo($.mobile.pageContainer)
				.click(function () { $(this).fadeOut(400, function () { $(this).remove(); }) });
		}
	}
}
$("#loginPage").bind('pageshow', prompt_iOSapp);
$("#indexPage").bind('pageshow', function () {
	if (window.NC && window.NC.setStatusBarColor) window.NC.setStatusBarColor("#B3B3B3");
	if (window.NC && window.NC.enablePageSwipe) window.NC.enablePageSwipe(true);
	prompt_iOSapp();

	focus_lost=false;
	should_run_comet = true;
	$.ajax({
		url: WSROOT + "ethAccount.asmx/IsSignedInEx",
		data: "{time: "+(new Date()).getTime()+"}",
		error: function (xhr, textStatus, exception) {
			if (xhr.responseText.toLowerCase().indexOf("unauthorized") != -1 || exception.toLowerCase().indexOf("unauthorized") != -1 || xhr.responseText.toLowerCase().indexOf("authentication failed") != -1)
				location.replace(window.location.pathname.indexOf("signin.html")!=-1 ? "signin.html" : "signin.html?ReturnUrl=" + encodeURIComponent(window.location.pathname + window.location.search));
			else
				popup_error(xhr, null, null, exception.message);
		},
		success: function (retval, textStatus) {
		    loginEmailAddress = retval.d.loginEmail;
		    $("#wemo_autosearch").attr("checked", !retval.d.noWemoSearch);

		    if (initial_open_dialog) {
		    	if (window.location.search == "?add_manager") {
		    		$("#btnAddNewManager").trigger("click");
		    		initial_open_dialog = false;
		    		return;
		    	}
				else if (window.location.search == "?add_honeywell") {
					$.mobile.changePage($("#addnewPage"), { transition: device_transition, role: "dialog" });
					$("#addHoneywellBtn").trigger('click');
					initial_open_dialog = false;
					return;
				}
				else if (window.location.search == "?add_nest") {
		    		$.mobile.changePage($("#addnewPage"), { transition: device_transition, role: "dialog" });
		    		$("#addNestBtn").trigger('click');
		    		initial_open_dialog = false;
		    		return;
		    	}
		    	else if (window.location.search == "?update_account") {
		    		accountOptions($("#global-settings"));
		    		initial_open_dialog = false;
		    		return;
				}
				else if (window.location.search.startsWith("?url_")) {
					var q = window.location.search.substring(5).split("&");
					if (q.length >= 5) {
						var tag = {slaveId:q[1], mac:q[2], name:q[3], uuid:q[4]}
						eventURLOptions(null, tag, q[0]);
						return;
					}
				}
		    	else if (window.location.search == "?twitter_login") {
		    		$.ajax({
		    			url: WSROOT + "ethMobileNotifications.asmx/GetTwitterAuthorizeURL",
		    			data: "{}",
		    			success: function (retval, textStatus) {
		    				if (retval.d != null) window.location.href = (retval.d);
		    			}
		    		});
		    		initial_open_dialog = false;
		    		return;
		    	}
		    }

		    if (retval.d.wsRoot != null && retval.d.wsRoot.length > 1) {
		    	WSROOT = retval.d.wsRoot;
		    	if (window.NC) {
		    		if (window.NC.updateWsRoot) window.NC.updateWsRoot(WSROOT);
		    	}
		    	//location.replace(WSROOT + 'eth/index.html'); return;
		    }

			if (serverTime2LocalTime == 0) {

				if (window.NC && !retval.d.noWemoSearch) window.NC.discoverWeMo(retval.d.phoneID, "WirelessTagAccount_" + loginEmailAddress);
				$.ajax({
					url: WSROOT + "ethClient.asmx/GetServerTime2",
					data: "{tzo: " + (new Date()).getTimezoneOffset() + "}",
					success: function (retval, textStatus) {
						var serverTime = new Date((retval.d / 10000) - 11644473600000);
						var now = new Date();
						serverTime2LocalTime = serverTime.getTime() - now.getTime();
					}
				});
			} else if (retval.d.serverTime > 0) {
				var serverTime = new Date((retval.d.serverTime / 10000) - 11644473600000);
				var now = new Date();
				serverTime2LocalTime = serverTime.getTime() - now.getTime();
			}

			updateTagManagerSettings(retval.d);

			degCmode = retval.d.temp_unit ? 0 : 1;

			/*if(!retval.d){
				location.replace("signin.html");
				return;
			}*/

			if (needRefreshTagManagers) {
				$.ajax({
					url: WSROOT + "ethAccount.asmx/GetTagManagers3",
					success: function (retval, textStatus) {

						needRefreshTagManagers = false;
						refreshTagManagerDropDown(retval.d.managers);
						if ($("#dynamicManagerLinks").length == 0) {
							$("#ifttt_hr").before(retval.d.links)
						}
					}
				});
			}
			createTagList();

			if(retval.d.messageHTML) {
				popupMN(retval.d.messageHTML, "", null);
			}

			/*$.ajax({
				url: WSROOT + "ethClient.asmx/GetTagManagerSettings",
				success: function (retval, textStatus) {
					$("#updateInterval").val(retval.d.postbackInterval).selectmenu("refresh");
					degCmode = retval.d.temp_unit ? 0:1;					
				}
			});*/
		}
	});
});
var freqTols = [4000, 8000, 15000, 25000, 35000];
function updateMaxFreqOffset(rxFilter) {
	if (rxFilter == 0) maxFreqOffset = freqTols[0];
	else if (rxFilter <= 16) maxFreqOffset = freqTols[1];
	else if (rxFilter <= 32) maxFreqOffset = freqTols[2];
	else if (rxFilter <= 48) maxFreqOffset = freqTols[3];
	else maxFreqOffset = freqTols[4];
}
var tmSetting;
function updateTagManagerSettings(d) {
	tmSetting = d;

	if (d.wsRoot != null && d.wsRoot.length > 1) {
		WSROOT = d.wsRoot;
		if (window.NC) {
			if (window.NC.updateWsRoot) window.NC.updateWsRoot(WSROOT );
		}
		//location.replace(WSROOT + 'eth/index.html'); return;     // can cause infinite redirect loop
	}

	$("#connect_suggest").val(d.connectSuggest);
	$("#updateInterval").val(d.postbackInterval).selectmenu("refresh");

	if (tmSetting.limited) {
		$(".hide-for-limited").hide();
		$("#global-settings option").filter("[value='2'],[value='3'],[value='6']").remove();
		$("#global-settings").selectmenu("refresh");
	} else {
		$(".hide-for-limited").show();
	}
	//$("#global-settings").selectmenu("refresh");

	if (d.rev >= 2 && !tmSetting.limited) {
		freqTols = d.freqTols;
		$("#rxFilterChoiceSpan").show();
		updateMaxFreqOffset(d.rxFilter);
		$("#rxFilterChoice").val(d.rxFilter).selectmenu("refresh");
	} else {
		$("#rxFilterChoiceSpan").hide();
	}
	if (d.rev < 3) {
		$(".http-verb-options").hide();
	}

}

var getDesktopPush_xhr = null;

function stopComet() {
	should_run_comet = false;

	if (getDesktopPush_xhr) {
		getDesktopPush_xhr.abort();
		getDesktopPush_xhr = null;
	}
	if (getNextUpdate_xhr) {
		$.each(getNextUpdate_xhr, function (i, xhr) {
			xhr.abort(); 
		});
		getNextUpdate_xhr = null;
	}
}
// clears the tag list, and recreate using the active selected tag manager. also updates the update interval choice. 
function refreshNewMac() {
	if (window.NC && window.NC.refreshNewMac)
		window.NC.refreshNewMac();

	if (clearNotificationJSTimer) clearTimeout(clearNotificationJSTimer);
	notificationQueue = new Array();

	stopComet();
	taglist_cache = {};
	$("#taglist").html("");
	createTagList();

	if(!allTagManager){
		$.ajax({
			url: WSROOT + "ethClient.asmx/GetTagManagerSettings",
			success: function (retval, textStatus) {
				updateTagManagerSettings(retval.d);
			}
		});
	}
}

function SaveTagInfo(tag, btn) {
	var oldhtml = show_finding(btn, "Saving...");
	var ampData_backup = tag.ampData; delete tag["ampData"];
	var thermostat_backup = tag.thermostat; delete tag["thermostat"];
	var thermostatRef_backup = tag.thermostatRef; delete tag["thermostatRef"];
	$.ajax({
		url: WSROOT + "ethClient.asmx/SaveTagInfo",
		data: JSON.stringify({ "tag": tag }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			tag = retval.d;
			tag.ampData = ampData_backup; tag.thermostat = thermostat_backup; tag.thermostatRef = thermostatRef_backup;
			updateTag(tag);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message); restore_finding(btn, oldhtml);
		}
	});
	tag.ampData = ampData_backup; tag.thermostat = thermostat_backup; tag.thermostatRef = thermostatRef_backup;
}
function pingTag(btn, tag) {
	var oldhtml = show_finding(btn, "Pinging...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/PingTag",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml); updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
function lightOn(btn, id) {
	var oldhtml = show_finding(btn, "Finding...");
	var tag = taglist_cache[id];
	$.ajax({
		url: WSROOT + "ethClient.asmx/LightOn",
		data: "{id: '" + tag.slaveId + "', flash: false}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
function lightOff(btn, id) {
	var oldhtml = show_finding(btn, "Finding...");
	var tag = taglist_cache[id];
	$.ajax({
		url: WSROOT + "ethClient.asmx/LightOff",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
			restore_finding(btn, oldhtml);
		}
	});
}
function copyURL(tb) {
	tb.previousSibling.select();
	tb.previousSibling.setSelectionRange(0, 99999); /*For mobile devices*/
	document.execCommand("copy");
	popup("Link copied. Make sure to check permission checkboxes below and click Apply Permissions.", $(tb), tb.previousSibling.value);
}
function selectedURL(tb, isMotion) {
	$(isMotion ? "#shareMotion" : "#shareTemp").attr("checked", true).checkboxradio("refresh"); return false;
}
function previewEmbedHTML(wid) {
	var tag = taglist_cache[wid];
	$.ajax({
		url: WSROOT + "ethLogs.asmx/EditSharePermissions",
		data: JSON.stringify({ "ids": [tag.slaveId], "shareTemperature": [$("#shareTemp").is(":checked")], "shareMotion": [$("#shareMotion").is(":checked")] }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function () {
			$("#embdedHTMLPreview").html($("#embedHTML").val());
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message);
		}
	});
}
function shareTag(btn, id) {
	var tag = taglist_cache[id];
	if (btn.val() == "3") {
		window.open("https://www.facebook.com/dialog/feed?display=popup&app_id=1519065224973451&link=http%3A%2F%2Fwww.wirelesstag.net&caption=Wireless%20Sensor%20Tags&picture=http://mytaglist.com/eth/tags/"
				+ tag.uuid + ".jpg&description=" + $("#tagstatline-" + id).text() +
			"&name=" + tag.name + "&message=Add+a+comment&actions=[{link%3A%22http%3A%2F%2Fwirelesstags.myshopify.com%2Fcollections%2Fall%22%2C+name%3A+%22Buy%22+}]&redirect_uri=https%3A%2F%2Fwww.mytaglist.com%2Feth%2FclosePopup.html", "_blank", "width=500, height=500");

		return;
	}
	var isMotion = (btn.val() == "2");
	var isLight = (btn.val() == "4");
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		url: WSROOT + "ethLogs.asmx/GetSharePermissions",
		data: JSON.stringify({ "ids": [tag.slaveId], "type": isMotion ? "motion" : (isLight ? "light" : "temperature") }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		complete: function () { restore_finding(btn, oldhtml); },
		success: function (retval, textStatus) {
			shareInfo = retval.d;
			var copy_icon = '<svg onclick="copyURL(this);" style="width:24px;height:24px;padding-left:4px;vertical-align:text-bottom" viewBox="0 0 24 24"><path fill="#888" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" /></svg >'

			var html = "<div style='padding: 15px; width: " + (window.innerWidth - 200) + "px'><b>Share this data</b>" +
				"<div data-role='fieldcontain'><label for='graphURL'>Link to open graph in Web:</label><input type='text' id='graphURL'>" + copy_icon + "</div>" +
				"<div data-role='fieldcontain'><label for='downloadURL'>CSV download link:</label><input type='text' id='downloadURL'>" + copy_icon + "</div>"+
				"<div data-role='fieldcontain'><label for='iosURL'>Link to open graph in iOS app:</label><input type='text' id='iosURL'>" + copy_icon + "</div>"+
				"<div data-role='fieldcontain'><label for='embedHTML'>HTML to embed latest readings:</label><input type='text' id='embedHTML'>" + copy_icon + "<button onclick='previewEmbedHTML("+id+")' data-theme='d'>Preview HTML</button></div><div id='embdedHTMLPreview'></div>"+
			"<form><center><input type='checkbox' id='shareTemp' ><label for='shareTemp'>Anyone with link can access temperature/humidity/lux data for this tag</label>"+
			"<input type='checkbox' id='shareMotion' ><label for='shareMotion'>Anyone with link can access motion log data for this tag</label>" +
			"<a rel='close' data-role='button' data-theme='b' data-inline=1 href='#'>Apply Permissions</a></center></form></div>";

			var holder = $("#taglist");
			if (holder.data('simpledialog')) {
				holder.data('simpledialog').options.fullHTML = html;
				holder.simpledialog('refresh').simpledialog('open');
			} else {
				holder.simpledialog({
					'mode': 'blank',
					'left': 80, 'top': '0px',
					'prompt': false,
					'useDialog': false,
					'useDialogForceFalse': true, 
					'forceInput': false,
					'useModal': true,
					pickPageTheme: 'c',
					'fullHTML': html
				});
			}

			holder.data('simpledialog').options.onClosed = function () {
				if (shareInfo.shareMotion[0] != $("#shareMotion").is(":checked") || shareInfo.shareTemperature[0] != $("#shareTemp").is(":checked")) {
					$.ajax({
						url: WSROOT + "ethLogs.asmx/EditSharePermissions",
						data: JSON.stringify({ "ids": [tag.slaveId], "shareTemperature": [$("#shareTemp").is(":checked")], "shareMotion": [$("#shareMotion").is(":checked")] }),
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				}
			};

			$("#shareMotion").attr("checked", shareInfo.shareMotion[0]).checkboxradio("refresh");
			$("#shareTemp").attr("checked", shareInfo.shareTemperature[0]).checkboxradio("refresh");
			$("#graphURL").val(shareInfo.graphUrl).click(function () { return selectedURL(this,isMotion );});
			$("#downloadURL").val(shareInfo.downloadUrl).click(function () { return selectedURL(this, isMotion); });
			$("#iosURL").val(shareInfo.iosAppUrl); //.click(function () { return selectedURL(this, isMotion); });
			$("#embedHTML").val(shareInfo.embedHTML); //.click(function () {return selectedURL(this,isMotion);});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message);
		}
	});
}
function editComment(btn, id) {
	var tag = taglist_cache[id];
	promptAsync("Tag comment:", tag.comment, function (newname) {
		if (newname == null) return;
		tag.comment = newname;
		SaveTagInfo(tag, btn);
	});
}

var stat_url;
function open_indiv_graph(tag, onready) {
	if (allTagManager && selectedTagManager != tag.mac) {
		$.ajax({
			url: WSROOT + "ethAccount.asmx/SelectTagManager",
			data: JSON.stringify({ "mac": selectedTagManager = tag.mac }),
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn, null, exception.message); },
			success: function (retval, textStatus) {
				onready();
			}
		});
	} else {
		onready();
	}
}
function indiv_tempGraph(id, als){
	var tag = taglist_cache[id];
	if (window.NC) {
		if (window.NC.tempGraphUuid) {
			if (als)
				window.NC.tempGraphUuidALS(tag.uuid, tag.name);			
			else if (tag.isTcProbe && (tag.rev & 0xF) == 0xF)
				window.NC.tempGraphUuidChipTemp(tag.uuid, tag.name);
			else
				window.NC.tempGraphUuid(tag.uuid, tag.name, dewPointMode);			
		} else {
			open_indiv_graph(tag, function () {
				if (als)
					window.NC.tempGraphALS(tag.slaveId, tag.name);
				/*else if (tag.hasZmod) {
					if (window.NC.tempGraphZmod) window.NC.tempGraphZmod(tag.slaveId, tag.name);
					else window.NC.tempGraphALS(tag.slaveId, tag.name);
				}*/
				else if (window.NC.tempGraphChipTemp && tag.isTcProbe && (tag.rev & 0xF) == 0xF)
					window.NC.tempGraphChipTemp(tag.slaveId, tag.name);
				else
					window.NC.tempGraph(tag.slaveId, tag.name, dewPointMode);
			});
		}
	} else {
		var p = {
			slaveid: (allTagManager && selectedTagManager != tag.mac) ? tag.uuid : tag.slaveId,
			name: tag.name, hasALS: (als ? "true" : null), //hasZmod: (tag.hasZmod ? "true" : null),
			isFlat: tag.hasFlat?"true":null, 
			hasChipTemp: ((tag.isTcProbe && ((tag.rev & 0xF) == 0xF))&&!tag.shorted ? "true" : null),
			isMoisture: tag.isMoistureTag,
			isWME: ((tag.isTcProbe && ((tag.rev & 0xF) == 0xE)) ? "true" : null)
			/*, tempBL: tag.tempBL, capBL: tag.capBL, luxBL: tag.luxBL*/
		};		
		stat_url = WSROOT+"eth/tempStats.html?" + jQuery.param(p);
		if (isMobile()) location.href = stat_url;
		else pcOpenStats(stat_url);
	}
}
function indiv_stats(btn, id) {
	switch(btn.val()){
		case "5":
			var tag = taglist_cache[id];
			if (window.NC && window.NC.multiGraphUuids)
			{
				window.NC.multiGraphUuids("\""+tag.uuid+"\"", "motion");
			} else {
				var p = {
					slaveid: (allTagManager && selectedTagManager != tag.mac) ? tag.uuid : tag.slaveId,
					name: tag.name
				};
				stat_url = "stats.html?" + jQuery.param(p);

				if (isMobile()) location.href = stat_url;
				else window.open(stat_url, "_blank");
			}
			break;

		case "51":
			indiv_tempGraph(id, false);
			break;
		case "52":
			indiv_tempGraph(id, true);
			break;
	}
}
function advanced(btn, id) {
	var tag = taglist_cache[id];
	var newname = null;
	switch (btn.val()) {
		case "21":
			mnOptions(btn, tag); break;
		case "30":
			messageOptions(btn, tag); break;
		case "62":
			var log_url = WSROOT+"webcams/" + (tag.thermostat.honeywell_device_id == 0 ? tag.thermostat.nest_id : tag.thermostat.honeywell_device_id) + ".txt";
			if (isMobile()) location.href = (log_url);
			else window.open(log_url, "_blank");
			break;
		case "-1":
			msOptions(btn, tag); break;
		case "31":
			eventURLOptions(btn, tag); break;
		//case "32":
			//readTagTypeInfo(btn, id); break;
		case "1":
			promptAsync("New tag name:", tag.name, function (newname) {
				if (newname) {
					tag.name = newname;
					SaveTagInfo(tag, btn);
				}
			});
			break;
		
		case "3":
			if(confirm("Wipe tag's flash memory to allow it to be associated with another tag manager, under a new ID. When a tag is unpaired, captured temperature/event log data on cloud will be hidden, then permanently removed after six months, until you undelete the tag, or use 'Settings' -> 'Move Data' to move these data under a new tag. Continue?")){
				var oldhtml = show_finding(btn, "Unpairing...");
				$.ajax({
					complete: function () { restore_finding(btn, oldhtml); },
					url: WSROOT + "ethClient.asmx/UnassociateTag",
					data: "{id: '" + tag.slaveId + "'}",
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					success: function (retval, textStatus) {
						var tag = retval.d; restoreTagWid(tag);
						if (tag.alive) {
							$("#collapsible-" + tag.wid).remove();
							$("#taglist").resetRoundedEdges();
						} else {
							var holder = $("#collapsible-" + tag.wid);
							if (holder.data('simpledialog')) {
								holder.simpledialog('open');
							} else {
								holder.simpledialog({
									mode: 'bool',
									'useDialog': false,
									'useDialogForceFalse': true, 
									prompt: "Tag failed to respond to unpair request. If tag is not flashing and you remove, you will need to undelete to regain access. Do you want to remove it from list?",
									useModal: true, forceInput: false, cleanOnClose: false,
									'buttons': {
										'Yes, remove': {
											click: function () {

												stopComet();

												$.ajax({
													url: WSROOT + "ethClient.asmx/DeleteTag",
													data: "{id: " + tag.slaveId + "}",
													headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
													complete: function () {
														getNextUpdate();
														getDesktopPush();
													}
												});
												$("#collapsible-" + tag.wid).remove();
												$("#taglist").resetRoundedEdges();
											}, icon: "forward"
										},
										'Cancel': {
											click: function () {
												//$.mobile.changePage("#indexPage", {transition: "slidedown"}, true);
											}, icon: "back"
										}
									}
								});
							}

						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn, null, exception.message);
					}
				});
			}
			break;

		case "4":
			tag.migrationPending = !tag.migrationPending;
			SaveTagInfo(tag, btn);
			break;

		case "11":
			rssiModeOptions(btn, id);
			break;
		case "12":
			calFreqOffset(btn, tag);
			break;
		case "14":
			v2flagOptions(tag);
			break;
		case "6":
			genericSingleTagAction(btn, tag, "SoftwareResetTag", "Resetting...");
			break;
		case "9":
			genericSingleTagAction(btn, tag, "SecondaryArm", "Recording...");
			break;
		case "10":
			genericSingleTagAction(btn, tag, "SecondaryDisarm", "Erasing...");
			break;
	}
	return true;
}
function closeGraph() {
	if (isMobile()) history.back();
	else window.close();
}

function genericSingleTagAction(btn, tag, method, progress) {
	var oldhtml = show_finding(btn, progress);
	$.ajax({
		url: WSROOT + "ethClient.asmx/" + method,
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml); updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message); restore_finding(btn, oldhtml);
		}
	});
}
function updateAgoString(tag) {
	try {
		var agostring = UserFriendlyTimeSpanString(tag.lastComm);
		$("#lasttalk-" + tag.wid).text(agostring);
		if (tempDispMode == 2)
			$("#temp-display-" + tag.wid).html(agostring.replace("ago", ""));
	} catch (e) { }
}

function play_tagname(uuid, suffix) {
	if (window.NC) {
		window.NC.playTwoMediaUrl(window.NC.getWsRoot() + "eth/audio/" + uuid + ".mp3", suffix.src);
	} else {
		var tagMp3 = document.createElement('audio');
		tagMp3.src = "audio/" + uuid + ".mp3";
		tagMp3.type = "audio/mpeg";
		tagMp3.volume = 1;
		tagMp3.load();
		//	alert(tagMp3.src + " " + suffix.src);
		tagMp3.addEventListener('ended', function () { suffix.load(); suffix.type = "audio/mpeg"; suffix.volume = 1; suffix.play(); }, false);
		tagMp3.play();
	}
	return true;
}
function beep_oor(vibrate_only) {
	return beep_once(vibrate_only);
}
function start_beep(vibrate_only) {
	beep_looping = true;
	audioElement.addEventListener('ended', function () { if (beep_looping) beep_once(vibrate_only); }, false);
	beep_once(vibrate_only);
	//beep_loop_id = setInterval(function () { beep_once(vibrate_only); }, 2000);
	return true;
}
function stop_beep() {
	beep_looping = false;
	return true;
}
var wavefile_loaded = false;
var is_open, is_open_for_too_long, is_closed, is_out_of_range, is_back_in_range, has_moved, is_low_battery;
var temp_normal, temp_toohigh, temp_toolow, too_dry, too_humid, cap_normal, detected_water, no_longer_detected_water, silence;
var light_normal, light_toobright, light_toodark;
//var amp_normal, amp_toohigh, amp_toolow;
var analog_toolow, analog_toohigh, analog_normal;
var detected_movement, timed_out, carried_away, in_free_fall;
var is_disconnected;
//var is_online, is_offline;
var audioElement;

function play_ogg(ogg) {
	try {
		var a = document.createElement('audio'); a.type = "audio/ogg"; a.src = 'ringtone/' + ogg + '.ogg';
		a.play();
	}
	catch (e)
	{ }
}

function load_wavefile() {
	audioElement = document.createElement('audio'); audioElement.type = "audio/wav"; audioElement.src = 'styles/beep.wav';
	audioElement.load();
	is_open = document.createElement('audio'); is_open.src = WSROOT + 'eth/styles/is_open.mp3';
	is_open_for_too_long = document.createElement('audio'); is_open_for_too_long.src = WSROOT + 'eth/styles/is_open_for_too_long.mp3';
	is_closed = document.createElement('audio'); is_closed.src = WSROOT + 'eth/styles/is_closed.mp3';
	is_out_of_range = document.createElement('audio'); is_out_of_range.src = WSROOT + 'eth/styles/is_out_of_range.mp3';
	is_back_in_range = document.createElement('audio'); is_back_in_range.src = WSROOT + 'eth/styles/is_back_in_range.mp3';
	is_low_battery = document.createElement('audio'); is_low_battery.src = WSROOT + 'eth/styles/is_low_battery.mp3';

	has_moved = document.createElement('audio'); has_moved.src = WSROOT + 'eth/styles/has_moved.mp3';
	temp_normal = document.createElement('audio'); temp_normal.src = WSROOT + 'eth/styles/returned_to_normal_temperature.mp3';
	temp_toohigh = document.createElement('audio'); temp_toohigh.src = WSROOT + 'eth/styles/exceeded_upper_temp_limit.mp3';
	temp_toolow = document.createElement('audio'); temp_toolow.src = WSROOT + 'eth/styles/exceeded_lower_temp_limit.mp3';
	too_dry = document.createElement('audio'); too_dry.src = WSROOT + 'eth/styles/is_too_dry.mp3';
	too_humid = document.createElement('audio'); too_humid.src = WSROOT + 'eth/styles/is_too_humid.mp3';
	cap_normal = document.createElement('audio'); cap_normal.src = WSROOT + 'eth/styles/returned_to_normal_humidity.mp3';
	detected_water = document.createElement('audio'); detected_water.src = WSROOT + 'eth/styles/detected_water.mp3';
	no_longer_detected_water = document.createElement('audio'); no_longer_detected_water.src = WSROOT + 'eth/styles/no_longer_detected_water.mp3';
	silence = document.createElement('audio'); silence.src = WSROOT + 'eth/styles/silence.mp3';
	light_normal = document.createElement('audio'); light_normal.src = WSROOT + 'eth/styles/returned_to_normal_brightness.mp3';
	light_toobright = document.createElement('audio'); light_toobright.src = WSROOT + 'eth/styles/is_too_bright.mp3';
	light_toodark = document.createElement('audio'); light_toodark.src = WSROOT + 'eth/styles/is_too_dark.mp3';

	analog_normal = document.createElement('audio'); analog_normal.src = WSROOT + 'eth/styles/returned_to_normal_voltage.mp3';
	analog_toohigh = document.createElement('audio'); analog_toohigh.src = WSROOT + 'eth/styles/is_too_high_voltage.mp3';
	analog_toolow = document.createElement('audio'); analog_toolow.src = WSROOT + 'eth/styles/is_too_low_voltage.mp3';

	//voc_normal = document.createElement('audio'); voc_normal.src = WSROOT + 'eth/styles/returned_to_normal_voc.mp3';
	//too_smelly = document.createElement('audio'); too_smelly.src = WSROOT + 'eth/styles/is_too_smelly.mp3';
	//too_fresh = document.createElement('audio'); too_fresh.src = WSROOT + 'eth/styles/is_too_fresh.mp3';

	//amp_normal = document.createElement('audio'); amp_normal.src = WSROOT + 'eth/styles/returned_to_normal_current.mp3';
	//amp_toohigh = document.createElement('audio'); amp_toohigh.src = WSROOT + 'eth/styles/exceeded_upper_current_limit.mp3';
	//amp_toolow = document.createElement('audio'); amp_toolow.src = WSROOT + 'eth/styles/exceeded_lower_current_limit.mp3';
	detected_movement = document.createElement('audio'); detected_movement.src = WSROOT + 'eth/styles/detected_movement.mp3';
	timed_out = document.createElement('audio'); timed_out.src = WSROOT + 'eth/styles/timed_out.mp3';
	carried_away = document.createElement('audio'); carried_away.src = WSROOT + 'eth/styles/carried_away.mp3';
	in_free_fall = document.createElement('audio'); in_free_fall.src = WSROOT + 'eth/styles/in_free_fall.mp3';
	is_disconnected = document.createElement('audio'); is_disconnected.src = WSROOT + 'eth/styles/is_disconnected.mp3';
	//is_online = document.createElement('audio'); is_online.src = WSROOT + 'eth/styles/is_online.mp3';
	//is_offline = document.createElement('audio'); is_offline.src = WSROOT + 'eth/styles/is_offline.mp3';
	wavefile_loaded = true;
}
function start_process_notification_queue() {
	if (notificationQueue.length == 0) {
		return;
	}
	var tag = notificationQueue[0];

	if (!wavefile_loaded) load_wavefile();
	eval(tag.notificationJS);
	clearNotificationJSTimer = setTimeout(function () {
		$.ajax({
			url: WSROOT + "ethClient.asmx/ClearNotificationJSFor",
			data: JSON.stringify({ "slaveid": tag.slaveId }),
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			error: function (xhr, textStatus, exception) {
			}
			//complete: function () {				notificationRun = false; 			}
		});
		clearNotificationJSTimer = null;
		notificationQueue.shift();
		start_process_notification_queue();
	}, (tag.notificationJS.indexOf("popup") == -1)?5000:0);
}

function tempDispClick(e) {
	e.stopPropagation();
	tempDispMode = (tempDispMode + 1) % 4;
	if (window.localStorage) window.localStorage["tempDispMode"] = tempDispMode;
	$.each(taglist_cache, function (id, tag) {
		$("#temp-display-" + tag.wid).html(tempDisp(tag));
	});
}
var tempDispMode; // temp, RH, updated, batteryVolt
if (window.localStorage["tempDispMode"])
	tempDispMode = parseInt(window.localStorage["tempDispMode"]);
else
	tempDispMode = 0;

function tempDisp(tag) {
	if (tempDispMode == 0) {
		if (tag.rev >= 11 && tag.temperature) {
			if (degCmode)
				return tag.temperature.toFixed(1) + "°C";
			else
				return (tag.temperature * 9 / 5 + 32).toFixed(1) + "°F";
		} else if (tag.thermostat != null) {
			if (degCmode)
				return tag.temperature.toFixed(1) + "°C";
			else
				return (tag.temperature * 9 / 5 + 32).toFixed(1) + "°F";
		} else
			return "";
	} else if (tempDispMode == 1) {
		return tag.cap.toFixed(1) + "%";
	} else if (tempDispMode == 2) {
		return UserFriendlyTimeSpanString(tag.lastComm).replace("ago","");
	} else {
		return tag.batteryVolt.toFixed(2) + "V";
	}
}
function ds18state(tag) {
	if (tag.isTcProbe) {
		if (tag.isThermocouple)
		{
			if(tag.shorted) {  // indicates I2C mode
				return tag.az2==1? " (SHT3x)":" (SHT20)";  // bit 0 indicates in I2C mode if it is SHT3x or SHT20
			} else if(!tag.ds18&&(tag.az2&2)!=0) { // bit 1 indicates ktype not connected
				return " (Ambient, No Probe)";
			} else {
				if(tag.az2==0) {   // DS18 mode with internal temp
					var internal_temp="<b>"+(degCmode? tag.cap.toFixed(1)+"°C":(tag.cap*9/5+32).toFixed(1)+"°F")+"</b>";
					return (tag.ds18? " (DS18) ":" (k-Type) ")+internal_temp+" (Ambient)";
				} else {  // RCO mode with internal temp
					return " (Ambient) "+tag.cap.toFixed(1)+"% (Soil Moisture)";
				}
			}
		}
		else if (tag.isExternalDS18Probe) {
			if(tag.ds18) {
				if(tag.az2==0)
					return " (DS18B20)";
				else {
					return " (DS18B20) "+tag.cap.toFixed(1) + "% (Soil Moisture)";
				}
			}
			else if (tag.shorted) return tag.az2 == 1 ? " (SHT3x)" : " (SHT20)";
			else return " (No Probe)";
		} else
			return tag.ds18 ? " (DS18) " : " (Internal)";
	}else if (tag.isReed) {
		if (tag.ds18) return " (External)";			
		else return " (Internal)";
	}
	else if (tag.tagType == 21) return " (PRO)";
	else return "";
}
function tagVer(tag) {
	if (tag.version1 == 2) {
		if (tag.rev == 14) return " (v2.1)";
		else if (tag.rev == 15) return " (v2.2)";
		else if (tag.rev == 0x1F) return " (v2.3)";
		else if (tag.rev == 0x20) return " (v2.4)";
		else if (tag.rev > 0x20) return " (v2.5)";
		else return " (v2.0)";
	}
	else if (tag.version1 == 3) {
		return "(v3.0)";
	}
	else if (tag.version1 == 4) {
		return "(v4.0)";
	}
	if (tag.tagType != 12) return "";
	if (tag.rev == 0) return " (v1.1)";
	else if (tag.rev == 1) return ' (v1.2)';
	else if (tag.rev == 11) return " (v1.3)";
	else if (tag.rev == 12) return " (v1.4)";
	else if (tag.rev == 13) return " (v1.5)";
	else return "";
}
function isLowBattery(tag) {
	return tag.batteryVolt < (tag.useCoinCell ? tempCorr(tag.LBTh, tag.temperature) : tag.LBTh); 
}
function calculateTagStatus(tag, isMsTag, isMoistureTag, isCurrentTag, isHTU, isFlat) {
	//if ((tag.rev & 0xF)==0xE && tag.rev>= 0x4E) isMsTag = false;

	if (tag.isWeMoLED) {
		return tag.lit ? " (On " + tag.cap.toFixed(0) + "%)" : " (Off)";
	}else if (tag.isWeMo) {
		return tag.lit ? " (On)" : " (Off)";
	} else if (tag.isCam) {
		return tag.lit ? " (Streaming)" : " (Off)";
	}
	var tag_status = tag.OutOfRange ? "(Out of range)" : isMsTag ? "(" + tagEventStates[tag.eventState][0] + (tag.az2 == 2 ? " 2D)" : ")") : "";
	if (tag.isNest)
		tag_status = tag.eventState == 5 ? " (Home)" : " (Away)";
	else if (tag.thermostat != null)
		tag_status = tag.eventState == 5 ? " (ON)" : " (OFF)";

	if (tag.slaveId >= 0 && isLowBattery(tag)) tag_status += " (Battery Low)";

	if (isMoistureTag)
	{
		if (tag.shorted) tag_status += " (Water Detected)";
		if(tag.capEventState>=2)tag_status += (" ("+capEventStates[tag.capEventState][0]+")");
	}
	else if (isFlat) {
		if (tag.shorted) tag_status += " (Water Detected)";
		if (tag.capEventState >= 2) tag_status += (" (" + analogEventStates[tag.capEventState][0] + ")");
	}
	else if (isHTU)
	{
		if(tag.capEventState>=2)tag_status += (" ("+rhEventStates[tag.capEventState][0]+")");
	}	
	if (tag.tempEventState == 2) tag_status += " (Too Hot)";
	else if (tag.tempEventState == 3) tag_status += " (Too Cold)";

	if (tag.hasALS) {
		if (tag.lightEventState == 3) tag_status += " (Too Dark)";
		else if (tag.lightEventState == 4) tag_status += " (Too Bright)";
	}
	/*else if (tag.hasZmod) {
		if (tag.lightEventState == 3) tag_status += " (Low VOC)";
		else if (tag.lightEventState == 4) tag_status += " (VOC Too High)";
	}*/
	if (tag.playback != null) tag_status += playbackStatus(tag.playback);
	return tag_status;
}
function playbackStatus(playback) {
	return " - Uploading data: " + playback.receivedPoints + "/" + playback.totalPoints;
}
function calculateTagTheme(tag) {
	var ampEventState = tag.ampData == null ? 0 : tag.ampData.eventState;
	if (tag.tempEventState == 2) return "p";
	if (tag.tempEventState == 3) return "b";

	if (tag.lightEventState == 3) return "b";
	if (tag.lightEventState == 4) return "e";

	if (tag.hasFlat) {
		if (tag.capEventState == 4) return "e";
		if (tag.capEventState == 3) return "b";
		else if (tag.shorted) return "f";
		else return "c";
	} else {
		if (tag.capEventState == 4) return "f";
		if (tag.capEventState == 3) return "r";
	}

	if (tag.isCam) {
		if (tag.lit) return "t";
		else return "d";
	}else
	if (tag.isWeMo) {
		if (tag.lit) return "f";
		else return "c";
	}
	else if (tag.thermostat != null)
	{
		if (tag.eventState == 5) return "t";
		else return "a";
	}
	return tagEventStates[tag.eventState][1];
}
function dewPoint(RH, T) {
	var b = 17.67, c = 243.5;
	var u = Math.log(RH / 100.0) + b * T / (c + T);
	return c * u / (b - u);
}
function rhDisplay(tag) {
	if (!dewPointMode || tag.temperature==0.0) {
		return tag.cap.toFixed(1) + "%";
	}
	var dp = dewPoint(tag.cap, tag.temperature);
	return (degCmode ? dp.toFixed(1) + "°C" : Math.round(dp * 9 / 5 + 32).toFixed(1) + "°F");
}
var wid_counter = 0;

function restoreTagWid(tag) {
	if (!tag.hasOwnProperty("wid")) {
		if (allTagManager) {
			var ot = uuid2tag[tag.uuid];
			if (ot) {
				tag.wid = ot.wid; tag.mac = ot.mac;
			} else
				tag.wid = wid_counter++;
		}
		else tag.wid = tag.slaveId;
	}
}
function updateTag(tag, dont_play_notificationJS) {

	tag.isMsTag = (tag.tagType == 12 || tag.tagType == 13 || tag.tagType == 21 || tag.tagType == 26);
	if ((tag.rev & 0xF) == 0xE && tag.rev >= 0x4E) tag.isMsTag = false;

	tag.hasALS = (tag.tagType == 26 || tag.tagType==107);
	tag.isMoistureTag = tag.tagType == 32;
	tag.isFlat = (tag.tagType == 34);
	tag.isWMETag = false;
	tag.hasBeeper = (tag.tagType == 13 || tag.tagType == 12 || tag.tagType == 21 || tag.tagType==26);
	tag.isReed = (tag.tagType == 52 || tag.tagType == 53);
	tag.isPIR = (tag.tagType == 72);
	tag.isKumostat = (tag.tagType == 62);
	tag.hasEventLog = tag.isMsTag || tag.isReed || tag.isPIR;
	tag.isNest = tag.thermostat != null && tag.thermostat.nest_id != null;
	tag.isWeMo = (tag.tagType == 82);
	tag.useCoinCell = !(tag.tagType == 102 || tag.tagType == 106 || tag.tagType == 107 || tag.tagType == 42);
	tag.isWeMoLED = tag.isWeMo && (tag.cap > 0);
	tag.isCam = (tag.tagType == 92);

	//tag.hasZmod = (tag.tagType == 106);
	tag.hasFlat = (tag.tagType == 34);

	if(tag.isWeMo){
		tag.primaryLightLabel = "On";
		tag.secondaryLightLabel = "Off";
		tag.LightOnTheme = "f";
	} else if (tag.isCam) {
		tag.primaryLightLabel = "Streaming On";
		tag.secondaryLightLabel = "Streaming Off";
		tag.LightOnTheme = "t";
	} else {
		tag.primaryLightLabel = "Light On";
		tag.secondaryLightLabel = "Light Off";
		tag.LightOnTheme = "b";
	}

	tag.hasTempSensor = !tag.isWeMo && !tag.isCam;
	tag.isHTU = (tag.tagType == 52 || tag.tagType == 62 || tag.tagType == 72 || tag.tagType == 13 || tag.tagType == 21 || tag.tagType == 26 || tag.tagType == 102 || tag.tagType == 106 || tag.tagType == 107 );

	tag.isTcProbe = (tag.tagType == 42);
	tag.isExternalDS18Probe = tag.isTcProbe && (tag.rev & 0xF) == 0xD;
	tag.isThermocouple=tag.isTcProbe&&(tag.rev&0xF)==0xF;
	tag.isRCO=tag.isTcProbe&&tag.shorted==0&&tag.az2==1; 
	tag.hasDS18Switch = tag.isReed || (tag.isTcProbe && (tag.rev & 0xF) != 0xD) || (tag.isTcProbe && tag.rev>0x80);
	tag.hasHighResTemp = tag.isHTU || tag.isTcProbe;
	if ((tag.rev & 0xF) == 0xD && tag.rev >= 0x4D) tag.isHTU = false;
	if (tag.isTcProbe && (tag.rev & 0xF) == 0xE) {
		tag.isHTU = true;
		tag.isWMETag = true;
	}
	if (tag.isTcProbe && (tag.rev & 0xF) == 0xD && tag.rev>0x80 && !tag.ds18 && tag.cap>0) {
		tag.isHTU = true;
	}
	if (tag.isTcProbe && tag.isThermocouple && tag.shorted && !tag.ds18) {
		tag.isHTU = true;
	}

	tag.isCurrentTag = (tag.tagType == 42);

	restoreTagWid(tag);
	var oldTag = taglist_cache[tag.wid] || {};
	taglist_cache[tag.wid] = tag;
	uuid2tag[tag.uuid] = tag;
	tag._updated = true;

	/*if (tag.zmod != null) {
		var bm = tag.zmod.baseline_measured;
		if (bm > 0) {
			if (oldTag.zmod == null || bm > oldTag.zmod.baseline_measured) {
				setTimeout(function () { popup(tag.name + ": Baseline reading taken " + UserFriendlyTimeSpanString(bm), $("#collapsible-" + tag.wid)); }, 100);
			}
		}
	}*/

	if ($("#tagtitle-" + tag.wid).length == 0) {
		createTag(tag);
		$("#taglist").resetRoundedEdges();
		return;
	}

	if (tag.hasFlat) {
		if ((oldTag.az2 & 16) != (tag.az2 & 16)) {
			refreshTagDetail(tag);
			return;
		}
	}

	var tag_status = calculateTagStatus(tag, tag.isMsTag || tag.isPIR || tag.isReed, tag.isMoistureTag || tag.isWMETag, tag.isCurrentTag, tag.isHTU, tag.isFlat);
	var tag_theme = calculateTagTheme(tag);

	try{
		setTheme($("#tagtitle-" + tag.wid).find("a:eq(0)").find(".ui-btn").andSelf(), tag_theme);

		if (tag.OutOfRange && !oldTag.OutOfRange) {
			$("#tagtitle-" + tag.wid).addClass("oor");
		}
		else if (!tag.OutOfRange && oldTag.OutOfRange) $("#tagtitle-" + tag.wid).removeClass("oor");

		tag.needFreqCal = (Math.abs(tag.freqOffset) > maxFreqOffset);

		if (tag.hasBeeper) {
			var btn1 = $("#beepbtn-" + tag.wid).attr("title", buttonTooltip(tag)).parent();
			//var btn2 = $("#alt-beepbtn-" + tag.wid).parent();
			var btn3 = $("#main-beepbtn-" + tag.wid).parent();
			if (tag.migrationPending) {
				btn1.find(".ui-btn-text").text("Migrate"); btn1.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-refresh"); setTheme(btn1, "e");
				//btn2.find(".ui-btn-text").text("Stop Beep"); btn2.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-delete");
				btn3.show();
			}
			else if (tag.needFreqCal) {
				btn1.find(".ui-btn-text").text("Calibrate Radio"); btn1.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-refresh"); setTheme(btn1, "e");
				//btn2.find(".ui-btn-text").text("Stop Beep"); btn2.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-delete");
				btn3.show();
			}
			else {
				btn3.hide();
				if (tag.beeping) {
					btn1.find(".ui-btn-text").text( "Stop Beep"); btn1.find(".ui-icon").removeClass("ui-icon-search ui-icon-refresh").addClass("ui-icon-delete"); setTheme(btn1, "b");
					//btn2.find(".ui-btn-text").text("Beep"); btn2.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-delete");
				} else {
					btn1.find(".ui-btn-text").text( "Beep"); btn1.find(".ui-icon").removeClass("ui-icon-delete ui-icon-refresh").addClass("ui-icon-search"); setTheme(btn1, "c");
					//btn2.find(".ui-btn-text").text("Stop Beep"); btn2.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-delete");
				}
			}
		} else {
			var btn1 = $("#updatebtn-" + tag.wid).attr("title", buttonTooltip(tag)).parent();
			var btn3 = $("#main-updatebtn-" + tag.wid).parent();
			if (tag.migrationPending) {
				btn1.find(".ui-btn-text").text("Migrate"); btn1.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-refresh"); setTheme(btn1, "e");
				btn3.show();
			} else if (tag.needFreqCal) {
				btn1.find(".ui-btn-text").text("Calibrate Radio"); btn1.find(".ui-icon").removeClass("ui-icon-search ui-icon-plus").addClass("ui-icon-refresh"); setTheme(btn1, "e");
				btn3.show();
			} else {
				btn3.hide();
				btn1.find(".ui-btn-text").text("Update"); btn1.find(".ui-icon").removeClass("ui-icon-delete ui-icon-search").addClass("ui-icon-refresh"); setTheme(btn1, "c");
			}
		}
		setTheme($("#light-btn-" + tag.wid + "-button"), tag.lit ? tag.LightOnTheme : "c");

		$("#astat-" + tag.wid).text(tagEventStates[tag.eventState][0]);
		setTheme($("#armbtn-" + tag.wid + "-button"), tagEventStates[tag.eventState][1]);
		if (tag.isMoistureTag || tag.isWMETag) {
			$("#cap-status-" + tag.wid).text(capEventStates[tag.capEventState][0]);
			setTheme($("#capbtn-" + tag.wid).parent(), capEventStates[tag.capEventState][1]);
		}
		else if (tag.isFlat) {
			if (tag.az2 & 16) { 
				$("#analog-status-" + tag.wid).text(analogEventStates[tag.capEventState][0]);
				setTheme($("#analog-btn-" + tag.wid).parent(), analogEventStates[tag.capEventState][1]);
			}
			setTheme($("#capbtn-" + tag.wid).parent(), tag.shorted?"f":"c");
		}
		else if (tag.isHTU) {
			$("#rhdisp-" + tag.wid).show();
			$("#rh-status-" + tag.wid).text(rhEventStates[tag.capEventState][0]);
			setTheme($("#rhbtn-" + tag.wid).parent(), rhEventStates[tag.capEventState][1]);
		} else {
			$("#rhdisp-" + tag.wid).hide();
		}

		if (tag.hasALS) {
			$("#als-status-" + tag.wid).text(lightEventStates[tag.lightEventState][0]);
			setTheme($("#alsbtn-" + tag.wid).parent(), lightEventStates[tag.lightEventState][1]);
		}
		/*else if (tag.hasZmod) {
			$("#voc-status-" + tag.wid).text(vocEventStates[tag.lightEventState][0]);
			setTheme($("#zmod-btn-" + tag.wid + "-button"), vocEventStates[tag.lightEventState][1]);
		}*/

		$("#tagname-" + tag.wid).text(tag.name + " " + tag_status); // + " "  + tag.solarVolt+"Ga ");
		if (tag.hasFlat) {
			var fc = $("#flat-indicator-" + tag.wid)[0].children;
			fc[0].style.fill = tag.capRaw & 1 ? fc_on : fc_off;
			fc[1].style.fill = tag.capRaw & 2 ? fc_on : fc_off;
			fc[2].style.fill = tag.capRaw & 4 ? fc_on : fc_off;
			fc[3].style.fill = tag.capRaw & 8 ? fc_on : fc_off;
		} else
			$("#signal-icon-" + tag.wid).removeClass().addClass("ui-icon-signal-" + (tag.alive ? signalToBars(tag) : 0)).attr("title", tagSignalTooltip(tag));

		$("#temp-display-" + tag.wid).html(tempDisp(tag));

		$("#temp-status-" + tag.wid).text(tempEventStates[tag.tempEventState][0]);
		setTheme($("#tempbtn-" + tag.wid).parent(), tempEventStates[tag.tempEventState][1]);

		if (!dont_play_notificationJS) {
			if (tag.notificationJS != null && tag.notificationJS != "null" && tag.notificationJS.length > 0) {
				notificationQueue.push(tag);
				if (notificationQueue.length == 1) {
					start_process_notification_queue();
				}
			}
		}

		if (tag.isCam) {
			if (tag.beeping && !oldTag.beeping) { $("#start-lapse-" + tag.wid).hide(); $("#stop-lapse-" + tag.wid).show(); }
			else if (!tag.beeping && oldTag.beeping) { $("#start-lapse-" + tag.wid).show(); $("#stop-lapse-" + tag.wid).hide(); }

			$("#tag-pic-" + tag.wid).css({ "background-image": "url('" + WSROOT + "dropcam/" + tag.uuid + "/thumb?" + (new Date()).getTime() + "')", "background-position": "center", "background-size": "100%" });
			snapshotLoadNewer(tag);
		} else {
			if (!tag.image_md5) {
				if (!window.NC)
					$("#tag-pic-" + tag.wid).hide();
				else
					$("#tag-pic-" + tag.wid).css({ "background-image": "url('/eth/styles/images/Placeholder.png')", "background-position": "center", "background-size": "50%" });
			}
			else if (tag.image_md5 != oldTag.image_md5) {
				$("#tag-pic-" + tag.wid).css({ "background-image": "url('" + WSROOT + "eth/tags/" + tag.uuid + ".jpg?" + tag.image_md5 + "')", "background-size": "100%" }).show();
				//$("#tag-pic-" + tag.wid).css("background", "url('/eth/tags/"+tag.uuid+".jpg')").show();  
			}
		}
		if (tag.eventState == 2 || tag.eventState==5 || tag.eventState==8) {			// moved
			$("#resetbtn-" + tag.wid).parent().show();
		} else {
			$("#resetbtn-" + tag.wid).parent().hide();
		}
		if (tag.isKumostat && tag.thermostat != null) {
			var element = $("#kumostat-range-" + tag.wid);
			if (element) {
				var rs = $.data(element.get(0), "rangeslider");
				applyTempThresholdQ(tag.thermostat.threshold_q);
				rs._inputFirst.attr("min", degCmode!=0 ? degC_min:degF_min).attr("max", degCmode!=0 ? degC_max:degF_max).attr("step", degCmode!=0 ? degC_step:degF_step).val(toNativeTemp(tag.thermostat.th_low)).slider("refresh");
				rs._inputLast.attr("min", degCmode != 0 ? degC_min : degF_min).attr("max", degCmode != 0 ? degC_max : degF_max).attr("step", degCmode != 0 ? degC_step : degF_step).val(toNativeTemp(tag.thermostat.th_high)).slider("refresh");
				animateTstat(rs, tag);

				if (tag.thermostat.turnOff)
					rs.disable();
				else
					rs.enable()

				if (tag.isNest && !tag.thermostat.disableLocal)
					$("#ac_onoff_" + tag.wid).flipswitch("option", "onText", "Home").flipswitch("option", "offText", "Away");
				else
					$("#ac_onoff_" + tag.wid).flipswitch("option", "onText", "AC/Heat On").flipswitch("option", "offText", "AC/Heat Off");

				$("#fan_onoff_" + tag.wid).attr("checked", tag.thermostat.fanOn).flipswitch("refresh");
				$("#ac_onoff_" + tag.wid).attr("checked", !tag.thermostat.turnOff).flipswitch("refresh");
				$("#target-choice-" + tag.wid).val(tag.thermostat.targetUuid);
				$("#target-name-" + tag.wid).text(uuid2tag[tag.thermostat.targetUuid].name);
			}
		}
		else if (tag.thermostatRef != null) {
			var element = $("#kumostat-range-" + tag.thermostatRef.wid);
			if (element) {
				var rs = $.data(element.get(0), "rangeslider");
				animateTstat(rs, tag.thermostatRef);
			}
		}
		updateAgoString(tag);

		if (tag.slaveId >= 0) {
			var uag = $("#pingBtn-" + tag.wid);
			if (uag.val() != tag.postBackInterval) uag.val(tag.postBackInterval).selectmenu("refresh");
		}

		var batDisplay = $("#tagbat-" + tag.wid);
		if (isLowBattery(tag))
			batDisplay.addClass("lbWarn");
		else
			batDisplay.removeClass("lbWarn");
		batDisplay.text(tag.batteryVolt.toFixed(2));

		if (tag.version1 != 4) {		// version1=4 uses Tadiran

			var batDisplayPc = $("#tagbat-pc-" + tag.wid);
			if (isLowBattery(tag))
				batDisplayPc.addClass("lbWarn");
			else
				batDisplayPc.removeClass("lbWarn");
			batDisplayPc.text((tag.batteryRemaining * 100).toFixed(0));
		}
		
		$("#tagcomment-" + tag.wid).text(tag.comment);
		if (!tag.alive) {
			$("#signal-text-" + tag.wid).attr("title", tagBackOffTooltip(tag)).text("No Signal");
		} else {
			$("#signal-text-" + tag.wid).attr("title", tagBackOffTooltip(tag)).text(Math.round(tag.signaldBm) + "dBm");
		}
		if (!tag.isKumostat) {
			$("#tag-lit-" + tag.wid).text(tag.lit ? "On" : "Off");
		}
		/*if (tag.hasZmod) {
			$("#tag-zmod-" + tag.wid).html(tag.shorted ? zmodDisplay(tag) : "<b>Off</b>");
		}*/
		$("#tag-temp-" + tag.wid).html(tag.temperature ? "<b>" + (degCmode ? tag.temperature.toFixed(1) + "°C" : (tag.temperature * 9 / 5 + 32).toFixed(1) + "°F") + "</b>" + ds18state(tag) : "N/A" + ds18state(tag));
		if (tag.isExternalDS18Probe) {
			$("#probe-type-" + tag.wid).text(tag.ds18 ? "DS18B20" : (tag.shorted? (tag.az2 == 1 ? "SHT3x" : "SHT20") : "No Probe") ) ;
		} else if (tag.isThermocouple) {
			$("#probe-type-" + tag.wid).text(tag.ds18 ? "DS18B20" : (tag.shorted ? (tag.az2 == 1 ? "SHT3x" : "SHT20"):"k-Type"));
		}
		if(tag.isWMETag) {
			$("#tag-moisture-"+tag.wid).html(tag.cap.toFixed(2));
		}
		else if(tag.isMoistureTag||tag.isFlat)
			$("#tag-moisture-"+tag.wid).html(tag.cap.toFixed(0));
		else if(tag.isHTU) {
			$("#tag-moisture-"+tag.wid).html(rhDisplay(tag));
			$("#tag-moisture-label-"+tag.wid).text(tag.isRCO? "Soil Moisture":"Humidity");
		}
		if (tag.hasALS) {
			$("#tag-lux-" + tag.wid).html(tag.lux.toFixed(2));
		}
		if (tag.hasFlat && tag.az2 & 16) {
			$("#tag-analog-" + tag.wid).html(tag.lux.toFixed(2));
		}
		/*if (tag.tagType==22) {
			$("#tag-temp-" + tag.wid).html(tag.temperature ? Math.round(tag.temperature) + "" : "N/A");
			$("#tag-solarstat-" + tag.wid).text(tag.solarVolt ? (tag.solarVolt >= tag.batteryVolt ? ", Charging" : ", On battery") : "");
		}*/

		var advchoice = $("#advanced-choice-" + tag.wid);
		var needUpdateAdvanced = false;
		/*if (tag.isMsTag) {
			if (oldTag.eventState == 0 && tag.eventState != 0) {
				advchoice.find("option[value='4']").after('<option value="9" title="Record the current angle and only notify if tag is moved away for from the plane formed by this angle and the armed angle.">Define 2nd Closed Angle</option>');
				needUpdateAdvanced = true;
			}
			else if (oldTag.eventState != 0 && tag.eventState == 0) {
				advchoice.find("option[value='9']").remove();
				needUpdateAdvanced = true;
			}
			if (oldTag.az2 == 0 && tag.az2 != 0) {
				advchoice.find("option[value='5']").before('<option title="Return to regular door/gate mode." value="10">Erase 2nd Closed Angle</option>');
				needUpdateAdvanced = true;
			}
			else if (oldTag.az2 != 0 && tag.az2 == 0) {
				advchoice.find("option[value='10']").remove();
				needUpdateAdvanced = true;
			}
		}*/
		var mt = tag.migrationPending ? "Use New Wireless Setting" : "Use Old Wireless Setting";
		var mt_dom = advchoice.find("option[value='4']")[0];
		if (mt_dom!=null && mt_dom.innerHTML != mt) {
			mt_dom.innerHTML = mt;
			needUpdateAdvanced = true;
		}

		if (needUpdateAdvanced)
			advchoice.selectmenu("refresh", true);

	}
	catch (e) {
	}
}
function toNativeTemp(degC) {
	return degCmode!=0 ? degC : Math.round(degC * 9.0 / 5.0 + 32);
}
function fromNativeTemp(temp) {
	return degCmode != 0 ? temp : (temp-32.0)*5.0/9.0;
}
function getThermostatColor(tag) {
	if (tag.thermostat.turnOff) return "gray";
	else if (tag.temperature > tag.thermostat.th_high) return "blue";
	else if (tag.temperature < tag.thermostat.th_low) return "orange";
	else return "gray";
}
function animateTstat(rs, tag) {
	var currentTemp = uuid2tag[tag.thermostat.targetUuid].temperature;
	if (tag.thermostat.turnOff == false) {
		if (currentTemp < tag.thermostat.th_low) {
			rs.setSolidBgAt(toNativeTemp(currentTemp), "orange");
			rs.animateBgAt(toNativeTemp(tag.thermostat.th_low), "orange");
			return;
		}
		else if (currentTemp > tag.thermostat.th_high) {
			rs.setSolidBgAt(toNativeTemp(currentTemp), "blue");
			rs.animateBgAt(toNativeTemp(tag.thermostat.th_high), "blue");
			return;
		}
	}
	rs.setSolidBgAt(toNativeTemp(currentTemp), "gray");
	rs.animateBg.hide();
}
function findTagFromSlaveIdAndMac(slaveId, mac) {
	var tag;
	if (allTagManager) {
		$.each(taglist_cache, function (id, t) {
			if (t.slaveId == slaveId && t.mac == mac) { tag = t; return false; }
		});
	} else
		tag = taglist_cache[slaveId];
	return tag;
}
function MN_onPictureUpdated2(uuid, md5) {
	var tag = uuid2tag[uuid];
	tag.image_md5 = md5;
	if (tag) $("#tag-pic-" + tag.wid).css({ "background-image": "url('" + WSROOT + "eth/tags/" + tag.uuid + ".jpg?" + tag.image_md5 + "')", "background-size": "100%" }).show();
}
function MN_onPictureUpdated(slaveId, mac) {
	var tag = findTagFromSlaveIdAndMac(slaveId, mac);
	if (tag) $("#tag-pic-" + tag.wid).css({ "background-image": "url('" + WSROOT + "eth/tags/" + tag.uuid + ".jpg?" + tag.image_md5 + "')", "background-size": "100%" }).show();
}
function tagBackOffTooltip(tag) {
	return "Transmit power " +  (tag.txpwr/2.55).toFixed(0) + "%";
}
function tagSignalTooltip(tag) {
	return tag.signaldBm + "dBm using " + (tag.txpwr / 2.55).toFixed(0) + "% transmit power";
}

function zmodDisplay(tag) {
	var zmod = tag.zmod;
	if (zmod && tag.shorted) {
		return "VOC: <b>" + zmod.tvoc[0].toFixed(3) + "</b> ppm"; //<br/>eCO<sub>2</sub>: <b>" + (zmod.eCO2[0].toFixed(1)) + "</b> ppm";
	}
	return "<b>Off</b>";
}
function clickPictureNC(wid) {
	var tag = taglist_cache[wid];
	if (tag.image_md5 == null) {
		launchCameraNC(tag);
	} else {
		var menu = $('<select id="_pictureOptionFor" data-native-menu="false" data-context-menu=1><option value="1">Replace Picture</option><option value="2">Delete Picture</option></select>');
		var holder = $("#tag-pic-" + wid);
		menu.appendTo(holder).selectmenu();
		menu.selectmenu("refresh").selectmenu("open");

		menu.change(function () {
			if ($(this).val() == "1")
				launchCameraNC(tag);
			else {
				$.ajax({
					url: WSROOT + "ethClient.asmx/DeleteTagImage",
					data: JSON.stringify({ "id": tag.slaveId }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					success: function (retval, textStatus) {
						tag.image_md5 = null;
						updateTag(tag);
					}
				});
			}
		});
	}
}
function launchCameraNC(tag) {
	if (window.NC.updatePicture3) {
		window.NC.updatePicture3(tag.uuid);
	} else {
		if (allTagManager)
			window.NC.updatePicture2(tag.slaveId, tag.mac);
		else
			window.NC.updatePicture(tag.slaveId);
	}
}
function createTagDetail(tag) {
	var ageText = UserFriendlyTimeSpanString(tag.lastComm);

	var html = ('<div class="column pic ui-shadow" id="tag-pic-{0}" ').format(tag.wid);
	
	if (tag.isCam) {
		html += (' style="background-image: url({0}dropcam/{1}/thumb?' + (new Date()).getTime() + ')"').format(WSROOT, tag.uuid);
		html += (' onclick="window.open(\'{0}dropcam/{1}\', \'\', \'width=768, height=432, scrollbars=0, status=0, toolbar=0, menubar=0\')" ').format(WSROOT, tag.uuid);
	} else {
		if (tag.image_md5 == null) {
			if (window.NC)
				html += ' style="background-image: url(styles/images/Placeholder.png); background-position: center; background-size: 50%; "';
			else
				html += ' style="display:none;"';
		} else {
			html += (' style="background-image: url({0}eth/tags/{1}.jpg?'+tag.image_md5+')"').format(WSROOT, tag.uuid);
		}
		if (window.NC) 
			html += (' onclick="clickPictureNC({0});" ').format(tag.wid);
		
	}
	html+="></div>";

	html += ('<button title="Edit this tag\'s comment" data-inline=1 data-icon=comment data-theme="c" onclick="editComment($(this), {0}); return false;" ><b><span id=tagcomment-{0}>{1}</span></b></button>')
	.format(tag.wid, tag.comment);

	if (tag.hasBeeper) {
		if (tag.migrationPending || tag.needFreqCal) {
			html += ('<button data-inline=1 id="main-beepbtn-{0}" data-theme="b" onclick="togglebeep($(this), {0}); return false;"  data-icon=search>Beep</button>').format(tag.wid);
		} else {
			html += ('<button data-inline=1 data-hide=1 id="main-beepbtn-{0}" data-theme="b" onclick="togglebeep($(this), {0}); return false;"  data-icon=search>Beep</button>').format(tag.wid);
		}
	} else {
		if (tag.migrationPending || tag.needFreqCal) {
			html += ('<button data-inline=1 id="main-updatebtn-{0}" data-theme="b" onclick="togglebeep($(this), {0}); return false;"  data-icon=refresh>Update</button>').format(tag.wid);
		} else {
			html += ('<button data-inline=1 data-hide=1 id="main-updatebtn-{0}" data-theme="b" onclick="togglebeep($(this), {0}); return false;"  data-icon=refresh>Update</button>').format(tag.wid);
		}
	}
	if (tag.isCam) {
		html += ('<button data-inline=1 id="snapshot-btn-{0}" data-theme="a" onclick="snapshot($(this), {0}); return false;"  data-icon=cam>Snapshot</button>').format(tag.wid);
		html += ('<select data-inline=1 data-theme="b" data-toptext="Record..." onchange="recordVideo($(this), {0}); return false;" data-native-menu="false" data-icon=camcoder><option value="5">5 second video</option><option value="10">10 second video</option><option value="15">15 second video</option><option value="20">20 second video</option><option value="30">30 second video</option><option value="45">45 second video</option><option value="60">1 minute video</option><option value="90">90 second video</option></select>').format(tag.wid);
		html += ('<span id="start-lapse-{0}" style="{1}"><select data-inline=1 data-theme="a" data-toptext="Make Time Lapse..." onchange="startTimeLapse($(this), {0}); return false;" data-native-menu="false" data-icon=time><option value="120">2 hour to 90 seconds</option><option value="180">3 hour to 90 seconds</option><option value="360">6 hour to 90 second</option><option value="720">12 hour to 90 seconds</option><option value="1440">24 hour to 90 seconds</option><option value="2880">48 hour to 90 seconds</option><option value="4320">72 hour to 90 seconds</option></select></span>').format(tag.wid, tag.beeping?"display:none":"");
		html += ('<span id="stop-lapse-{0}" style="{1}"><button data-inline=1 data-theme="d"  onclick="stopTimeLapse($(this), {0}); return false;"  data-icon=check>Stop Time Lapse</button></span>').format(tag.wid, tag.beeping ? "" : "display:none");
	}
	/*if (tag.hasBeeper) {
		if (tag.migrationPending || tag.needFreqCal) {
			html += ('<button data-inline=1 id="alt-beepbtn-{0}" data-theme="c" onclick="togglebeep($(this), {0}); return false;"  data-icon=delete>Stop Beep</button>').format(tag.wid);
		} else {
			html += ('<button data-inline=1 id="alt-beepbtn-{0}" data-theme="c" onclick="togglebeep($(this), {0}); return false;"  data-icon={2}>{1}</button>')
						.format(tag.wid, tag.beeping ? "Beep" : "Stop Beep", tag.beeping ? "search" : "delete");
		}
	}*/
	if (!tag.isKumostat) {
		html += ('<select id=light-btn-{0} title="Click to turn on or off" data-inline=1 data-theme="{2}" data-toptext="<span class=static-btn-text>{3}</span><b><span id=tag-lit-{0}>{1}</span></b>" onchange="togglelight($(this), {0}); return false;" data-native-menu="false" data-icon={4}><option value="1">Turn On</option><option value="0">Turn Off</option></select>')
			.format(tag.wid, tag.lit ? "On" : "Off", tag.lit ? tag.LightOnTheme : "c", tag.isCam | tag.isWeMo ? "" : "Light<br/>", tag.isCam ? "power" : "bulb");
	}
	/*if (tag.hasZmod) {
		html += ('<select id=zmod-btn-{0} title="Volatile Organic Compound/Indoor Air Quality" data-inline=1 data-theme="{3}" data-toptext="<span class=static-btn-text>Air Quality<br/></span><span id=tag-zmod-{0}>{1}</span><br/><span id=voc-status-{0}>{2}</span>" onchange="ctrlZmod($(this), {0}); return false;" data-native-menu="false" data-icon=air><option value="1">Enable</option><option value="0">Disable</option><option value="2">Options...</option></select>')
			.format(tag.wid, zmodDisplay(tag), vocEventStates[tag.lightEventState][0], vocEventStates[tag.lightEventState][1]);		
	}*/
	if (tag.isMsTag || tag.isPIR) {
		if (tag.eventState == 2 || tag.eventState==5 || tag.eventState==8)  // moved or detected or carried away
		{
			html += ('<button data-inline=1 id="resetbtn-{0}" data-icon=delete data-theme="c" onclick="resetit($(this), {0}); return false;" >Reset</button>').format(tag.wid);
		}
		else {
			html += ('<button data-hide=1 data-inline=1 id="resetbtn-{0}" data-icon=delete data-theme="c" onclick="resetit($(this), {0}); return false;" >Reset</button>').format(tag.wid);
		}
	}
	var temp_disp=null;
	if (tag.hasHighResTemp) {
		temp_disp = tag.temperature ? "<b>" + (degCmode ? Math.round(tag.temperature * 10) / 10 + "°C" : Math.round(tag.temperature * 90 / 5 + 320) / 10 + "°F") + "</b>" +ds18state(tag) : "N/A" + ds18state(tag);
	}
	else if (tag.hasTempSensor) {
		temp_disp = tag.temperature ? "<b>" + (degCmode ? tag.temperature.toFixed(1) + "°C" : (tag.temperature * 9 / 5 + 32).toFixed(1) + "°F") + "</b>" : "N/A";
	}
	if (temp_disp) html += ('<button data-inline=1 title="Configure temperature monitoring..." id=tempbtn-{0} data-icon=thermo data-theme="{3}" onclick="tempOptions($(this), {0}); return false;" ><span class=static-btn-text>Temperature <br/></span><span id=tag-temp-{0}>{1}</span><br/><span id=temp-status-{0}>{2}</span></button>')
			.format(tag.wid, temp_disp,
			tempEventStates[tag.tempEventState][0], tempEventStates[tag.tempEventState][1]);
	if (tag.isExternalDS18Probe) {
		
		html += ('<select id=detect-probe-btn-{0} title="Connect the DS18B20 or SHT20 probe, then click this button to enable it." data-inline=1 data-theme="c" data-toptext="<span class=static-btn-text>Probe type</span><br><b><span id=probe-type-{0}>{1}</span></b>" onchange="toggleDS18($(this), {0}); return false;" data-native-menu="false" data-icon=gear><option value="1" {2}>DS18B20</option><option value="2" {3}>SHT20 (SEN0227)</option>{4}{5}</select>')
			.format(tag.wid,tag.ds18? (tag.az2==1?"Soil Moisture":"DS18B20"):(tag.shorted? (tag.az2==1? "SHT3x":"SHT20"):"No Probe"),
				tag.ds18? "selected":"",tag.ds18||(tag.az2==0)? "":"selected",
				tag.rev>0xB0? '<option value="4" '+(tag.shorted&&tag.az2==1? "selected":"")+'>SHT3x (SEN0385)</option>':"",
				tag.rev>0xD0? '<option value="6" '+(!tag.ds18&&!tag.shorted&&tag.az2==1? "selected":"")+'>Soil Moisture</option><option value="5" '+(tag.ds18&&!tag.shorted&&tag.az2==1? "selected":"")+'>DS18B20+Soil Moisture</option>':"");

		//html += ('<button data-inline=1 data-icon="info" title="Connect the DS18B20 or SHT20 probe, then click this button to enable it" id="detect-ds18-{0}" onclick="applyDs18(taglist_cache[{0}], {2}, $(this)); return false;"><b>Detect {1}</b></button>')
			//.format(tag.wid, tag.ds18?"SHT20":"DS18B20", tag.ds18?"false":"true");
	}
	else if (tag.isThermocouple) {

		html += ('<select id=detect-probe-btn-{0} title="Connect a probe, then click this button to enable it." data-inline=1 data-theme="c" data-toptext="<span class=static-btn-text>Probe type</span><br><b><span id=probe-type-{0}>{1}</span></b>" onchange="toggleDS18($(this), {0}); return false;" data-native-menu="false" data-icon=gear><option value="1" {2}>DS18B20</option><option value="0" {3}>k-Type Thermocouple</option>' + (tag.rev > 0x80 ? '<option value="2" {4}>SHT20</option>' : "") + '{5}{6}</select>')
			.format(tag.wid,tag.ds18? (tag.az2==1? "Soil Moisture":"DS18B20"):(tag.shorted? (tag.az2==1? "SHT3x":"SHT20"):"k-Type"),
				tag.ds18? "selected":"",!tag.ds18&&!tag.shorted? "selected":"",!tag.ds18&&tag.shorted&&tag.az2==0? "selected":"",
				tag.rev>0xB0? '<option value="4" '+(!tag.ds18&&tag.shorted&&tag.az2==1? "selected":"")+'>SHT3x</option>':"",
				tag.rev>0xD0? '<option value="5" '+(tag.ds18&&tag.az2==1? "selected":"")+'>Soil Moisture</option>':"" ,
		);

	}
	if (tag.hasALS) {

		html += ('<button data-inline=1 id=alsbtn-{0} title="Configure ambient light level monitoring..." data-icon=star data-theme="{3}" onclick="lightOptions($(this), {0}); return false;" ><span class=static-btn-text>Ambient Light<br/></span><b><span id=tag-lux-{0}>{1}</span> lux</b><br/><span id=als-status-{0}>{2}</span></button>')
			.format(tag.wid, tag.lux.toFixed(2),
			lightEventStates[tag.lightEventState][0], lightEventStates[tag.lightEventState][1]);
	}
	if (tag.hasFlat) {
		html += ('<button data-inline=1 id=capbtn-{0} title="Configure water sensor..." data-icon=rh data-theme="{2}" onclick="capOptions($(this), {0}); return false;" ><span class=static-btn-text>Water<br/></span><b><span id=tag-moisture-{0}>{1}</span>%</b></button>')
			.format(tag.wid, tag.cap.toFixed(0),  tag.shorted?"f":"c");

		if (tag.az2 & 16)
			html += ('<button data-inline=1 id=analog-btn-{0} title="Configure analog voltage monitoring..." data-theme="{3}" onclick="capOptions($(this), {0}, true); return false;" ><span class=static-btn-text>Analog<br/></span><b><span id=tag-analog-{0}>{1}</span> volt</b><br/><span id=analog-status-{0}>{2}</span></button>')
				.format(tag.wid, tag.lux.toFixed(2),
					analogEventStates[tag.capEventState][0], analogEventStates[tag.capEventState][1]);
	}
	if (tag.isMoistureTag ) {
		html += ('<button data-inline=1 id=capbtn-{0} title="Configure moisture sensor..." data-icon=rh data-theme="{3}" onclick="capOptions($(this), {0}); return false;" ><span class=static-btn-text>Moisture<br/></span><b><span id=tag-moisture-{0}>{1}</span>%</b><br/><span id=cap-status-{0}>{2}</span></button>')
			.format(tag.wid, tag.cap.toFixed(0),
			capEventStates[tag.capEventState][0], capEventStates[tag.capEventState][1]);
	}
	else if (tag.isWMETag) {
		html += ('<button data-inline=1 id=rhbtn-{0} data-icon=rh title="Configure WME monitoring..." data-theme="{3}" onclick="capOptions($(this), {0}); return false;" ><span class=static-btn-text>WME<br/></span><b><span id=tag-moisture-{0}>{1}</span>%</b><br/><span id=cap-status-{0}>{2}</span></button>')
			.format(tag.wid, tag.cap.toFixed(2),
			capEventStates[tag.capEventState][0], capEventStates[tag.capEventState][1]);
	}
	else if (tag.isHTU || tag.isExternalDS18Probe || tag.isThermocouple) {
		html+=('<span id=rhdisp-{0} style="display:{4}"><button data-inline=1 id=rhbtn-{0} data-icon=rh title="Configure humidity monitoring..." data-theme="{3}" onclick="capOptions($(this), {0}); return false;" ><span id=tag-moisture-label-{0} class=static-btn-text>{5}</span><span class=static-btn-text><br/></span><b><span id=tag-moisture-{0}>{1}</span></b><br/><span id=rh-status-{0}>{2}</span></button></span>')
			.format(tag.wid,rhDisplay(tag),rhEventStates[tag.capEventState][0],rhEventStates[tag.capEventState][1],tag.isHTU? "inline-block":"none",tag.isRCO?"Soil Moisture":"Humidity");
	}

	if(tag.isMsTag && tag.rev!=0x4E){
		html += ('<select title="Motion sensor" data-inline=1 id="armbtn-{0}" data-toptext="<span class=static-btn-text>Motion<br/>sensor<br/></span><b><span id=astat-{0}>{1}</span></b>" data-icon=grid data-theme="{2}" onchange="armDisarm($(this), {0}); return false;" data-native-menu="false" ><option value="1">Arm</option><option value="2">Disarm</option><option value="4">Options...</option></select>')
						.format(tag.wid, tagEventStates[tag.eventState][0], tagEventStates[tag.eventState][1]);
	}
	else if (tag.isPIR) {
		html += ('<select title="PIR sensor" data-inline=1 id="armbtn-{0}" data-toptext="<span class=static-btn-text>PIR sensor<br/></span><b><span id=astat-{0}>{1}</span></b>" data-icon=grid data-theme="{2}" onchange="armDisarm($(this), {0}); return false;" data-native-menu="false" ><option value="1">Arm</option><option value="2">Disarm</option><option value="4">Options...</option></select>')
						.format(tag.wid, tagEventStates[tag.eventState][0], tagEventStates[tag.eventState][1]);
	}
	else if (tag.isReed) {
		html += ('<select title="Reed sensor" data-inline=1 id="armbtn-{0}" data-toptext="<span class=static-btn-text>Reed <br/>sensor<br/></span><b><span id=astat-{0}>{1}</span></b>" data-icon=grid data-theme="{2}" onchange="armDisarm($(this), {0}); return false;" data-native-menu="false" ><option value="1">Arm</option><option value="2">Disarm</option><option value="4">Options...</option></select>')
						.format(tag.wid, tagEventStates[tag.eventState][0], tagEventStates[tag.eventState][1]);
	}
	else if (tag.isKumostat) {
		applyTempThresholdQ(tag.thermostat.threshold_q);
		html += ('<select title="Choose which tag to use as temperature sensor for this thermostat." data-inline=1 id="target-choice-{0}" data-toptext="Set At: <br/><b><span id=target-name-{0}>{1}</span></b>" data-native-menu="false">').format(tag.wid, uuid2tag[tag.thermostat.targetUuid].name);
		$.each(taglist_cache, function (id, sensor) {
			html += ('<option value="{0}" {1}>{2}</option>').format(sensor.uuid, sensor.uuid == tag.thermostat.targetUuid ? "selected" : "", sensor.name);
		});
		html += "</select>";
	}
	
	if (tag.isWeMoLED) {
		html += ('<select data-inline=1 id="dimming-speed-{0}" data-theme="c" data-native-menu="false" ><option value="0">Dim immediately</option><option value="10">Dim gradually</option><option value="50">Dim very gradually</option></select>')
						.format(tag.wid);
	}
	html += ('<span id="updateIntervalFor-{0}"></span>​').format(tag.wid);
	if (tag.wid >= 0) {
		html += ('<select data-inline=1 id="pingBtn-{0}" data-theme="c" data-native-menu=0 data-icon="refresh" onchange="setPostbackIntervalFor($(this),{0}); return false;" data-toptext="<span class=static-btn-text>Updated<br/></span><b><span id=lasttalk-{0}>{1}</span></b><br/>Signal: <b><span title=\'{3}\' id=signal-text-{0}>{2}</span></b>"><option value=0>Update Now</option>')
			.format(tag.wid, ageText, (tag.alive && tag.signaldBm > -115) ? Math.round(tag.signaldBm) + "dBm" : "No Signal", tagBackOffTooltip(tag));
		$("#updateInterval option").each(function () {
			html += '<option value=' + this.value + (this.value == tag.postBackInterval ? " selected" : "") + ">Record " + this.innerHTML.toLowerCase() + "</option>";
		});
		html += '<option value="-1">If Out of Range...</option><option value="-2">Notifications...</option></select>';

		if (tag.version1 >= 4) {
			html += ('<select title="Edit low battery notification options" data-inline=1 data-theme="c" data-native-menu=0 data-icon=0 data-iconpos=none onchange="batteryOptions($(this),{0}); return false;" data-toptext="<span class=static-btn-text>Battery<br/></span><b><span id=tagbat-{0} {2}>{1}</span> volt</b>"><option value=0>Low Battery Notifications</option><option value=1>Historical Graph</option></select>')
				.format(tag.wid, tag.batteryVolt.toFixed(2), isLowBattery(tag) ? "class='lbWarn'" : "");
		} else {
			html += ('<select title="Edit low battery notification options" data-inline=1 data-theme="c" data-native-menu=0 data-icon=0 data-iconpos=none onchange="batteryOptions($(this),{0}); return false;" data-toptext="<span class=static-btn-text>Battery<br/></span><b><span id=tagbat-{0} {2}>{1}</span> volt<br/><span id=tagbat-pc-{0} {2}>{3}</span>%</b> left"><option value=0>Low Battery Notifications</option><option value=1>Historical Graph</option></select>')
				.format(tag.wid, tag.batteryVolt.toFixed(2), isLowBattery(tag) ? "class='lbWarn'" : "", (tag.batteryRemaining * 100).toFixed(0));
		}
	} else {
		html += ('<button title="Get the latest status of this device." data-inline=1 id="pingBtn-{0}" data-icon=refresh data-theme="c" onclick="reqPostback($(this), {0}); return false;" >Update</button>').format(tag.wid);
	}

	if (tag.hasALS) {
		html += ('<select data-inline=1 data-right=0 data-toptext="<span class=static-btn-text>Graphs</span>" title="Graphs..." onchange="indiv_stats($(this), {0}); return false;" data-native-menu="false" data-icon="graph"><option title="View motion sensor event log." value="5">Motion Events</option><option selected value="51">Temperature/Humidity</option><option selected value="52">Temperature/Humidity/Lux</option></select>').format(tag.wid);
	}
	/*else if (tag.hasZmod) {
		html += ('<select data-inline=1 data-right=0 data-toptext="<span class=static-btn-text>Graphs</span>" title="Graphs..." onchange="indiv_stats($(this), {0}); return false;" data-native-menu="false" data-icon="graph"><option selected value="51">Temperature/Humidity</option><option selected value="52">Temperature/Humidity/VOC</option></select>').format(tag.wid);
	}*/
	else if (tag.hasEventLog) {
		var graph_title = 'Temperature' + (tag.isMoistureTag ? '/Moisture' : '') + (tag.isWMETag ? "WME" : (tag.isHTU ? '/Humidity' : '')) ;
		html += ('<select data-inline=1 data-right=0 data-toptext="<span class=static-btn-text>Graphs</span>" title="Graphs..." onchange="indiv_stats($(this), {0}); return false;" data-native-menu="false" data-icon="graph"><option title="View motion sensor event log." value="5">Motion Events</option><option selected value="51">' + graph_title + '</option></select>').format(tag.wid);
	} else if (tag.hasFlat) {
		html += ('<select data-inline=1 data-right=0 data-toptext="<span class=static-btn-text>Graphs</span>" title="Graphs..." onchange="indiv_stats($(this), {0}); return false;" data-native-menu="false" data-icon="graph"><option selected value="51">Temperature/Water</option><option selected value="52">Temperature/Water/Analog</option></select>').format(tag.wid);
	}
	else if (tag.hasTempSensor) {
		html += ('<button title="View temperature/humidity graph" data-inline=1 data-icon=graph data-theme="c" onclick="indiv_tempGraph({0}, false); return false;" ><span class=static-btn-text>Graph</span></button>').format(tag.wid);
	}

	if (tag.hasTempSensor) {
		html += ('<select data-inline=1 data-toptext="<span class=static-btn-text>Share</span>" title="Share tag data..." onchange="shareTag($(this), {0}); return false;" data-native-menu="false" data-icon="share"><option value="1">Temperature/Humidity</option>' +
			(tag.hasALS ?'<option value="4">Ambient light</option>':'')
			+'<option value="2">Motion events</option><option value="3">Facebook</option></select>').format(tag.wid);
	}
	html += ('<span id="moreBtnFor-{0}"></span>​<select data-inline=1 data-right=1 data-toptext=" " title="More..." onchange="advanced($(this), {0}); return false;" id="advanced-choice-{0}" data-native-menu="false" data-icon="arrow-r">').format(tag.wid);
	if (tag.thermostat != null && tag.slaveId < 0) {
		if (tag.isNest)
			html += '<option value="-1" title="Configure notification when your nest transitions between home & away states." >Home/Away Sensor Events</option>';   
		
		html += '<option value="62">Diagnostic Messages</option><option value="1">Change Name</option><option value="3">Unpair</option></select>';
	} else
		html += '<option value="1">Change Tag Name</option><option value="30">Customize Message</option><option value="21">Notifications and Reports</option><option value="31">URL Calling</option>' +
			(tag.slaveId >= 0 ? '<option value="14">Special Options</option><option title="Switch tag manager between old/new frequency and data-rate when talking to this tag." value="4">' + (tag.migrationPending ? "Use New Wireless Setting" : "Use Old Wireless Setting") + '</option>' : "")
		 + (tag.version1 >= 2 ? '<option title="Enable/disable low power receive mode." value="11">Receiver Mode</option><option title="Correct frequency offset caused by temperature drift. Do this to improve range after relocating tag to a different temperature environment (e.g. from room to freezer)." value="12">Calibrate Frequency Offset</option>' : '')
		 + '<option title="This has same effect as taking battery out and reinserting: disarm/stop monitoring on every sensor, and disable any periodic data transmission. This will not unpair the tag." value="6">Reset States</option><option value="3">Unpair</option></select>';

	if (tag.isKumostat) {
		html += ('<input type="switch" data-role="flipswitch" data-wrapper-class="long-label-flipswitch" data-on-text="{3}" data-off-text="{4}" id="ac_onoff_{0}" {1}/><input type="switch" data-role="flipswitch" data-on-text="Fan On" data-off-text="Fan Auto" id="fan_onoff_{0}" {2}/>')
				.format(tag.wid, tag.thermostat.turnOff ? "" : "checked", tag.thermostat.fanOn ? "checked" : "",
				tag.isNest && !tag.thermostat.disableLocal ? "Home" : "AC/Heat On",
				tag.isNest && !tag.thermostat.disableLocal ? "Away" : "AC/Heat Off");
		html += ('<div data-role="rangeslider" id="kumostat-range-{0}" {6}><label for="kumostat-min-{0}">Comfort zone:</label><input type="number" step="{7}" data-type="range" name="kumostat-min-{0}" id="kumostat-min-{0}" min="{1}" max="{2}" value="{3}" data-unit="°{5}"><input type="number" data-type="range" name="kumostat-max-{0}"  step="{7}" id="kumostat-max-{0}" min="{1}" max="{2}" value="{4}" data-unit="°{5}"></div>')
			.format(tag.wid, degCmode ? degC_min : degF_min, degCmode ? degC_max : degF_max,
									toNativeTemp(tag.thermostat.th_low), toNativeTemp(tag.thermostat.th_high), degCmode ? "C" : "F", tag.image_md5 != null ? "data-indent=100" : "", degCmode ? degC_step : degF_step);

		setTimeout(function () {
			var element = $("#kumostat-range-" + tag.wid);
			var rs = $.data(element.get(0), "rangeslider");
			var targetChoice = $("#target-choice-" + tag.wid);
			var hvac_onoff = $("#ac_onoff_" + tag.wid);
			var fan_onoff = $("#fan_onoff_" + tag.wid);
			var tstat_control = function (en) {
				hvac_onoff.flipswitch(en);
				fan_onoff.flipswitch(en);
				rs._inputFirst.slider(en);
				rs._inputLast.slider(en);
			}

			hvac_onoff.bind("change", function () {

				tag.thermostat.turnOff = !(hvac_onoff.is(":checked"));
				animateTstat(rs, tag);
				tstat_control("disable");

				$.ajax({
					url: WSROOT + "ethClient.asmx/ThermostatOnOff",
					data: JSON.stringify({ "thermostatId": tag.slaveId, "turnOff": tag.thermostat.turnOff }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () {
						tstat_control("enable");
					},
					success: function (retval, textStatus) {
						updateTag(tag = retval.d);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});

			});
			fan_onoff.bind("change", function () {
				var sw = $(this);
				tag.thermostat.fanOn = $(this).is(":checked");
				tstat_control("disable");

				$.ajax({
					url: WSROOT + "ethClient.asmx/ThermostatFanOnOff",
					data: JSON.stringify({ "thermostatId": tag.slaveId, "turnOn": tag.thermostat.fanOn }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () {
						tstat_control("enable");
					},
					success: function (retval, textStatus) {
						updateTag(tag = retval.d);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});

			});

			targetChoice.bind("change", function () {
				if (targetChoice.val() != tag.thermostat.targetUuid) {
					var oldhtml = show_finding(targetChoice, "Configuring...");
					tstat_control("disable");
					$.ajax({
						url: WSROOT + "ethClient.asmx/SetThermostatTarget",
						data: JSON.stringify({ "thermostatId": tag.slaveId, "tempSensorUuid": targetChoice.val(), "th_high": tag.thermostat.th_high, "th_low": tag.thermostat.th_low }),
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						complete: function () {
							tstat_control("enable");
						},
						success: function (retval, textStatus) {

							uuid2tag[tag.thermostat.targetUuid].thermostatRef = null;
							tag = retval.d;
							uuid2tag[tag.thermostat.targetUuid].thermostatRef = tag;
							updateTag(tag, true);

							//updateTempThresholdQ(uuid2tag[tag.thermostat.targetUuid].slaveId, rs._inputFirst, rs._inputLast);

							set_finding_text(targetChoice, "Starting Monitoring...");

							$.ajax({
								url: WSROOT + "ethClient.asmx/ArmTempSensor",
								data: "{id: '" + uuid2tag[tag.thermostat.targetUuid].slaveId + "'}",
								headers: allTagManager ? { 'X-Set-Mac': uuid2tag[tag.thermostat.targetUuid].mac } : null,
								success: function (retval, textStatus) {
									restore_finding(targetChoice, oldhtml);
									updateTag(retval.d, true);
								},
								error: function (xhr, textStatus, exception) {
									restore_finding(targetChoice, oldhtml);
									popup_error(xhr, null, null, exception.message);
								}
							});

						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
							restore_finding(targetChoice);
							targetChoice.val(tag.thermostat.targetUuid).selectmenu("refresh");
						}
					});
				}
			});
			element.bind("rangeslidereditend", function () {
				tag.thermostat.th_low = fromNativeTemp(rs._inputFirst.val());
				tag.thermostat.th_high = fromNativeTemp(rs._inputLast.val());
				animateTstat(rs, tag);
				tstat_control("disable");

				$.ajax({
					url: WSROOT + "ethClient.asmx/SetThermostatTarget",
					data: JSON.stringify({ "thermostatId": tag.slaveId, "tempSensorUuid": tag.thermostat.targetUuid, "th_high": tag.thermostat.th_high, "th_low": tag.thermostat.th_low }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					success: function (retval, textStatus) {
						updateTag(tag = retval.d, true);
						if (tag.thermostat.targetUuid != tag.uuid)
							popup("Configuring temperature monitoring at " + uuid2tag[tag.thermostat.targetUuid].name + "...", rs.solidBg);
						$.ajax({
							url: WSROOT + "ethClient.asmx/ArmTempSensor",
							data: "{id: '" + uuid2tag[tag.thermostat.targetUuid].slaveId + "'}",
							headers: allTagManager ? { 'X-Set-Mac': uuid2tag[tag.thermostat.targetUuid].mac } : null,
							success: function (retval, textStatus) {
								tstat_control("enable");
								updateTag(retval.d, true);
								if (tag.thermostat.targetUuid != tag.uuid)
									popup("Temperature monitoring successfully configured", rs.solidBg);
							},
							error: function (xhr, textStatus, exception) {
								popup_error(xhr, rs.solidBg, null, exception.message);
								tstat_control("enable");
							}
						});

					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
						tstat_control("enable");
					}
				});


			});
			animateTstat(rs, tag);
		}, 300);
	}

	if (tag.isWeMoLED) {
		html += ('	<div data-role="fieldcontain" style="text-align:center;"><label for="dimmer-{0}">Dimmer: </label><input type="number" data-role="slider" step=1 name="dimmer-{0}" id="dimmer-{0}" value="{1}" min="0" max="100" data-unit="%" /></div>')
			.format(tag.wid, tag.cap.toFixed(0));
		setTimeout(function () {
			var speed = $("#dimming-speed-" + tag.wid);
			speed.val(localStorage["dimming-speed-" + tag.uuid]).selectmenu("refresh");

			var element = $("#dimmer-" + tag.wid);
			element.bind('slidestop', function (event) {
				element.slider("disable");
				$.ajax({
					url: WSROOT + "WeMoLink.asmx/DimLED",
					data: JSON.stringify({id: tag.slaveId, dimTo: element.val(), speed: localStorage["dimming-speed-" + tag.uuid] = speed.val()}),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () {
						element.slider("enable");
					},
					success: function (retval, textStatus) {
						updateTag(retval.d);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});

			});
		}, 300);
	}

	if (tag.isCam) {
		html += ("<table><tr><td id='snapshots-{0}'><button id='loadSnapshotsBtn' data-icon=gear>Load</button></td></tr></table>").format(tag.wid);
		snapshot_cache[tag.uuid] = { snapshotOlderThan: dateToFileTime(new Date()) };
		setTimeout(function () { snapshotLoadMore($("#loadSnapshotsBtn"), tag); }, 100);
	}

	return html;
}
function setPostbackIntervalFor(btn, wid) {
	var tag = taglist_cache[wid];
	if (btn.val() == "0") {
		reqPostback(btn, wid);
		btn.val(tag.postBackInterval).selectmenu("refresh");
	}
	else if (btn.val() == "-1") {

		reviveOptions(btn, wid);
		btn.val(tag.postBackInterval).selectmenu("refresh");

	} else if (btn.val() == "-2") {

		oorOptions(btn, wid);
		btn.val(tag.postBackInterval).selectmenu("refresh");

	} else {
		var oldhtml = show_finding(btn, "Configuring...");
		$.ajax({
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn, null, exception.message); restore_finding(btn, oldhtml); },
			url: WSROOT + "ethClient.asmx/SetPostbackIntervalFor",
			data: "{id: " + tag.slaveId + ", sec:" + btn.val() + "}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				restore_finding(btn, oldhtml);
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				restore_finding(btn, oldhtml);
				btn.val(tag.postBackInterval).selectmenu("refresh");
				popup_error(xhr, null, null, exception.message);
			}
		});
	}
	return false;
}
function snapshotLoadMore(btn, tag) {
	var oldhtml = show_finding(btn, "Loading...");
	var cache = snapshot_cache[tag.uuid];
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/GetSnapshots2",
		data: JSON.stringify({ slaveId: tag.slaveId, topN: 32, olderThan: cache.snapshotOlderThan, includeVideos: true }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		complete: function () {
			btn.parent().remove();
		},
		success: function (retval, textStatus) {
			var listhtml = "";
			for (var i = 0; i < retval.d.length; i++) {
				var fn = retval.d[i];
				cache.snapshotOlderThan = fn.replace(/v|t/, "");
				if (!cache.latestDateTime) cache.latestDateTime = cache.snapshotOlderThan;

				var timestamp = fileTimeToDate(fn.replace(/v|t/,""));
				var dateString = timestamp.toLocaleDateString();
				if (cache.firstDateString == null) cache.firstDateString = dateString;
				if (cache.lastDateString != dateString) {
					if (listhtml != "") listhtml += "</li>";
					listhtml += ('<h5 class="snapshot-date">{0}</h5>').format(dateString);
					cache.lastDateString = dateString;
				}
				listhtml += htmlFromSnapshot(tag, fn, timestamp);
			}
			if (i == 32) {
				listhtml += '<button data-inline=1 data-icon="arrow-r" onclick="snapshotLoadMore($(this), {0}); return false;">Load more</button>'.format(tag.wid);
			}
			$("#snapshots-" + tag.wid).append(listhtml).trigger("create");
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message);
		}
	});
}
var deleting_snapshot = false;
function delete_snapshot(btn, wid, fn) {
	deleting_snapshot = true;
	var tag = taglist_cache[wid];
	$.ajax({
		url: WSROOT + "DropCamLink.asmx/DeleteSnapshot",
		data: JSON.stringify({ slaveId: tag.slaveId, fn: fn }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			btn.parent().remove();
			deleting_snapshot = false;
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message);
		}
	});
}
function open_snapshot(url, wid) {
	if (deleting_snapshot) return;
	var tag = taglist_cache[wid];
	var html; var type=url.slice(-1);
	if (type == "t") {
		$.ajax({
			url: WSROOT + "DropCamLink.asmx/GetTimeLapseInfo",
			data: JSON.stringify({ slaveId: tag.slaveId }),
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				popup("Time lapse is under way", null,
					"<center><table><tr><td>Will finish at</td><td> " + fileTimeToDate(retval.d.endTime).toLocaleString() + "</td></tr>" + 
					"<tr><td>Current progress</td><td> " + (retval.d.completed * 100).toFixed(0) + "%, " + (retval.d.currentSeq) + " frames captured</td></tr>" +
					"<tr><td>Started at </td><td>" + fileTimeToDate(retval.d.startTime).toLocaleString() + "</td></tr></table></center>");
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, null, null, exception.message);
			}
		});
		return;
	}
	else if (type == "v")
		html = '<video id="dropcamVideo" width="768" height="432" controls autoplay><source src="{0}webcams/{1}.mp4" type="video/mp4" /></video>'.format(WSROOT, url);
	else
		html = "<img src='{0}webcams/{1}.jpg' />".format(WSROOT, url);

	var holder = $("#taglist");
	if (holder.data('simpledialog')) {
		holder.data('simpledialog').options.fullHTML = html;
		holder.simpledialog('refresh').simpledialog('open');
	} else {
		holder.simpledialog({
			'left': ($.mobile.activePage.width()-768)/2,
			'mode': 'blank',
			'useDialog': false,
			'useDialogForceFalse': true, 
			'prompt': false,
			'forceInput': false,
			'useModal': true,
			pickPageTheme: 'c',
			'fullHTML': html,
			onClosed: function () {
				$("#dropcamVideo")[0].pause();
			}
		});
	}
	//if (isVideo) $("#dropcamVideo")[0].play();
}
function htmlFromSnapshot(tag, fn, timestamp)
{
	if (isMobile() || (fn.slice(-1)=="t"&&tag.beeping))
		return '<div onclick="open_snapshot(\'{1}/{2}\',{4}); return false;" style="background-image: url({0}webcams/{1}/{2}s.jpg); background-size: 100%" class="snapshot" title="{3}"></div>'
			.format(WSROOT, tag.uuid, fn, timestamp, tag.wid);
	else
		return '<div onclick="open_snapshot(\'{1}/{2}\',{4}); return false;" style="background-image: url({0}webcams/{1}/{2}s.jpg); background-size: 100%" class="snapshot" title="{3}"><span class="snapshot-delete" onclick="delete_snapshot($(this), {4},\'{2}\'); return false;"> Delete </span></div>'
			.format(WSROOT, tag.uuid, fn, timestamp, tag.wid);
}
$("#taglist").bind("expand", function (event) {
	var content = $(event.target).find(".ui-collapsible-content");
	if (content.html() == "") {
		content.html(createTagDetail(taglist_cache[$(event.target).data("slaveid")])).trigger("create");
		showTip3($(event.target).data("slaveid"));
	}
});

function refreshTagDetail(tag) {
	var content = $("#collapsible-" + tag.wid).find(".ui-collapsible-content");
	if (content != null && content.html()!=null && content.html().length>0) 
		content.html(createTagDetail(tag)).trigger("create");
}

function buttonTooltip(tag) {
	return tag.migrationPending ? "Re-try migrating to the new wireless setting" :
		(tag.needFreqCal ? "Correct " + (tag.freqOffset / 1000).toFixed(1) + "kHz offset" + (tag.freqCalApplied != 0 ? " (" + (tag.freqCalApplied / 1000).toFixed(1) + "kHz corrected)" : "") : "");
}
var tipShown = 0;
function showTip1() {
	if (loadPref("_shownTip1") == "t") return false;
	tipShown = 1;
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#taglist:eq(0)").children().first().find(".ui-collapsible-heading-right")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 230; 
	var top = targetRect.top - bodyRect.top + 22; 
	$('<div id="tip" class="tips arrow-u" style="left:' + left + '; top:' + top + '">Click here to switch between temperature, <br/>RH, battery, or last update to display</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip1", "t");
	return true;
}
function isTouchScreendevice() {
	return 'ontouchstart' in window||navigator.maxTouchPoints;
};
function showTipReOrder() {
	if(isTouchScreendevice()) return;
	if (window.NC) return;  
	if (loadPref("_shownTipReOrder") == "t") return;
	if ($("#tips-back").is(":visible")) return;

	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#taglist:eq(0)").children().eq(1).find(".ui-collapsible-heading-toggle")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 30;
	var top1 = targetRect.top - bodyRect.top + 40;
	$('<div id="tip" class="tips arrow-u" style="left:' + left + '; top:' + top1 + '">Drag here with mouse (on computers) up/down to re-arrange the order tags are displayed</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTipReOrder", "t");
}
function showTipOOR(slaveid) {
	if (loadPref("_shownTipOOR") == "t") return;
	if ($("#tips-back").is(":visible")) return;

	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#collapsible-"+slaveid).find(".ui-collapsible-heading-toggle")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 60;
	var top1 = targetRect.top - bodyRect.top + 40;
	$('<div id="tip" class="tips arrow-u" style="left:' + left + '; top:' + top1 + '">"Out of range" means that a tag is not sending periodic updates. If not physically out of range, <br/>this indicates that the battery is getting weak or tag is damaged. Try taking out battery and <br/>putting back in or replacing the battery. If that does not help, try <a href="http://store.wirelesstag.net/pages/support#factory_reset" target="_blank">factory reset</a>. </div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTipOOR", "t");
}
function showTip2() {
	if (loadPref("_shownTip2") == "t") return;
	tipShown = 2;
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#taglist:eq(0)").children().first().find(".ui-collapsible-heading-toggle")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 60; 
	var top = targetRect.top - bodyRect.top + 40; 
	$('<div id="tip" class="tips arrow-u" style="left:' + left + '; top:' + top + '">Click anywhere on tag name to show more buttons. <br>Drag with mouse (on computers) to change display order if you have multiple tags.</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip2", "t");
}
var tip_wid;
function showTip3(wid) {
	tip_wid = wid;
	if (loadPref("_shownTip3") == "t") return;
	tipShown = 3;
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#light-btn-" + wid + "-button")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 130;
	var top = targetRect.top - bodyRect.top + 60;
	$('<div id="tip" class="tips arrow-u" style="left:' + left + '; top:' + top + '">Try turning on/off LED <br> is a good way to check connectivity</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip3", "t");
}

function showTip4() {
	if (loadPref("_shownTip4") == "t") return;
	tipShown = 4;
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#pingBtn-"+tip_wid+"-button")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 110;
	var top = targetRect.top - bodyRect.top + 60;
	$('<div id="tip" class="tips arrow-u" style="left:' + left + '; top:' + top + '">Click here to set logging interval for <br>this sensor/tag individually</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip4", "t");
}
function showTip5() {
	if (loadPref("_shownTip5") == "t") return;
	tipShown = 5;
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#updateInterval")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 80;
	var top = targetRect.top - bodyRect.top - 50;
	$('<div id="tip" class="tips arrow-d" style="left:' + left + '; top:' + top + '">Click here to set logging interval for all tags</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip5", "t");
}
function showTipThWnd() {
	if (loadPref("_shownTipThWnd") == "t") return;
	if ($("#th_window_temp").length == 0) {
		showTip6();
		return;
	}
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#th_window_temp")[0].getBoundingClientRect();
	if (targetRect.top == 0) return;
	tipShown = 5.5;
	var left = targetRect.left - bodyRect.left - 50;
	var top = targetRect.top - bodyRect.top - 152;
	$('<div id="tip" class="tips arrow-d" style="left:' + left + '; top:' + top +
		'">Threshold window prevents too many too-cold/too-hot & back-to-normal events when temperature hovers exactly at the threshold. For example, if lower threshold is set to 10°C, with 2°C threshold window, too-cold events still trigger at your set threshold of 10°C, but back-to-normal event won\'t trigger until it is 12°C.</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTipThWnd", "t");
}

function showTip6() {
	if (loadPref("_shownTip6") == "t") return;
	if ($("#temp_monitor_interval").length == 0) return;

	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("#temp_monitor_interval")[0].getBoundingClientRect();
	if (targetRect.top == 0) return;
	tipShown = 6;
	var left = targetRect.left - bodyRect.left - 175;
	var top = targetRect.top - bodyRect.top - 135;
	$('<div id="tip" class="tips arrow-d" style="left:' + left + '; top:' + top +
		'">Sets how often tags measure temperature internally. <br>e.g. 5 min means if the temperature crosses thresholds<br>you will receive notification within 5 min, even if<br>you have recording/logging interval set to <br>once every hour or longer.</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip6", "t");
}

function showTip7() {
	if (loadPref("_shownTip7") == "t") return;
	tipShown = 7;
	var bodyRect = document.body.getBoundingClientRect();
	var targetRect = $("label[for='temp_monitor_interval']")[0].getBoundingClientRect();
	var left = targetRect.left - bodyRect.left - 75;
	var top = targetRect.top - bodyRect.top - 115;
	$('<div id="tip" class="tips arrow-d" style="left:' + left + '; top:' + top +
		'">Generally, hover mouse pointer over label <br>of a setting to display help about what that option<br> does (with mouse on web browser/PC only)</div>').appendTo($(document.body));
	$("#tips-back").show();
	savePref("_shownTip7", "t");
}


$("#tips-back").click(function () {
	$("#tips-back, .tips").fadeOut(300);
	window.setTimeout(function () {
		if (tipShown == 1) showTip2();
		else if (tipShown == 3) showTip4();
		else if (tipShown == 4) showTip5();
		else if (tipShown == 5.5) showTip6();
		else if (tipShown == 6) showTip7();
	}, 400);
});

var anyMs = false;
var flat_indicator_svg = '<rect height="12" width="12" rx="3" style="stroke:#6ebc1f; stroke-width:2;fill:{0}"></rect><rect x="16" height="12" width="12" rx="3" style="stroke:#6ebc1f; stroke-width:2;fill:{0}"></rect><rect y="16" height="12" width="12" rx="3" style="stroke:#6ebc1f; stroke-width:2;fill:{2}"></rect><rect x="16" y="16" height="12" width="12" rx="3" style="stroke:#6ebc1f; stroke-width:2;fill:{3}"></rect>';
var fc_on = "#6ebc1f", fc_off = "#fff";

function createTag(tag) {
	if (tag.isMsTag) anyMs = true;

	var tag_status = calculateTagStatus(tag, tag.isMsTag || tag.isPIR || tag.isReed, tag.isMoistureTag || tag.isWMETag, tag.isCurrentTag, tag.isHTU, tag.isFlat);
	var tag_theme = calculateTagTheme(tag);

	var html = ('<div data-slaveid="{3}" id="collapsible-{3}" {7} data-role="collapsible" data-theme="{0}"><h3 title="drag to move up & down" id=tagtitle-{3} {6}><span id=tagname-{3}>{1} {2}</span></h3><h3><div title="tap/click to switch" onclick="tempDispClick(event); return false;" class=ui-temp-display id=temp-display-{3}>{5}</div>')
		.format(tag_theme, tag.name, tag_status, tag.wid, 0, tempDisp(tag), tag.OutOfRange ? "class=oor" : "", isFiltered(tag) ? 'style="display:none;"' : "");
	if (tag.hasFlat)
		html += '<svg viewBox="-2 -2 32 32" id=flat-indicator-' + tag.wid + ' class="flat-indicator">' + flat_indicator_svg.format(tag.capRaw & 1 ? fc_on : fc_off, tag.capRaw & 2 ? fc_on : fc_off, tag.capRaw & 4 ? fc_on : fc_off, tag.capRaw & 8 ? fc_on : fc_off) + '</svg></h3>'; 
	else
		html += ('<span id=signal-icon-{0} class=ui-icon-signal-{1} title="{2}"></span></h3>').format(tag.wid, tag.alive ? signalToBars(tag) : 0, tagSignalTooltip(tag));

	tag.needFreqCal = (Math.abs(tag.freqOffset) > maxFreqOffset);

	if (tag.hasBeeper) {
		html += ('<button title="{4}" data-inline=1 id="beepbtn-{0}" data-corners=0 data-shadow=0 data-theme="{2}" onclick="togglebeep($(this), {0}); return false;"  data-icon={3}>{1}</button></span>')
							.format(tag.wid, tag.migrationPending ? "Migrate" : (tag.needFreqCal ? "Calibrate Radio" : (tag.beeping ? "Stop Beep" : "Beep")),
							(tag.migrationPending || tag.needFreqCal) ? "e" : (tag.beeping ? "b" : "c"), tag.migrationPending ? "refresh" : (tag.beeping ? "delete" : "search"), buttonTooltip(tag));
	} else {
		html += ('<button title="{3}" data-inline=1 id="updatebtn-{0}" data-corners=0 data-shadow=0 data-theme="{2}" onclick="togglebeep($(this), {0}); return false;"  data-icon="refresh">{1}</button>')
							.format(tag.wid, tag.migrationPending ? "Migrate" : (tag.needFreqCal ? "Calibrate Radio" : "Update"), (tag.needFreqCal || tag.migrationPending) ? "e" : "c", buttonTooltip(tag));

	}
	html += '</div>';
	/*var taglist_elem = document.getElementById('taglist');
	taglist_elem.innerHTML = html;
	$("#taglist").trigger('create');
	*/
	$(html).appendTo("#taglist").trigger('create');
	$("#collapsible-" + tag.wid).collapsible();

	if (!window.NC) {
		$("#taglist").sortable({
			delay: 300,
			helper: 'clone',
			'containment': 'parent',
			cancel: '.ui-slider-handle, .ui-flipswitch-on, .ui-btn-corner-all, .ui-head-btn, button',
			'opacity': 0.6,
			update: function (event, ui) {
				$("#taglist").resetRoundedEdges();
				$.ajax({
					url: WSROOT + "ethClient.asmx/ReorderTag2",
					data: JSON.stringify({
						"uuid1": taglist_cache[ui.item.data("slaveid")].uuid, "uuid_prev": ui.item.prev().data("slaveid") ? taglist_cache[ui.item.prev().data("slaveid")].uuid : null,
						"uuid_next": taglist_cache[ui.item.next().data("slaveid")] ? taglist_cache[ui.item.next().data("slaveid")].uuid : null
					})
				});
			}
		});
	}

	if (tag.notificationJS != null && tag.notificationJS != "null" && tag.notificationJS.length > 0) {
		notificationQueue.push(tag);
		if (notificationQueue.length == 1) {
			start_process_notification_queue();
		}
	}
}

var smoothie_loaded = false;
function loadSmoothie() {
	var newScript = document.createElement('script');
	newScript.type = 'text/javascript';
	newScript.src = 'styles/smoothie.js?11';
	document.getElementsByTagName("head")[0].appendChild(newScript);
}
// use filter_NC
function isFiltered(tag) {
	if (filter_NC == null || filter_NC.length != 2) return false;
	var keyword = filter_NC[0], scope = filter_NC[1];
	
	if (keyword == "" || tag.name.toLowerCase().indexOf(keyword) != -1 || tag.comment.indexOf(keyword) != -1) {
		if (scope > 0) {
			if (scope == 1 && tag.tempEventState != 2) {
				return true;
			}
			else if (scope == 2 && tag.tempEventState != 1) {
				return true;
			}
			else if (scope == 3 && tag.tempEventState != 3) {
				return true;
			}
			else if (scope == 4 && tag.tempEventState != 0) {
				return true;
			}
		}
		return false;
	} else
		return true;
}
// scope: =0: all, 1: toohot, 2: normal, 3: toocold, 4: off
// keyword must be lower case
function filterWithKeyword(keyword, scope) {
	filter_NC = [keyword, scope];
	$.each(taglist_cache, function (id, tag) {
		if (tag) {
			if (isFiltered(tag))
				$("#collapsible-" + tag.wid).hide();
			else
				$("#collapsible-" + tag.wid).show();
		}
	});
}
var filter_NC=null;
var taglist_sorted = [];
function createTagList() {
	
	$.ajax({
		url: WSROOT + (allTagManager?"ethClient.asmx/GetTagList2":"ethClient.asmx/GetTagList"),
		success: function (retval, textStatus) {
			/*$.each(nest_watcher, function (auth, watcher) {
				if(watcher._fb)
					watcher._fb.off();
			});
			nest_watcher = {};*/

			if (window.NC && !MN_registered) {
				var token = window.NC.registerMN(loginEmailAddress);
				if (token.indexOf("[") == 0)
					filter_NC = JSON.parse(token);
				MN_registered = true;
			}

			$.each(taglist_cache, function (id, tag) { tag._updated = false; });
			wid_counter = 0; uuid2tag = {}; tmgrs_dbids = {};
			taglist_sorted = retval.d;
			for (var i = 0; i < retval.d.length; i++) {
				updateTag(retval.d[i]);
				tmgrs_dbids[retval.d[i].dbid] = 1;			// used by GetNextUpdateForAllManagersOnDB
			}
			//$("#taglist").trigger('create');
			var hasZmodTag = false, hasLightTag = false;

			var suggestions = [];
			$.each(taglist_cache, function (id, tag) {
				if (tag) {
					suggestions.push(tag.name);
					if (tag.comment != null && tag.comment != "") suggestions.push(tag.comment);

					if (!tag._updated) {
						$("#collapsible-" + tag.wid).remove();
						$("#taglist").resetRoundedEdges();
						delete taglist_cache[id];
					} else {

						if (tag.thermostat != null) {
							var targetTag = uuid2tag[tag.thermostat.targetUuid];
							if (targetTag != null) targetTag.thermostatRef = tag;
						}

						if (tag.tagType == 26 || tag.tagType == 107) hasLightTag = true;
						if (tag.tagType == 106) hasZmodTag = true;
					}
				}
			});

			if (window.NC && window.NC.setSearchSuggestions) {
				window.NC.setSearchSuggestions(JSON.stringify(suggestions));
			}

			if (hasLightTag && $("#multi-stats-light-option").length == 0) {
				$("<option value='light' id='multi-stats-light-option'>Ambient Light</option>").insertAfter("#multi-stats-temp-option");
				$("#multi-stats").selectmenu("refresh");
			} else if ($("#multi-stats-light-option").length == 1 && !hasLightTag) {
				$("#multi-stats-light-option").remove();
				$("#multi-stats").selectmenu("refresh");
			}

			/*if (hasZmodTag && $("#multi-stats-zmod-option").length == 0) {
				$("<option value='tvoc' id='multi-stats-zmod-option'>Air Quality</option>").insertAfter("#multi-stats-temp-option");
				$("#multi-stats").selectmenu("refresh");
			} else if ($("#multi-stats-zmod-option").length == 1 && !hasZmodTag) {
				$("#multi-stats-zmod-option").remove();
				$("#multi-stats").selectmenu("refresh");
			}*/

			/*if (hasCurrentTag) {
				if (!smoothie_loaded) {
					loadSmoothie();
				} else {
					smoothie_redrawAll();
				}
			}*/

			if (initial_open_dialog) {
				if (window.location.search == "?temp_options") {
					initial_open_dialog = false;
					tempOptions(null, null);
					return;
				}
				else if (window.location.search == "?motion_options") {
					initial_open_dialog = false;
					msOptions(null, null);
					return;
				}
				else if (window.location.search == "?cap_options") {
					initial_open_dialog = false;
					capOptions(null, null);
					return;
				}
				else if (window.location.search.indexOf("?uuid=") == 0) {
					var uuid = window.location.search.substring(6);
					if (uuid2tag[uuid]) {
						tagToFocus = uuid2tag[uuid].wid;
						//focusOnTag();
					}
				}

			}

			if (retval.d.length > 0) {
				if (!showTip1())  // if tip1 has been displayed, do not show tip reorder
					if (retval.d.length > 1) {
						showTipReOrder();
					} else {
						// tip has been shown, there is only 1 tag, so open details for user
						if (isNaN(tagToFocus)) {
							$(".ui-collapsible-contain").eq(0).trigger("expand");				
						}
					}
			}

			if (window.NC) {

				if (window.NC.getPushNotificationPayload) {
					MN_onMessage(eval("(function(){return " + window.NC.getPushNotificationPayload() + ";})()"));
				}
			}
			focusOnTag();
			getNextUpdate();
			getDesktopPush();

			for (id in taglist_cache) {
				var tag = taglist_cache[id];
				if (tag.slaveId >= 0 && tag.OutOfRange) {
					showTipOOR(tag.slaveId);
					break;
				}
			}

			if(localStorage["mytaglist.stats.abandoned"]!="1")
				checkAbandoned();

		},
		error: function (xhr, textStatus, exception) {
			//popupDebug(xhr, btn);
			popup_error(xhr, null, null, exception.message);
		}
	});
}

["too_humid", "too_dry", "water_detected","water_dried","cap_normal", "temp_toohigh", "temp_toolow", "temp_normal", "too_bright", "too_dark", "light_normal", "door_opened", "motion_detected", "motion_timedout"].forEach(
	function (x) {
		$(".url_" + x).click(function () {
			eventURLOptions($(this), option_tag, x);
			return false;
		});
	});

$(".ifttt_create").click(function () {
	window.location.href = "https://ifttt.com/create/if-wirelesstag?sid=1";
	return false;
});

$("#ifttt_moved_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/TFdyq89P/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_moved_call").click(function () {
	window.location.href = "https://ifttt.com/applets/vNrRGgcC/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_opened_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/EVmYJ7Z9/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_opened_call").click(function () {
	window.location.href = "https://ifttt.com/applets/ADMKJNw4/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_detected_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/QmKBSj2Q/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_detected_call").click(function () {
	window.location.href = "https://ifttt.com/applets/qhfP5NaB/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_timedout_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/DKPTSydh/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});
$("#ifttt_timedout_call").click(function () {
	window.location.href = "https://ifttt.com/applets/PpXvKHWn/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?motion_options");
	return false;
});

$("#ifttt_toocold_call").click(function () {
	window.location.href = "https://ifttt.com/applets/uWJK9QyF/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});
$("#ifttt_toocold_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/Gbt8vQgT/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});
$("#ifttt_toohot_call").click(function () {
	window.location.href = "https://ifttt.com/applets/ANTiPcBQ/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});
$("#ifttt_toohot_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/MBPASaxK/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});

$("#ifttt_toowet_call").click(function () {
	window.location.href = "https://ifttt.com/applets/GbU3eVLS/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?cap_options");
	return false;
});

$(".ifttt_water_call").click(function() {
	window.location.href="https://ifttt.com/applets/vuDnJrPQ/embed?email="+loginEmailAddress+"&redirect_uri="+encodeURIComponent(window.location.origin+"/eth/index.html?cap_options");
	return false;
});
$(".ifttt_water_sms").click(function() {
	window.location.href = "https://ifttt.com/applets/veAaTiGD/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?cap_options");
	return false;
});

$("#ifttt_toowet_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/eqQyK6Ab/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?cap_options");
	return false;
});
$("#ifttt_toodry_call").click(function () {
	window.location.href = "https://ifttt.com/applets/kSiBPq74/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?cap_options");
	return false;
});
$("#ifttt_toodry_sms").click(function () {
	window.location.href = "https://ifttt.com/applets/BnMsUZBg/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?cap_options");
	return false;
});

$("#ifttt_tcc_up").click(function () {
	window.location.href = "https://ifttt.com/applets/uUf5J9bz/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});
$("#ifttt_tcc_down").click(function () {
	window.location.href = "https://ifttt.com/applets/uu9ExgeV/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});
$("#ifttt_tcc_off").click(function () {
	window.location.href = "https://ifttt.com/applets/eyWc2Ve5/embed?email=" + loginEmailAddress + "&redirect_uri=" + encodeURIComponent(window.location.origin + "/eth/index.html?temp_options");
	return false;
});

function processComet(text) {
	var tags = eval("(" + text + ")");
	if (tags != null) {
		if (Array.isArray(tags))
			for (var i = 0; i < tags.length; i++)
				updateTag(tags[i]);
		else {  
			// tags is jsonObject, can be either "serial": true/false  or payload 
			if (tags.alert) {
				MN_onMessage(tags);
			} else {
				for (mac in tags) {				
					var i = tmgrs_index[mac];
					if (i) tmgrs_cache[i].online = tags[mac];
				}
				refreshTagManagerDropDown(tmgrs_cache);
			}
		}
	} 
}
function getNextUpdateForOneDB(dbid) {
	return $.ajax({
		url: WSROOT + (allTagManager ? "ethComet.asmx?op=GetNextUpdateForAllManagersOnDB2" : "ethComet.asmx?op=GetNextUpdate2"),
		dataType: "xml",
		contentType: "text/xml; charset=\"utf-8\"",
		beforeSend: function (xhr) { xhr.setRequestHeader("SOAPAction", allTagManager ? '"http://mytaglist.com/ethComet/GetNextUpdateForAllManagersOnDB2"' : '"http://mytaglist.com/ethComet/GetNextUpdate2"'); },
		data: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><'
			+ (allTagManager ? "GetNextUpdateForAllManagersOnDB2" : "GetNextUpdate2") + ' xmlns="http://mytaglist.com/ethComet"' + (allTagManager ? '><dbid>' + dbid + '</dbid></GetNextUpdateForAllManagersOnDB2>' : "/>") + '</soap:Body></soap:Envelope>',
		error: function (xhr, textStatus, exception) {
			getNextUpdate_xhr = null;
			if (textStatus != "abort" && xhr.responseText)
				popup_error(xhr, $.mobile.pageContainer);
			else if (should_run_comet) {
				setTimeout(getNextUpdate, 1000);
			}
		},
		success: function (retval, textStatus, xhr) {
			var result = $(xhr.responseXML).find(allTagManager ? 'GetNextUpdateForAllManagersOnDB2Result' : 'GetNextUpdate2Result');
			if (result.length && result.attr("xsi:nil") != "true") {
				processComet(result.text());
			}
			if (getNextUpdate_xhr) {
				var index = getNextUpdate_xhr.indexOf(xhr);
				if (index != -1) {
					getNextUpdate_xhr[index] = getNextUpdateForOneDB(dbid);
				}
			}
		}
	});
}
function getDesktopPush() {
	if (window.MN) return;
	if(getDesktopPush_xhr!=null) return;

	getDesktopPush_xhr = $.ajax({
		url: WSROOT + "ethComet.asmx?op=GetDesktopPush",
		dataType: "xml",
		contentType: "text/xml; charset=\"utf-8\"",
		beforeSend: function (xhr) { xhr.setRequestHeader("SOAPAction", '"http://mytaglist.com/ethComet/GetDesktopPush"'); },
		data: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetDesktopPush xmlns="http://mytaglist.com/ethComet"/></soap:Body></soap:Envelope>',
		error: function (xhr, textStatus, exception) {
			getDesktopPush_xhr = null;
			if (textStatus != "abort" && xhr.responseText)
				popup_error(xhr, $.mobile.pageContainer);
			else if (should_run_comet) {
				setTimeout(getDesktopPush, 1000);
			}
		},
		success: function (retval, textStatus, xhr) {
			if (should_run_comet) {
				getDesktopPush_xhr = getDesktopPush();
			}
			var result = $(xhr.responseXML).find('GetDesktopPushResult');
			if (result.length && result.attr("xsi:nil") != "true") {
				processComet(result.text());
			}
		}
	});
}
var getNextUpdate_xhr = null;
function getNextUpdate() {
	should_run_comet = true;
	if (getNextUpdate_xhr) return;
	getNextUpdate_xhr = [];
	var dbids = allTagManager ? tmgrs_dbids : { 0: 0 };

	$.each(dbids, function (dbid, one) {
		getNextUpdate_xhr.push(getNextUpdateForOneDB(dbid));
	});
}
$("a.optionSubmit").click(function (event) {
	$(this).parent().parent().find("form").submit();
});

$("a.logout").click(function (event) {
	var btn = $(event.target);
	var oldhtml = show_finding(btn, "Signing Off...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/SignOut",
		success: function (retval, textStatus) {
			//$.mobile.changePage("signin.html", { transition: "slidedown" });
			location.replace("signin.html");
			if (window.NC) window.NC.signOut();
		},
		error: function (xhr, textStatus, exception) {
			restore_finding(btn, oldhtml);
			popup_error(xhr, btn, null, exception.message);
		}
	});
});


$("#addnewPage").live('pagebeforeshow', function () {
	$("#alternative_add_tag_options").show();
	$("#compat_notice").hide();
	$("#namingform").hide();
	$("#nestLinkForm").hide();
	$("#WeMoLinkForm").hide();
	$("#DropcamLinkForm").hide();
});

var searchCancelled = true;
var searchBtnHtml;
$("#addnewPage").live('pagebeforehide', function () {
	if (!searchCancelled) {
		searchCancelled = true;
		restore_finding($("#searchbtn"), searchBtnHtml);
	}
});
var newTagInfo = null;
function continueSearch(btn) {
	$.ajax({
		url: WSROOT + "ethClient.asmx/ScanNewTag2",
		data: "{timeout: 2000, searchV1Tag: " + $("#searchV1").is(":checked")+ "}",
		success: function (retval, textStatus) {
			if (retval.d != null) {

				newTagInfo = retval.d;
				
				$("#foundInfo_name")[0].innerHTML = (newTagInfo.description + " (rev." + newTagInfo.version2.toString(16).toUpperCase()+")");
				$("#foundInfo_signal")[0].innerHTML = (newTagInfo.signaldBm > -105 ? newTagInfo.signaldBm + "dBm" : "No Signal");
				$("#foundInfo_bat")[0].innerHTML = (Math.round(100.0 * retval.d.batteryVolt) / 100) + " volt";  //(Math.round(100.0 * ((retval.d.batteryVolt - 2.3) / 0.85)) + "% left");1

				if (newTagInfo.version1 >= 2) {
					$("#lockFlashChoice").show();
					if(!tmSetting.optimizeForV2Tag&&!$.isEmptyObject(taglist_cache)) {
						$("#compat_notice_text").text("Current wireless setting of your Tag Manager is compatible with old (version 1) tags. Although it still works with this new (version 2) tag, the tag's maximum possible range cannot be achieved. We recommend that you unpair all version 1 tags, migrate to an non-compatible wireless setting (such as 9.6kbps, 20kHz, w/ error checking) to take full advantage of this version 2 tag.");
						$("#compat_notice").show();
					} else {
						$("#compat_notice").hide();
					}
				} else {
					$("#lockFlashChoice").hide();
					
					if (tmSetting.optimizeForV2Tag) {
						$("#compat_notice_text").text("Current wireless setting of your Tag Manager is not compatible with old (version 1) tags. Before you can associate this old (version 1) tag, please migrate to a wireless setting that is compatible with version 1 tags, such as 20.3kbps, 140kHz, w/o error checking. ");
						$("#compat_notice").show();
					}
				}
				if (newTagInfo.version1 >= 4 || (newTagInfo.version2 > 0x90 && newTagInfo.tagType1 != 26) || newTagInfo.version2 > 0xB0 || (newTagInfo.tagType1==32 && newTagInfo.version2>=0x21)) {
					$("#cachedPostbackChoice").show();
					$("#cachedPostback").change(function () {
						if (this.checked) {
							if (localStorage["warned_cached_postback"] != "1") {
								alert("Please make sure you understand what this option does. With this option, if you set update every 10 minutes, temperature is recorded every 10 minutes, but is updated/transmitted to the app every 130 minutes including 13 data points in each update or transmission. You will NOT see recent temperature on screen unless you manually click update, but you will get longer battery life because it is more efficient to send more data in one transmission. In recorded temperature/RH/lux graphs, data points will be spaced every 10 minutes.");
								localStorage["warned_cached_postback"] = "1";
							}
						}
					});

				} else {
					$("#cachedPostbackChoice").hide();
				}
				if (newTagInfo.version2 >= 15) {
					$("#noLEDChoice").show();
				} else {
					$("#noLEDChoice").hide();
				}

				$("#alternative_add_tag_options").hide();

				var dead_tag_choices= "";
				for (id in taglist_cache) {
					var tag = taglist_cache[id];
					if (tag.slaveId >= 0 && tag.OutOfRange) {
						dead_tag_choices += ('<option value="{0}">{1}</option>').format(tag.slaveId, tag.name);
					}
				}
				if (dead_tag_choices.length>0) {
					$("#inheritTagOptions").show();
					$('#inheritTagMenu').html('<option value="-1">(Do not replace any tag)</option>' + dead_tag_choices).selectmenu('refresh');
				} else {
					$("#inheritTagOptions").hide();
					$('#inheritTagMenu').html("");
				}

				$("#namingform").show();

				searchCancelled = true;
				restore_finding(btn, searchBtnHtml);

				$("#addnew_name").val(newTagInfo.suggestedName);
				/*$.ajax({ url: WSROOT + "ethClient.asmx/SuggestNewTagName",
					success: function (retval) { $("#addnew_name").val(retval.d); },
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn, null, exception.message);
					}
				});*/

			} else if (!searchCancelled) {
				continueSearch(btn);
			} else {
				restore_finding(btn, searchBtnHtml);
			}
		},
		error: function (xhr, textStatus, exception) {
			restore_finding(btn, searchBtnHtml);
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
$("#searchbtn").bind("click", function (event) {
	event.preventDefault();
	searchCancelled = false;
	var btn = $(event.target);
	searchBtnHtml = show_finding(btn, "Searching...");
	continueSearch(btn);
});

var newTag;
$("#addnew_name").blur({ regex: "^\\S+", message: "Required" }, validate);
$("#namingform").bind('submit', function (event) {
	event.preventDefault();
	$("#namingform input").trigger('blur');
	if ($("label.error").length == 0) {
		var btn = $("#associate_submitBtn");
		var oldhtml = show_finding(btn, "Associating...");
		var name = $('#addnew_name').val(); var comment = $('#addnew_comment').val();
		$.ajax({
			url: WSROOT + "ethClient.asmx/AssociateNewTag6",
			data: JSON.stringify({"nameBase64": btoa(name),"commentBase64": btoa(comment),"taginfo": newTagInfo,"timeout": 6000,"lockFlash": $("#lockFlash").is(":checked"),"noLED": $("#noLED").is(":checked"),cachedPostback: $("#cachedPostback").is(":checked"),inheritSlaveId: $("#inheritTagMenu").val() == null ? -1 : $("#inheritTagMenu").val() }),
			success: function (retval, textStatus) {
				restore_finding(btn, oldhtml);

				newTag = retval.d;
				if (!newTag.alive) {
					if (btn.data("simpledialog")) {
						btn.simpledialog("open");
					}
					else {
						btn.simpledialog({
							mode: 'bool', prompt: "Tag failed to respond to association request. Did the tag beep twice or stop flashing?", useModal: true, forceInput: true, cleanOnClose: false,
							'useDialog': false,
							'useDialogForceFalse': true, 
							'buttons': {
								'No, nothing happened, still flashing (roll back)': {
									click: function () {
										$.ajax({
											url: WSROOT + "ethClient.asmx/DeleteTag",
											data: "{id: " + newTag.slaveId + "}"
										});
									}, icon: "back"
								},
								'Yes, it stopped flashing (treat as done)': {
									click: function () {
										$.mobile.changePage("#indexPage", { transition: device_transition }, true);

										updateTag(newTag);

										setTimeout(function () {

											/*if (newTag.isKumostat) {
												kumostatOptions($("#options-choice-" + newTag.wid), newTag);
											}*/

											pingTag($("#pingBtn-" + newTag.wid), newTag);
										}, 500);


									}, icon: "forward"
								}
							}
						});
					}
				} else {
					$.mobile.changePage("#indexPage", { transition: device_transition }, true);

					updateTag(newTag);
					setTimeout(function () {

						/*if (newTag.isKumostat) {
							kumostatOptions($("#options-choice-" + newTag.wid), newTag);
						}*/

						pingTag($("#pingBtn-" + newTag.wid), newTag);
					}, 500);
				}
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn, null, exception.message); restore_finding(btn, oldhtml);
			}
		});//.always(function () { restore_finding(btn, oldhtml); });
	}
});

//$("#loginEmail").blur({ regex: VALID_EMAIL_REGEX, message: "Valid email address required to recover password." }, validate);
$("#loginPwd").blur({ regex: "^.{3,}$", message: "password must be at least 3 characters" }, validate);

//$("#send_email_to").blur({ regex: VALID_EMAIL_REGEX, message: "Valid email address required for notification."}, validate);
//$("#send_email_to_oor").blur({ regex: VALID_EMAIL_REGEX, message: "Valid email address required for notification."}, validate);
$("#doormode").change(function () {
	if ($(this).val() === "1") {
		$("#hmc_timeout_mode").parent().hide();
		$("#non_door_mode_label").hide(); $("#door_mode_delay").parent().show();
		$(".motion_detect_mode_only").hide();
		$(".door_mode_only").show();
	} else {
		$("#hmc_timeout_mode").parent().show();
		$(".door_mode_only").hide();
		$("#door_mode_delay").parent().hide(); $("#non_door_mode_label").show();
		$(".motion_detect_mode_only").show();
	}
});	
$("#send_email").change(function () {
	if (this.checked) {
		$("#send_email_to_group").show();
		//if ($("#doormode").val()==="1") $("#send_email_on_close_group").show();
	} else { $("#send_email_to_group").hide(); /*$("#send_email_on_close_group").hide();*/ }
});
$("#send_tweet_ms").change(function () { if (this.checked) { $("#send_tweet_ms_group").show(); } else { $("#send_tweet_ms_group").hide(); } });
$("#send_email_oor").change(function () { if (this.checked) { $("#send_email_oor_group").show(); } else { $("#send_email_oor_group").hide(); } });
$("#send_tweet_oor").change(function () { if (this.checked) { $("#send_tweet_oor_group").show(); } else { $("#send_tweet_oor_group").hide(); } });
$("#send_email_cap2").change(function () { if (this.checked) { $("#send_email_cap2_group").show(); } else { $("#send_email_cap2_group").hide(); } });
$("#send_tweet_cap2").change(function () { if (this.checked) { $("#send_tweet_cap2_group").show(); } else { $("#send_tweet_cap2_group").hide(); } });

$("#send_email_cap3").change(function () { if (this.checked) { $("#send_email_cap3_group").show(); } else { $("#send_email_cap3_group").hide(); } });
$("#send_tweet_cap3").change(function () { if (this.checked) { $("#send_tweet_cap3_group").show(); } else { $("#send_tweet_cap3_group").hide(); } });

$("#send_email_lb").change(function () { if (this.checked) { $("#send_email_lb_group").show(); } else { $("#send_email_lb_group").hide(); } });
$("#send_tweet_lb").change(function () { if (this.checked) { $("#send_tweet_lb_group").show(); } else { $("#send_tweet_lb_group").hide(); } });
$("#send_email_temp").change(function () { if (this.checked) { $("#send_email_temp_group").show(); } else { $("#send_email_temp_group").hide(); } });
$("#send_tweet_temp").change(function () { if (this.checked) { $("#send_tweet_temp_group").show(); } else { $("#send_tweet_temp_group").hide(); } });
$("#send_email_lux").change(function () { if (this.checked) { $("#send_email_lux_group").show(); } else { $("#send_email_lux_group").hide(); } });
$("#send_tweet_lux").change(function () { if (this.checked) { $("#send_tweet_lux_group").show(); } else { $("#send_tweet_lux_group").hide(); } });

var capOptionSetup = false;
function setupCapOption() {
	$("#send_email_cap").change(function () { if (this.checked) { $("#send_email_cap_group").show(); } else { $("#send_email_cap_group").hide(); } });
	$("#send_tweet_cap").change(function () { if (this.checked) { $("#send_tweet_cap_group").show(); } else { $("#send_tweet_cap_group").hide(); } });
	$("#enableCapEvent").change(function () { if (this.checked) { $("#capEventGroup").show(); } else { $("#capEventGroup").hide(); } });
	$("#beep_at_pc_cap").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_cap_group").show(); } else { $("#beep_at_pc_vibrate_cap_group").hide(); } });
	capOptionSetup = true;
}

var currentOptionSetup = false;
function setupCurrentOption() {
	$("#send_email_current").change(function () { if (this.checked) { $("#send_email_current_group").show(); } else { $("#send_email_current_group").hide(); } });
	$("#send_tweet_current").change(function () { if (this.checked) { $("#send_tweet_current_group").show(); } else { $("#send_tweet_current_group").hide(); } });
	$("#enableCurrentEvent").change(function () { if (this.checked) { $("#currentEventGroup").show(); } else { $("#currentEventGroup").hide(); } });
	$("#beep_at_pc_current").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_current_group").show(); } else { $("#beep_at_pc_vibrate_current_group").hide(); } });
	currentOptionSetup = true;
}

$("#enableTempEvent").change(function () {
	if (this.checked) {
		$("#tempEventGroup").show(); setTimeout(function () { showTipThWnd(); }, 500);
	} else { $("#tempEventGroup").hide(); }
});
$("#enableLightEvent").change(function () { if (this.checked) { $("#luxEventGroup").show(); } else { $("#luxEventGroup").hide(); } });
$("#enableZmodEvent").change(function () { if (this.checked) { $("#vocEventGroup").show(); } else { $("#vocEventGroup").hide(); } });

$("#beep_at_pc").change(function () { if (this.checked) { $("#beep_at_pc_options").show(); } else { $("#beep_at_pc_options").hide(); } });
$("#beep_at_pc_oor").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_oor_group").show(); } else { $("#beep_at_pc_vibrate_oor_group").hide(); } });
$("#beep_at_pc_cap2").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_cap2_group").show(); } else { $("#beep_at_pc_vibrate_cap2_group").hide(); } });
$("#beep_at_pc_cap3").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_cap3_group").show(); } else { $("#beep_at_pc_vibrate_cap3_group").hide(); } });
$("#beep_at_pc_temp").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_temp_group").show(); } else { $("#beep_at_pc_vibrate_temp_group").hide(); } });
$("#beep_at_pc_lux").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_lux_group").show(); } else { $("#beep_at_pc_vibrate_lux_group").hide(); } });

$("#enLB").change(function () { if (this.checked) { $("#enLB_group").show(); } else { $("#enLB_group").hide(); } });
$("#beep_at_pc_lb").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_lb_group").show(); } else { $("#beep_at_pc_vibrate_lb_group").hide(); } });
//$("#beep_at_tag").change(function () { if (this.checked) { $("#beep_at_tag_options").show(); } else { $("#beep_at_tag_options").hide(); } });
$("#auto_reset_delay_timeout").change(function () {
	if ($(this).val() == 0) {
		$("#auto_reset_delay_timeout_val_group").show();
	} else {
		$("#auto_reset_delay_timeout_val_group").hide();
	}
});
$("#hmc_timeout_mode").change(function () {
	if (this.checked) {
		$("#auto_reset_delay").parent().hide(); $("#auto_reset_delay_timeout").parent().show(); $(".hmc_timeout_mode_only").show();
	} else {
		$("#auto_reset_delay").parent().show(); $("#auto_reset_delay_timeout").parent().hide(); $(".hmc_timeout_mode_only").hide();
	}
});

$("#en_autoarm").change(function () { if (this.checked) { $("#autoarm_group").show(); } else { $("#autoarm_group").hide(); } });

$("#en_autoarm2").change(function () { if (this.checked) { $("#autoarm_group2").show(); } else { $("#autoarm_group2").hide(); } });
$("#day1_sun").change(function () { if (this.checked)$("#day2_sun").attr("checked", false).checkboxradio("refresh");});
$("#day1_mon").change(function () { if (this.checked)$("#day2_mon").attr("checked", false).checkboxradio("refresh");});
$("#day1_tue").change(function () { if (this.checked)$("#day2_tue").attr("checked", false).checkboxradio("refresh");});
$("#day1_wed").change(function () { if (this.checked)$("#day2_wed").attr("checked", false).checkboxradio("refresh");});
$("#day1_thu").change(function () { if (this.checked)$("#day2_thu").attr("checked", false).checkboxradio("refresh");});
$("#day1_fri").change(function () { if (this.checked)$("#day2_fri").attr("checked", false).checkboxradio("refresh");});
$("#day1_sat").change(function () { if (this.checked)$("#day2_sat").attr("checked", false).checkboxradio("refresh");});
$("#day2_sun").change(function () { if (this.checked)$("#day1_sun").attr("checked", false).checkboxradio("refresh");});
$("#day2_mon").change(function () { if (this.checked)$("#day1_mon").attr("checked", false).checkboxradio("refresh");});
$("#day2_tue").change(function () { if (this.checked)$("#day1_tue").attr("checked", false).checkboxradio("refresh");});
$("#day2_wed").change(function () { if (this.checked)$("#day1_wed").attr("checked", false).checkboxradio("refresh");});
$("#day2_thu").change(function () { if (this.checked)$("#day1_thu").attr("checked", false).checkboxradio("refresh");});
$("#day2_fri").change(function () { if (this.checked)$("#day1_fri").attr("checked", false).checkboxradio("refresh");});
$("#day2_sat").change(function () { if (this.checked)$("#day1_sat").attr("checked", false).checkboxradio("refresh");});

var option_tag;
var msConfig = {
	email: null, send_email: false, sensitivity: 50, interval: 2, beep_pc: true, beep_pc_loop: false,
	beep_tag: false, beep_tag_autostop: true, door_mode: true, door_mode_delay: 0, door_mode_angle: 22.5,
	send_email_on_close: false, auto_reset_delay: -1, beep_pc_tts: true, mobile_notifications: [],
	aa1_tod: 0, ada1_tod: 0, aa2_tod: 0, ada2_tod: 0, aa1_en: false, aa2_en: false, aa1_dow: 0, aa2_dow: 0, tzo: 0
};
var cap2Config;

function mnOptions(btn, tag) {
	var oldhtml = show_finding(btn, "Loading...");
	$("#mnOptionTitle").text("Notification Settings for " + tag.name);
	option_tag = tag;
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadMobileNotificationConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#mnOptionPage"), { transition: device_transition, role: "dialog" });

			if (tag.cap > 0 || tag.isMoistureTag) {
				$("#capRep").val(msConfig.capReportFreq).selectmenu("refresh");
				$(".capOnly").show();
			} else $(".capOnly").hide();

			if (tag.hasALS) {
				$("#luxRep").val(msConfig.luxReportFreq).selectmenu("refresh");
				$(".luxOnly").show();
			} else $(".luxOnly").hide();

			$("#tempRep").val(msConfig.tempReportFreq).selectmenu("refresh");
			$("#rssiRep").attr("checked", msConfig.rssiMode).checkboxradio("refresh");
			$("#email_report_to").val(msConfig.email || loginEmailAddress);

			$("#mobileNotifications").children().remove();
			if (msConfig.mobile_notifications.length > 0) {
				var html = '<fieldset data-role="controlgroup" id="mn-list"><legend>Send to only:</legend>';
				for (var i = 0; i < msConfig.mobile_notifications.length; i++) {
					html += ('<input type="checkbox" name="mnc-{0}" id="mnc-{0}" class="custom" {1}/><label for="mnc-{0}">{2}</label>')
							.format(i, msConfig.mobile_notifications[i].disabled ? '' : 'checked="checked"', msConfig.mobile_notifications[i].name);
				}
				html += '</fieldset>';
				$(html).appendTo("#mobileNotifications");
				$("#mobileNotifications").trigger('create').show();
			}

			$("#btnDelete_mn").unbind("click").click(function (event) {
				event.preventDefault();
				var btn2 = $(this);
				if(confirm("This will unregister unchecked mobile device(s) for push notifications until the next time you run the app on these device(s). Continue?")){

					var oldhtml2 = show_finding(btn2, "Removing...");

					var todelete = [];
					for (var i = 0; i < msConfig.mobile_notifications.length; i++) {
						if (!$("#mnc-" + i).is(":checked"))
							todelete.push(msConfig.mobile_notifications[i].uuid);
					}

					$.ajax({
						url: WSROOT + "ethMobileNotifications.asmx/DeleteTokens",
						data: JSON.stringify({ "device_uuids": todelete }),
						complete: function () { restore_finding(btn2, oldhtml2);  },
						success: function (retval, textStatus) {

							for (var i = 0; i < msConfig.mobile_notifications.length; i++) {
								if (!$("#mnc-" + i).is(":checked")) {
									$("#mnc-" + i).parent().remove();
								}
							}
							$("#mn-list").controlgroup("refresh");
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				}
			});
			$("#mnOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#mnOptionForm input:visible").trigger('blur');
				//if ($("label.error").length == 0) {
				var btn = $("#btnOptionSubmit_mn");
				var oldhtml = show_finding(btn, "Saving...");

				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_mn").is(":checked");

				for (var i = 0; i < msConfig.mobile_notifications.length; i++) {
					msConfig.mobile_notifications[i].disabled = $("#mnc-" + i).is(":checked") ? false : true;
				}
				msConfig.tempReportFreq = $("#tempRep").val();
				msConfig.capReportFreq = $("#capRep").val();
				msConfig.luxReportFreq = $("#luxRep").val();
				msConfig.rssiMode = $("#rssiRep").is(":checked");
				msConfig.email = $("#email_report_to").val();

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveMobileNotificationConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
						//location.hash = "#indexPage";
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
				//}
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}

function batteryOptions(btn, wid) {
	if (btn.val() == 0) lbOptions(btn, wid);
	else {
		var tag = taglist_cache[wid];
		if (window.NC) {
			if (allTagManager) {
				window.NC.multiGraphUuids("\"" + tag.uuid + "\"", "batteryVolt");
			} else {
				window.NC.multiGraph(tag.slaveId, "batteryVolt");
			}
		}
		else {
			var id = allTagManager ? tag.uuid : tag.slaveId;

			var p = { slaveids: id, type: "batteryVolt" };
			stat_url = WSROOT+"eth/tempStatsMulti.html?" + jQuery.param(p);
			
			if (isMobile()) location.href = (stat_url);
			else window.open(stat_url, "_blank");
		}
	}
}
var apns_sound_choice=["Default", "Bip", "Droplet", "Quack", "Voltage", "Boing", "Honk", "Single Click", "Whit", "ChuToy", "Indigo", "Solemn", "Wild Eep", "Clink-Klank", "Laugh", "Sosumi", "Your Turn", "Computer Error", "Logjam", "Temple", "moof", "Door Bell", "Metal_Latch", "Thin Air", "Door Chime", "Monkey", "Train Horn", "Door_Close", "Uh oh", "End Fx", "Door Buzzer",
"Bottle Rocket", "Bell Sound Ring", "Answering Machine", "Munchausen", "Laser Blasts", "Ice Cubes",	"Metal Pan", "Power Off Computer", "Time Travel", "Zoom", "Alarm Frenzy"];

for (var i = 0; i < apns_sound_choice.length; i++) {
	$('<option/>').val(apns_sound_choice[i]).text(apns_sound_choice[i]).appendTo('.apns_sound_choice');
}

$('.apns_sound_choice').change(function () {
	if ($(this).val() != "Default")
		if (window.NC) 
			window.NC.playApnsSound($(this).val());
		else
			play_ogg($(this).val());
});

function tempCorr(volt, temperature) {
	return (volt + (temperature == 0.0 ? 0 : (temperature > 43 ? 2.4 / 35.0 : temperature > 15 ? (temperature - 23.0) * 0.1 / 35.0 : (temperature - 15.0) * 0.1 / 14 - 8.0 * 0.1 / 35.0))).toFixed(2);
}

function lbOptions(btn, wid) {
	var tag = taglist_cache[wid];

	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});

	$.ajax({
		url: WSROOT + "ethClient.asmx/LoadLowBatteryConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#lbOptionPage"), { transition: device_transition, role: "dialog" });
			$("#lbOptionTitle").text("Low Battery Warning Options for " + tag.name);

			$("#enLB").attr("checked", msConfig.enabled).checkboxradio("refresh").trigger("change");
			$("#lbTh").val(msConfig.threshold).slider("refresh");
			if (tag.useCoinCell) {
				$("#coinCellLBThInfo").show();
				$("#lbth_cold").text(tempCorr(msConfig.threshold, -20));
				$("#lbth_hot").text(tempCorr(msConfig.threshold, 85));
			} else
				$("#coinCellLBThInfo").hide();

			$("#lbTh").unbind("change").change(function () {
				msConfig.threshold = parseFloat($(this).val());
				$("#lbth_cold").text(tempCorr(msConfig.threshold, -20));
				$("#lbth_hot").text(tempCorr(msConfig.threshold, 85));
			});

			$("#send_email_lb").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
			$("#send_tweet_lb").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to_lb").val(msConfig.email || loginEmailAddress);
			$("#beep_at_pc_lb").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_tts_lb").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
			$("#apns_sound_lb").val(msConfig.apnsSound).selectmenu("refresh");

			$("#beep_at_pc_vibrate_lb").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");
			$("#lb_notify_every").val(msConfig.notify_every).selectmenu("refresh");

			$("#lbOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#lbOptionForm input:visible").trigger('blur');
				var btn = $("#btnOptionSubmit_lb");
				var oldhtml = show_finding(btn, "Saving...");

				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_lb").is(":checked");

				msConfig.enabled = $("#enLB").is(":checked");
				msConfig.send_email = $("#send_email_lb").is(":checked");
				msConfig.send_tweet = $("#send_tweet_lb").is(":checked");
				msConfig.email = $("#send_email_to_lb").val();
				msConfig.beep_pc = $("#beep_at_pc_lb").is(":checked");
				msConfig.beep_pc_tts = $("#beep_at_pc_tts_lb").is(":checked");
				msConfig.apnsSound = $("#apns_sound_lb").val();
				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_lb").is(":checked");
				msConfig.notify_every = $("#lb_notify_every").val();
				msConfig.threshold = $("#lbTh").val();

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveLowBatteryConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function populateResetTimeout(msConfig) {
	if ($('#auto_reset_delay_timeout option[value=' + msConfig.auto_reset_delay + ']').length == 0) {
		$("#auto_reset_delay_timeout").val(0).selectmenu("refresh");
		$("#auto_reset_delay_timeout_val").val(msConfig.auto_reset_delay);
		$("#auto_reset_delay_timeout_val_group").show();
	} else {
		$("#auto_reset_delay_timeout").val(msConfig.auto_reset_delay).selectmenu("refresh");
		$("#auto_reset_delay_timeout_val_group").hide();
	}
}

function msOptions(btn, tag) {
	if (localStorage) {
		if (tag == null) tag = taglist_cache[ localStorage["msOptions_wid"] ];
		else localStorage["msOptions_wid"] = tag.wid;
	}

	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadMotionSensorConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#msOptionPage"), { transition: device_transition, role: "dialog" });

			rnc_open=null; rnc_detected=null;
			$.ajax({
				url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 0 }),
				success: function (retval, textStatus) {
					for (var i = 0; i < retval.d.length; i++) {
						if (retval.d[i].eventType == 3) {
							rnc_open = retval.d[i]; 
						} else if (retval.d[i].eventType == 5) {
							rnc_detected = retval.d[i]; 
						}
					}
					$("#rn_open").val(rnc_open == null ? 0 : rnc_open.intervalSec).selectmenu("refresh");
					$("#rn_detected").val(rnc_detected==null ? 0 : rnc_detected.intervalSec).selectmenu("refresh");
				}
			});
			
			$("#btnDeleteMotionEvent").unbind("click").click(function (event) {
				event.preventDefault();
				var btn2 = $(this);
				if (confirm("This will permanently delete all motion sensor related event records for this sensor/tag. Continue?")) {
					var oldhtml2 = show_finding(btn2, "Deleting...");
					$.ajax({
						url: WSROOT + "ethLogs.asmx/DeleteEventData2",
						data: JSON.stringify({ id: tag.slaveId, sensorType: 0 }),
						complete: function () { restore_finding(btn2, oldhtml2); },
						success: function (retval, textStatus) {
							popup("Permanently deleted " + retval.d + " records.")
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				}
			});

			$("#optionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#optionForm input:visible").trigger('blur');
				//if ($("label.error").length == 0) {
				var btn2 = $("#btnOptionSubmit");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var btn3 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml3 = show_finding(btn3, "Saving...");

				var applyAll = $("#applyAll").is(":checked");

				msConfig.sensitivity = $("#sensitivity").val();
				if ((tag.rev & 0xf) == 0xA) {
					msConfig.interval = parseInt($("#responsiveness2").val()) + parseInt($("#responsiveness").val());
					msConfig.sensitivity2 = $("#sensitivity2").val();
				} else {
					msConfig.interval = $("#responsiveness").val();
				}
				msConfig.door_mode = ($("#doormode").val() == 1 ? true : false);
				msConfig.door_mode_angle = $("#thAngle").val();
				msConfig.door_mode_delay = $("#door_mode_delay").val();
				msConfig.auto_reset_delay = $("#auto_reset_delay").is(':visible') ? $("#auto_reset_delay").val() : ($("#auto_reset_delay_timeout").val()>0? $("#auto_reset_delay_timeout").val():$("#auto_reset_delay_timeout_val").val() );
				msConfig.hmc_timeout_mode = $("#hmc_timeout_mode").is(":checked");

				msConfig.silent_arming = $("#silent_arming").is(":checked");
				msConfig.send_tweet = $("#send_tweet_ms").is(":checked");
				msConfig.send_email = $("#send_email").is(":checked");
				msConfig.email = $('#send_email_to').val();
				msConfig.send_email_on_close = $("#send_email_on_close").is(":checked");
				msConfig.beep_pc = $("#beep_at_pc").is(":checked");
				msConfig.beep_pc_loop = $("#beep_at_pc_loop").is(":checked");
				msConfig.beep_pc_tts = $("#beep_at_pc_tts").is(":checked");
				msConfig.apnsSound = $("#apns_sound").val();
				msConfig.apns_pause = $("#apns_pause").val();

				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate").is(":checked");
				//msConfig.beep_tag = $("#beep_at_tag").is(":checked");
				//msConfig.beep_tag_autostop = $("#beep_at_tag_autostop").is(":checked");

				msConfig.aa1_en = $("#en_autoarm").is(":checked");
				msConfig.aa2_en = $("#en_autoarm2").is(":checked");
				msConfig.aa1_tod = $("#aa1_tod").val();
				msConfig.aa2_tod = $("#aa2_tod").val();
				msConfig.ada1_tod = $("#ada1_tod").val();
				msConfig.ada2_tod = $("#ada2_tod").val();
				msConfig.aa1_dow = $("#day1_sun").is(":checked") + 2 * $("#day1_mon").is(":checked") + 4 * $("#day1_tue").is(":checked")
							+ 8 * $("#day1_wed").is(":checked") + 16 * $("#day1_thu").is(":checked") + 32 * $("#day1_fri").is(":checked") + 64 * $("#day1_sat").is(":checked");
				msConfig.aa2_dow = $("#day2_sun").is(":checked") + 2*$("#day2_mon").is(":checked") + 4*$("#day2_tue").is(":checked")
							+8*$("#day2_wed").is(":checked") + 16*$("#day2_thu").is(":checked") + 32*$("#day2_fri").is(":checked") + 64*$("#day2_sat").is(":checked");
				msConfig.tzo = (new Date()).getTimezoneOffset();

				if ($("#rn_open").val() != 0 || rnc_open) rnc_open = { eventType: 3, intervalSec: $("#rn_open").val() };
				if ($("#rn_detected").val() != 0 || rnc_detected) rnc_detected = { eventType: 5, intervalSec: $("#rn_detected").val() };
				if (rnc_open || rnc_detected)
					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty: tag.uuid, sensorType: 0, config: [rnc_open, rnc_detected] })
					});

				$.ajax({
					complete: function () { restore_finding(btn2, oldhtml2); restore_finding(btn3, oldhtml3); },
					url: WSROOT + "ethClient.asmx/SaveMotionSensorConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
						//location.hash = "#indexPage";
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
				//}
			});

			if (tag.isMsTag && tag.rev >= 0xE && !(tag.rev == 0xF && tag.tagType == 12)) {
				$("#hmc_timeout_mode").attr("checked", msConfig.hmc_timeout_mode).checkboxradio("refresh").trigger("change");
				if (msConfig.hmc_timeout_mode)
					populateResetTimeout(msConfig);
				$(".hmcV2p1Only").show();
			} else {
				$("#auto_reset_delay_timeout").parent().hide();
				$(".hmcV2p1Only").hide();
			}
			if (tag.hasBeeper) { $(".motionBuzzerOnly").show(); }
			else { $(".motionBuzzerOnly").hide(); }

			if (tag.isNest) {
				$("#doormode").val(0).trigger("change");
				$("#msOptionTitle").text("Home/Away Notification for " + tag.name);
				$("#auto_reset_delay_timeout").parent().hide();
				$("#auto_reset_delay").parent().hide();
				$(".hmcOnly").hide(); $(".sensitivity_sliders").hide(); $("#en_autoarm").parent().hide(); 
				$(".hide_for_pir").hide(); $(".show_for_pir").show();
			}
			else {
				$("#en_autoarm").parent().show();

				if (tag.isPIR) {
					$("#msOptionTitle").text("Infra-Red Sensor Options for " + tag.name);
					populateResetTimeout(msConfig);

					if (tag.rev >= 0x80) {
						$(".sensitivity_sliders").show();
						$("#sensitivity").val(msConfig.sensitivity).slider("refresh");
					} else
						$(".sensitivity_sliders").hide();

					$("#doormode").val(0).trigger("change");
					$(".hide_for_pir").hide(); $(".show_for_pir").show();

					$("#auto_reset_delay_timeout").parent().show();
					$("#auto_reset_delay").parent().hide();
					$(".hmcOnly").hide();
					$("#diff_als_info").hide();
				}
				else if (tag.hasALS) {
					$("#msOptionTitle").text("Motion Sensor Options for " + tag.name);
					$("#diff_als_info").show();
					$("#doormode").val(0).trigger("change");
					$(".hide_for_pir").hide(); $(".show_for_pir").show();
					$(".sensitivity_sliders").hide();
					$(".accelOnly").hide();
					$(".hmcOnly").hide();
					$(".angleOnly").show();
					$("#auto_reset_delay").val(msConfig.auto_reset_delay).selectmenu("refresh");
					$("#responsiveness").empty().append('<option value="1">Highest (worst battery life)</option><option value="2">Higher</option><option value="3">Medium</option><option value="4">Lower</option><option value="5">Lowest (best battery life)</option>');
					$("#responsiveness").val(msConfig.interval).selectmenu("refresh");
					$("#silent_arming").attr("checked", msConfig.silent_arming).checkboxradio("refresh");
				}
				else {
					$(".hide_for_pir").show(); $(".show_for_pir").hide();
					$("#diff_als_info").hide();

					if (tag.isReed) {
						$("#msOptionTitle").text("Reed Sensor Options for " + tag.name);
						$("#doormode").val(1).trigger("change");
						$("#auto_reset_delay_timeout").parent().hide();
						$("#auto_reset_delay").parent().hide();
						$(".hmcOnly").hide(); $(".sensitivity_sliders").hide();
					}
					else {
						$(".hmcOnly").show(); $(".sensitivity_sliders").show();

						$("#msOptionTitle").text("Motion Sensor Options for " + tag.name);
						$("#sensitivity").val(msConfig.sensitivity).slider("refresh");
						if ((tag.rev & 0xf) == 0xA) {
							$(".accelOnly").show(); $(".angleOnly").hide();
							$("#responsiveness").empty().append('<option value="7">400Hz (36uA, worst battery life)</option><option value="6">200Hz (18uA)</option><option value="5">100Hz (10uA)</option><option value="4">50Hz (6uA)</option><option value="3">25Hz (4uA)</option><option value="2">10Hz (3uA)</option><option value="1">1Hz (1uA, best battery life)</option>');
							$("#responsiveness").val(msConfig.interval & 0xF).selectmenu("refresh");
							$("#responsiveness2").val(msConfig.interval & 0xF0).selectmenu("refresh");
							$("#sensitivity2").val(msConfig.sensitivity2).slider("refresh");
						} else {
							$(".accelOnly").hide(); $(".angleOnly").show();
							$("#responsiveness").empty().append('<option value="1">Highest (worst battery life)</option><option value="2">Higher</option><option value="3">Medium</option><option value="4">Lower</option><option value="5">Lowest (best battery life)</option>');
							$("#responsiveness").val(msConfig.interval).selectmenu("refresh");
						}
						$("#thAngle").val(msConfig.door_mode_angle).slider("refresh");
						$("#auto_reset_delay").val(msConfig.auto_reset_delay).selectmenu("refresh");
						$("#silent_arming").attr("checked", msConfig.silent_arming).checkboxradio("refresh");
						$("#doormode").val(msConfig.door_mode ? "1" : "0").selectmenu("refresh").trigger("change");
					}
				}
			}
			$("#door_mode_delay").val(msConfig.door_mode_delay).selectmenu("refresh");
			$("#send_email").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
			$("#send_tweet_ms").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to").val(msConfig.email || loginEmailAddress);

			$("#send_email_on_close").attr("checked", msConfig.send_email_on_close).checkboxradio("refresh");

			$("#beep_at_pc").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_loop").attr("checked", msConfig.beep_pc_loop).checkboxradio("refresh");
			$("#beep_at_pc_tts").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh");
			$("#apns_sound").val(msConfig.apnsSound).selectmenu("refresh");
			$("#apns_pause").val(msConfig.apns_pause).selectmenu("refresh");

			$("#beep_at_pc_vibrate").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");
			//$("#beep_at_tag").attr("checked", msConfig.beep_tag).checkboxradio("refresh").trigger("change");
			//$("#beep_at_tag_autostop").attr("checked", msConfig.beep_tag_autostop).checkboxradio("refresh");

			$("#en_autoarm").attr("checked", msConfig.aa1_en).checkboxradio("refresh").trigger("change");
			$("#en_autoarm2").attr("checked", msConfig.aa2_en).checkboxradio("refresh").trigger("change");
			$("#aa1_tod").val(msConfig.aa1_tod).selectmenu("refresh");
			$("#aa2_tod").val(msConfig.aa2_tod).selectmenu("refresh");
			$("#ada1_tod").val(msConfig.ada1_tod).selectmenu("refresh");
			$("#ada2_tod").val(msConfig.ada2_tod).selectmenu("refresh");

			if (msConfig.aa1_dow == 0 && msConfig.aa2_dow == 0) {
				msConfig.aa1_dow = 62; msConfig.aa2_dow = 65;
			}
			$("#day1_sun").attr("checked", msConfig.aa1_dow & 1 ? true : false).checkboxradio("refresh");
			$("#day1_mon").attr("checked", msConfig.aa1_dow & 2 ? true : false).checkboxradio("refresh");
			$("#day1_tue").attr("checked", msConfig.aa1_dow & 4 ? true : false).checkboxradio("refresh");
			$("#day1_wed").attr("checked", msConfig.aa1_dow & 8 ? true : false).checkboxradio("refresh");
			$("#day1_thu").attr("checked", msConfig.aa1_dow & 16 ? true : false).checkboxradio("refresh");
			$("#day1_fri").attr("checked", msConfig.aa1_dow & 32 ? true : false).checkboxradio("refresh");
			$("#day1_sat").attr("checked", msConfig.aa1_dow & 64 ? true : false).checkboxradio("refresh");

			$("#day2_sun").attr("checked", msConfig.aa2_dow & 1 ? true : false).checkboxradio("refresh");
			$("#day2_mon").attr("checked", msConfig.aa2_dow & 2 ? true : false).checkboxradio("refresh");
			$("#day2_tue").attr("checked", msConfig.aa2_dow & 4 ? true : false).checkboxradio("refresh");
			$("#day2_wed").attr("checked", msConfig.aa2_dow & 8 ? true : false).checkboxradio("refresh");
			$("#day2_thu").attr("checked", msConfig.aa2_dow & 16 ? true : false).checkboxradio("refresh");
			$("#day2_fri").attr("checked", msConfig.aa2_dow & 32 ? true : false).checkboxradio("refresh");
			$("#day2_sat").attr("checked", msConfig.aa2_dow & 64 ? true : false).checkboxradio("refresh");

		}
		/*error: function (xhr, textStatus, exception) {
		popup_error(xhr, btn, null, exception.message);
		}*/
	});
}


$("#msOptionPage").live("pagebeforecreate", function () {
	//var tzo =  (new Date()).getTimezoneOffset();
	for (var h = 0; h < 24; h++) {
		for (var q = 0; q < 4; q++) {
			var lit = (h > 12 ? h - 12 : h) + ":" + (q == 0 ? "00" : q * 15) + (h >= 12 ? "PM" : "AM");
			var min_utc = h * 60 + q * 15; // + tzo;
			$('<option/>').attr('value', min_utc).text(lit).appendTo('#aa1_tod').clone().appendTo('#ada1_tod').clone().appendTo('#aa2_tod').clone().appendTo('#ada2_tod');
		}
	}
});

var degC_min = -35, degC_max = 105, degCmode = true;
var degF_min = degC_min * 9 / 5 + 32, degF_max = degC_max * 9 / 5 + 32;
var degC_step=0.1, degF_step=0.2;
//var degF_nest_min = 50, degF_nest_max = 90;
//var degC_nest_min = (degF_nest_min - 32) * 5 / 9, degC_nest_max = (degF_nest_max - 32) * 5 / 9;

function applyTempThresholdQ(q) {
	degC_min = q.min; degC_max = q.max;
	degF_min = degC_min * 9 / 5 + 32; degF_max = degC_max * 9 / 5 + 32;
	degC_step = q.step;
	degF_step = q.step * 9 / 5;
}
function updateTempThresholdQ(tag, min1, max1) {
	var min1_valC = degCmode ? min1.val() : (min1.val() - 32) * 5.0 / 9.0;
	var max1_valC = degCmode ? max1.val() : (max1.val() - 32) * 5.0 / 9.0;
		
	$.ajax({
		url: WSROOT + "ethClient.asmx/GetTemperatureThresholdQuantization",
		data: JSON.stringify({ "id": tag.slaveId, "sampleC1": min1_valC, "sampleC2": max1_valC }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			applyTempThresholdQ(retval.d);
			if (degCmode) {
				min1.attr("min", degC_min).attr("max", degC_max).attr("step", degC_step).val(retval.d.sample1.toFixed(2));
				max1.attr("min", degC_min).attr("max", degC_max).attr("step", degC_step).val(retval.d.sample2.toFixed(2));
			} else {
				min1.attr("min", degF_min).attr("max", degF_max).attr("step", degF_step).val((retval.d.sample1 * 9.0 / 5.0 + 32).toFixed(2));
				max1.attr("min", degF_min).attr("max", degF_max).attr("step", degF_step).val((retval.d.sample2 * 9.0 / 5.0 + 32).toFixed(2));
			}
		}
	});

}
$('#radio-RH').change(function () {
	dewPointMode = false; savePref("dewPointMode", "f");
});
$('#radio-DP').change(function () {
	dewPointMode = true; savePref("dewPointMode", "t");
});

function convertDegFToC() {
	var cal1 = $('#tempcal'); var cal1_val = cal1.val();
	cal1.attr("min", degC_min).attr("max", degC_max).val(((cal1_val - 32) * 5.0 / 9.0).toFixed(1));
	var min1 = $('#slider_min'); var min1_val = min1.val();
	min1.attr("min", degC_min).attr("max", degC_max).attr("step", degC_step).val(((min1_val - 32) * 5.0 / 9.0).toFixed(1));
	var max1 = $('#slider_max'); var max1_val = max1.val();
	max1.attr("min", degC_min).attr("max", degC_max).attr("step", degC_step).val(((max1_val - 32) * 5.0 / 9.0).toFixed(1));

	$("#th_window_temp").attr("min", 0).attr("max", 5).attr("step", degC_step).val(($("#th_window_temp").val() * 5.0 / 9.0).toFixed(1));

	$("#tempcal,#slider_min,#slider_max,#th_window_temp").data("unit", "°C");
}
$('#radio-degC').change(function () {
	if (!degCmode) {
		convertDegFToC();
		degCmode = true;
	}
});
function convertDegCToF() {
	var cal1 = $('#tempcal'); var cal1_val = cal1.val();
	cal1.attr("min", degF_min).attr("max", degF_max).val((cal1_val * 9.0 / 5.0 + 32).toFixed(1));
	var min1 = $('#slider_min'); var min1_val = min1.val();
	min1.attr("min", degF_min).attr("max", degF_max).attr("step", degF_step).val((min1_val * 9.0 / 5.0 + 32).toFixed(1));
	var max1 = $('#slider_max'); var max1_val = max1.val();
	max1.attr("min", degF_min).attr("max", degF_max).attr("step", degF_step).val((max1_val * 9.0 / 5.0 + 32).toFixed(1));

	$("#th_window_temp").attr("min", 0).attr("max", 9).attr("step", degF_step).val(($("#th_window_temp").val() * 9.0 / 5.0).toFixed(1));

	$("#tempcal,#slider_min,#slider_max,#th_window_temp").data("unit", "°F");
}
$('#radio-degF').change(function () {
	if (degCmode) {
		convertDegCToF();
		degCmode = false;
	}
});

var empty_http_header_line='<div ><select data-inline=1 class="http_header_choice"><option value="0" selected>Unused</option></select> :  <input style="display:none; max-width: 100%" data-inline=1 type="text" class="http_header_value" value="" /></div>';
function populate_http_header_lines() {
	$(".http_header_choice").each(function() {
		if(this.children.length==1) {
			var sel=$(this);
			["Authorization","Content-Type","Cookie","Cache-Control","Host", "Origin", "Pragma","User-Agent"].forEach(function(h) {
				sel.append($("<option>",{value: h, text: h}));
			});
			sel.change(function() {
				if(!sel.data("used")) {
					sel.data("used",true);
					sel.parent().parent().next().show();
					$("#http_header_list").append(empty_http_header_line).trigger("create");
					populate_http_header_lines();
				} else {
					if(sel.val()=="0") {
						sel.parent().parent().parent().remove();
					}
				}
			});
		}
	});
}
var currentEuConfig;
$(".http-verb-options").click(function (event) {
	event.preventDefault();
	var x = $(this).data("entry");

	var html = "<div style='padding: 15px; min-width:650px; '><b>HTTP Verb:</b><fieldset data-role='controlgroup' data-type='horizontal'>";
	var verbs = { GET: true, POST: false, PUT: false, DELETE: false };
	for (var verb in verbs) {
		html += "<input type='radio' name='http-verb' id='verb-{0}' value='{0}' /><label for='verb-{0}'>{0}</label>".format(verb);
	}

	currentEuConfig=eventURLConfig[x];
	var headers="";
	if(currentEuConfig.headers_json) {
		var json=JSON.parse(currentEuConfig.headers_json);
		for(var name in json ) {
			headers+='<div ><select data-inline=1 class="http_header_choice"><option value="0">Unused</option><option value="{0}" selected>{0}</option></select> : <input style="max-width: 100%" data-inline=1 type="text" class="http_header_value" value="{1}" /></div>'.format(name,json[name]);
		}
	} 
	headers+=empty_http_header_line;
	html+="</fieldset><b>HTTP Headers:</b><div data-role='fieldcontain' id='http_header_list'>"+headers+"</div><b>HTTP Body:</b><textarea id='http-content' style='width:650px;'></textarea></div>";

	var holder=$("#http-detail-parent");
	if(holder.data('simpledialog')) {
		holder.data('simpledialog').options.fullHTML=html;
		holder.simpledialog('refresh').simpledialog('open');
	}else
		holder.simpledialog({
			'left': ($.mobile.activePage.width()-600)/2,
			'mode': 'blank',
			'prompt': false,
			'forceInput': false,
			'useDialog': false,
			'useDialogForceFalse': true, 
			'useModal': true,
			pickPageTheme: 'c',
			'fullHTML': html,
			onClosed: function () {
				currentEuConfig.content = $("#http-content").val();
				currentEuConfig.verb=$('input:radio[name=http-verb]:checked').val();
				var json={};
				$(".http_header_choice").each(function() {
					var sel=$(this);
					if(sel.val()!="0") {
						json[sel.val()]=sel.parent().parent().next().val();
					}
				});
				currentEuConfig.headers_json=JSON.stringify(json);
			}
		});
	var selectedVerb = currentEuConfig.verb || "GET";
	$("#verb-" + selectedVerb).attr("checked", true).checkboxradio("refresh");// .parent().find("label").addClass("ui-btn-active");	
	$("#http-content").val(currentEuConfig.content);
	populate_http_header_lines();
	
});
$(".twitter_login").click(function (event) {
	event.preventDefault();
	$(this).closest("form").trigger("submit");
	twitterLogin($(this));
});
$(".facebook_login").click(function (event) {
	event.preventDefault();
	facebookLogin($(this));
});

/* function kumostatOptions(btn, tag) {
	var kConfig = {};
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadKumostatConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) kConfig = retval.d;

			$.mobile.changePage($("#kumostatOptionPage"), { transition: device_transition, role: "dialog" });
			$("#kumostatOptionTitle").text("Wiring Configuration for " + tag.name);
			
			$("#vdd_th").val(kConfig.vdd_exception_th).slider("refresh");
			for (var x in kConfig) {
				if (!isNaN(kConfig[x])) {
					[0, 1, 2, 4, 5, 6, 7].forEach(function (bit) {
						$('#kc_' + bit + '_' + x).attr("checked", (kConfig[x] & Math.pow(2, bit)) != 0).checkboxradio("refresh");
					});
				}
			}

			$("#kumostatOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#kumostatOptionForm input:visible").trigger('blur');

				//if ($("label.error").length == 0) {
				var btn1 = $("#btnOptionSubmit_kumostat");
				var oldhtml = show_finding(btn1, "Saving...");

				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_kumostat").is(":checked");

				for (var x in kConfig) {
					if (!isNaN(kConfig[x])) {
						kConfig[x] = 0;
						[0, 1, 2, 4, 5, 6, 7].forEach(function (bit) {
							if ($('#kc_' + bit + '_' + x).is(":checked")) kConfig[x] |= Math.pow(2, bit);
						});
					}
				}
				kConfig.vdd_exception_th = $("#vdd_th").val();

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveKumostatConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": kConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn1, oldhtml); restore_finding(btn2, oldhtml2);},
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
*/
/*
var vocOptionTag = null;
var last_voc_change_call = 0;
$('input[type=radio][name=voc-unit]').change(function () {
	var now = (new Date()).getTime();
	if (now - last_voc_change_call < 500) return;
	last_voc_change_call = now;

	var minmax = eval(this.value);
	try { $("#slider_max_voc").attr("min", minmax[0]).attr("max", minmax[1]).attr("step", minmax[1] / 2000); } catch (e) { }
	try { $("#slider_min_voc").attr("min", minmax[0]).attr("max", minmax[1]).attr("step", minmax[1] / 2000); } catch (e) { }

	$("#slider_max_voc").val(msConfig.lux_th_high).slider("refresh");
	$("#slider_min_voc").val(msConfig.lux_th_low).slider("refresh");

	$("#voc_range").rangeslider("setSolidBgAt", vocOptionTag.lux, "gray");
});

function update_voc_range(initial) {
	$('input[type=radio][name=voc-unit]').each(function () {
		var minmax = eval(this.value);
		if (minmax[0] < msConfig.lux_th_high && minmax[1] > msConfig.lux_th_high) {
			$(this).attr("checked", true).checkboxradio("refresh").trigger("change");
			if (initial) return false;
		} else
			$(this).attr("checked", false).checkboxradio("refresh");

		return true;
	});
}
function vocOptions(btn, wid) {
	var tag = taglist_cache[wid];
	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});

	vocOptionTag = tag;
	var oldhtml = show_finding(btn, ".");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadZmodSensorConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;
			$.mobile.changePage($("#vocOptionPage"), { transition: device_transition, role: "dialog" });

			$("#vocOptionTitle").text("Air Quality Sensor Options for " + vocOptionTag.name);
			$("#slider_min_voc").unbind("change").change(function () { msConfig.lux_th_low = this.value; });
			$("#slider_max_voc").unbind("change").change(function () { msConfig.lux_th_high = this.value; });
			$("#vocCal").val(tag.zmod.tvoc).slider("refresh");
			$("#rawVocReading").html(tag.zmod.raw_tvoc.toFixed(1));

			rnc_toosmelly = null; rnc_toofresh = null;
			$.ajax({
				url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 8 }),
				success: function (retval, textStatus) {
					for (var i = 0; i < retval.d.length; i++) {
						if (retval.d[i].eventType == 4) {
							rnc_toosmelly = retval.d[i];
						} else if (retval.d[i].eventType == 3) {
							rnc_toofresh = retval.d[i];
						}
					}
					$("#rn_toosmelly").val(rnc_toosmelly == null ? 0 : rnc_toosmelly.intervalSec).selectmenu("refresh");
					$("#rn_toofresh").val(rnc_toofresh == null ? 0 : rnc_toofresh.intervalSec).selectmenu("refresh");

					update_voc_range(true);
				}
			});


			$("#btnVocCalReset").unbind("click").click(function (event) {
				event.preventDefault();
				var btn2 = $("#btnVocCalReset");
				var oldhtml = show_finding(btn2, "Saving...");
				var raw_voc = tag.zmod.raw_tvoc;
				$.ajax({
					url: WSROOT + "ethClient.asmx/CalibrateZmod",
					data: "{id: '" + tag.slaveId + "', scale: 1.0}",
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn2, null, exception.message); restore_finding(btn2, oldhtml);
					},
					success: function (retval, textStatus) {
						restore_finding(btn2, oldhtml); updateTag(retval.d);
						$("#vocCal").val(retval.d.lux).slider("refresh");
						$("#voc_range").rangeslider("setSolidBgAt", retval.d.lux, "gray");
					}
				});
			});
			$("#btnVocCal").unbind("click").click(function (event) {
				event.preventDefault();
				var to = $("#vocCal").val();
				var btn2 = $("#btnVocCal");
				var oldhtml = show_finding(btn2, "Saving...");
				$.ajax({
					url: WSROOT + "ethClient.asmx/CalibrateZmod",
					data: "{id: '" + tag.slaveId + "', scale: '" + (to / tag.zmod.raw_tvoc) + "'}",
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn2, null, exception.message);	restore_finding(btn2, oldhtml);
					},
					success: function (retval, textStatus) {
						restore_finding(btn2, oldhtml);	updateTag(retval.d);
						$("#voc_range").rangeslider("setSolidBgAt", retval.d.lux, "gray");
					}
				});
			});

			$("#btnDeleteZmodEvent").unbind("click").click(function (event) {
				event.preventDefault();
				var btn2 = $(this);
				if (confirm("This will permanently delete all too record for this sensor/tag. Continue?")) {
					var oldhtml2 = show_finding(btn2, "Deleting...");
					$.ajax({
						url: WSROOT + "ethLogs.asmx/DeleteEventData2",
						data: JSON.stringify({ id: tag.slaveId, sensorType: 8 }),
						complete: function () { restore_finding(btn2, oldhtml2); },
						success: function (retval, textStatus) {
							popup("Permanently deleted " + retval.d + " records.")
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				}
			});

			$("#enableZmodEvent").attr("checked", vocOptionTag.lightEventState > 1).checkboxradio("refresh").trigger("change");

			$("#voc_toolow_delay").val(msConfig.th_low_delay);
			$("#voc_toohigh_delay").val(msConfig.th_high_delay);

			$("#send_email_voc").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
			$("#send_tweet_voc").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to_voc").val(msConfig.email || loginEmailAddress);
			$("#beep_at_pc_voc").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_tts_voc").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
			$("#apns_sound_voc").val(msConfig.apnsSound).selectmenu("refresh");
			$("#apns_pause_voc").val(msConfig.apns_pause).selectmenu("refresh");

			$("#beep_at_pc_vibrate_voc").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

			var org_th_low = msConfig.lux_th_low, org_th_high = msConfig.lux_th_high, org_th_low_delay = msConfig.th_low_delay, org_th_high_delay = msConfig.th_high_delay;

			$("#vocOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#vocOptionForm input:visible").trigger('blur');

				var btn1 = $("#btnOptionSubmit_voc");
				var oldhtml = show_finding(btn1, "Saving...");
				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_voc").is(":checked");

				msConfig.lux_th_low = $("#slider_min_voc").val();
				msConfig.lux_th_high = $("#slider_max_voc").val();
				//msConfig.lux_th_window = $("#th_window_voc").val();

				msConfig.th_low_delay = $("#voc_toolow_delay").val();
				msConfig.th_high_delay = $("#voc_toohigh_delay").val();

				msConfig.send_email = $("#send_email_voc").is(":checked");
				msConfig.send_tweet = $("#send_tweet_voc").is(":checked");
				msConfig.email = $("#send_email_to_voc").val();
				msConfig.beep_pc = $("#beep_at_pc_voc").is(":checked");
				msConfig.beep_pc_tts = $("#beep_at_pc_tts_voc").is(":checked");
				msConfig.apnsSound = $("#apns_sound_voc").val();
				msConfig.apns_pause = $("#apns_pause_voc").val();
				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_voc").is(":checked");

				if ($("#rn_toosmelly").val() != 0 || rnc_toosmelly) rnc_toosmelly = { eventType: 4, intervalSec: $("#rn_toosmelly").val() };
				if ($("#rn_toofresh").val() != 0 || rnc_toofresh) rnc_toofresh = { eventType: 3, intervalSec: $("#rn_toofresh").val() };
				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 8, config: [rnc_toosmelly, rnc_toofresh] })
				});

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveZmodSensorConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn1, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);

						if ($("#enableZmodEvent").is(":checked") &&
							(vocOptionTag.lightEventState <= 1 || org_th_high != msConfig.lux_th_high || org_th_low != msConfig.lux_th_low ||
								org_th_low_delay != msConfig.th_low_delay || org_th_high_delay != msConfig.th_high_delay)) {

							var oldhtml = show_finding(btn, "Configuring...");
							$.ajax({
								url: WSROOT + "ethClient.asmx/ArmLightSensor",
								data: "{id: '" + tag.slaveId + "'}",
								headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
								success: function (retval, textStatus) {
									restore_finding(btn, oldhtml); updateTag(retval.d);
								},
								error: function (xhr, textStatus, exception) {
									restore_finding(btn, oldhtml);
									popup_error(xhr, null, null, exception.message);
								}
							});
						}
						else if (!$("#enableZmodEvent").is(":checked") && vocOptionTag.lightEventState > 1) {
							var oldhtml = show_finding(btn, "Configuring...");
							$.ajax({
								url: WSROOT + "ethClient.asmx/DisarmLightSensor",
								data: "{id: '" + tag.slaveId + "'}",
								headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
								success: function (retval, textStatus) {
									restore_finding(btn, oldhtml); updateTag(retval.d);
								},
								error: function (xhr, textStatus, exception) {
									restore_finding(btn, oldhtml);
									popup_error(xhr, null, null, exception.message);
								}
							});
						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
*/
var lightOptionTag = null;
var last_lux_change_call = 0;
$('input[type=radio][name=lux-unit]').change(function () {
	var now = (new Date()).getTime();
	if (now - last_lux_change_call < 500) return;
	last_lux_change_call = now;

	var minmax = eval(this.value);
	//if (msConfig.lux_th_high <= minmax[1] && msConfig.lux_th_high > minmax[0]) {
		inside_lux_change = true;

		try { $("#slider_max_lux").attr("min", minmax[0]).attr("max", minmax[1]).attr("step", minmax[1] / 2000); } catch (e) { }
		try { $("#slider_min_lux").attr("min", minmax[0]).attr("max", minmax[1]).attr("step", minmax[1] / 2000); } catch (e) { }

		$("#slider_max_lux").val(msConfig.lux_th_high).slider("refresh");
		$("#slider_min_lux").val(msConfig.lux_th_low).slider("refresh");

		//	$("#th_window_lux").attr("min", 0).attr("max", minmax[1] / 20).attr("step", minmax[1] / 2000).val(msConfig.lux_th_window).slider("refresh");
		$("#lux_range").rangeslider("setSolidBgAt", lightOptionTag.lux, "gray");
	//}
});

function update_light_range(initial) {
	$('input[type=radio][name=lux-unit]').each(function () {
		var minmax = eval(this.value);
		if (minmax[0] < msConfig.lux_th_high && minmax[1] > msConfig.lux_th_high) {
			$(this).attr("checked", true).checkboxradio("refresh").trigger("change");
			if (initial) return false;
		} else 
			$(this).attr("checked", false).checkboxradio("refresh"); 

		return true;
	});
}

function lightOptions(btn, wid) {
	var tag = taglist_cache[wid];
	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});

	lightOptionTag = option_tag = tag;
	var oldhtml = show_finding(btn, ".");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadLightSensorConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;
			$.mobile.changePage($("#luxOptionPage"), { transition: device_transition, role: "dialog" });

			$("#luxOptionTitle").text("Light Sensor Options for " + lightOptionTag.name);
			$("#slider_min_lux").unbind("change").change(function () { msConfig.lux_th_low = this.value; });
			$("#slider_max_lux").unbind("change").change(function () { msConfig.lux_th_high = this.value; });

			rnc_toobright = null; rnc_toodark = null;
			$.ajax({
				url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 7 }),
				success: function (retval, textStatus) {
					for (var i = 0; i < retval.d.length; i++) {
						if (retval.d[i].eventType == 4) {
							rnc_toobright = retval.d[i];
						} else if (retval.d[i].eventType == 3) {
							rnc_toodark = retval.d[i];
						}
					}
					$("#rn_toobright").val(rnc_toobright == null ? 0 : rnc_toobright.intervalSec).selectmenu("refresh");
					$("#rn_toodark").val(rnc_toodark == null ? 0 : rnc_toodark.intervalSec).selectmenu("refresh");

					update_light_range(true);
				}
			});

			$("#btnDeleteLightEvent").unbind("click").click(function (event) {
				event.preventDefault();
				var btn2 = $(this);
				if(confirm("This will permanently delete all too bright/too dark/back to normal event record for this sensor/tag. Continue?")){
					var oldhtml2 = show_finding(btn2, "Deleting...");
					$.ajax({
						url: WSROOT + "ethLogs.asmx/DeleteEventData2",
						data: JSON.stringify({ id: tag.slaveId, sensorType: 7 }),
						complete: function () { restore_finding(btn2, oldhtml2); },
						success: function (retval, textStatus) {
							popup("Permanently deleted " + retval.d + " records.")
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				}
			});

			$("#enableLightEvent").attr("checked", lightOptionTag.lightEventState >1).checkboxradio("refresh").trigger("change");
			
	
			$("#lux_monitor_interval").val(msConfig.th_monitor_interval).selectmenu("refresh");
			$("#lux_toodark_delay").val(msConfig.th_low_delay);
			$("#lux_toobright_delay").val(msConfig.th_high_delay);

			$("#send_email_lux").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
			$("#send_tweet_lux").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to_lux").val(msConfig.email || loginEmailAddress);
			$("#beep_at_pc_lux").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_tts_lux").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
			$("#apns_sound_lux").val(msConfig.apnsSound).selectmenu("refresh");
			$("#apns_pause_lux").val(msConfig.apns_pause).selectmenu("refresh");

			$("#beep_at_pc_vibrate_lux").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

			var org_th_low = msConfig.lux_th_low, org_th_high = msConfig.lux_th_high, org_window = msConfig.lux_th_window,
			org_interval = msConfig.th_monitor_interval, org_th_low_delay = msConfig.th_low_delay, org_th_high_delay = msConfig.th_high_delay;

			$("#luxOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#luxOptionForm input:visible").trigger('blur');

				var btn1 = $("#btnOptionSubmit_lux");
				var oldhtml = show_finding(btn1, "Saving...");
				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_lux").is(":checked");

				msConfig.lux_th_low = $("#slider_min_lux").val();
				msConfig.lux_th_high = $("#slider_max_lux").val();
				//msConfig.lux_th_window = $("#th_window_lux").val();

				msConfig.th_low_delay = $("#lux_toodark_delay").val();
				msConfig.th_high_delay = $("#lux_toobright_delay").val();
				msConfig.th_monitor_interval = $("#lux_monitor_interval").val();
				
				msConfig.send_email = $("#send_email_lux").is(":checked");
				msConfig.send_tweet = $("#send_tweet_lux").is(":checked");
				msConfig.email = $("#send_email_to_lux").val();
				msConfig.beep_pc = $("#beep_at_pc_lux").is(":checked");
				msConfig.beep_pc_tts = $("#beep_at_pc_tts_lux").is(":checked");
				msConfig.apnsSound = $("#apns_sound_lux").val();
				msConfig.apns_pause = $("#apns_pause_lux").val();
				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_lux").is(":checked");

				if ($("#rn_toobright").val() != 0 || rnc_toobright) rnc_toobright = { eventType: 4, intervalSec: $("#rn_toobright").val() };
				if ($("#rn_toodark").val() != 0 || rnc_toodark) rnc_toodark = { eventType: 3, intervalSec: $("#rn_toodark").val() };
				if (rnc_toodark || rnc_toobright)
					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 7, config: [rnc_toobright, rnc_toodark] })
					});

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveLightSensorConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn1, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);

						if ($("#enableLightEvent").is(":checked") &&
							(lightOptionTag.lightEventState <= 1 || org_th_high != msConfig.lux_th_high || org_th_low != msConfig.lux_th_low || org_window != msConfig.lux_th_window ||
							org_interval != msConfig.th_monitor_interval || org_th_low_delay != msConfig.th_low_delay || org_th_high_delay != msConfig.th_high_delay)) {

							if (applyAll)
								all_tag_action(btn, "ArmLightSensorAll", "Configuring...");
							else {

								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/ArmLightSensor",
									data: "{id: '" + tag.slaveId + "'}",
									headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
									success: function (retval, textStatus) {
										restore_finding(btn, oldhtml); updateTag(retval.d, true);
									},
									error: function (xhr, textStatus, exception) {
										restore_finding(btn, oldhtml);
										popup_error(xhr, null, null, exception.message); 
									}
								});
							}
						}
						else if (!$("#enableLightEvent").is(":checked") && lightOptionTag.lightEventState > 1) {
							if (applyAll)
								all_tag_action(btn, "DisarmLightSensorAll", "Configuring...");
							else {

								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/DisarmLightSensor",
									data: "{id: '" + tag.slaveId + "'}",
									headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
									success: function (retval, textStatus) {
										restore_finding(btn, oldhtml); updateTag(retval.d);
									},
									error: function (xhr, textStatus, exception) {
										restore_finding(btn, oldhtml);
										popup_error(xhr, null, null, exception.message); 
									}
								});
							}
						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}

function capOptions(btn, id, isAnalog) {
	if (!capOptionSetup) setupCapOption();
	var tag = option_tag = taglist_cache[id];

	$(".btnDeleteCapEvent").unbind("click").click(function (event) {
		event.preventDefault();
		var btn2 = $(this);
		if (confirm("This will permanently delete all humidity/moisture/water-detect related event records for this sensor/tag. Continue?")) {
			var oldhtml2 = show_finding(btn2, "Deleting...");
			$.ajax({
				url: WSROOT + "ethLogs.asmx/DeleteEventData2",
				data: JSON.stringify({ id: tag.slaveId, sensorType: 2 }),
				complete: function () { restore_finding(btn2, oldhtml2); },
				success: function (retval, textStatus) {
					var num1 = retval.d;
					$.ajax({
						url: WSROOT + "ethLogs.asmx/DeleteEventData2",
						data: JSON.stringify({ id: tag.slaveId, sensorType: 2 }),
						complete: function () { restore_finding(btn2, oldhtml2); },
						success: function (retval, textStatus) {
							popup("Permanently deleted " + (num1 + retval.d) + " records.")
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, null, null, exception.message);
				}
			});
		}
	});
	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});

	var oldhtml = show_finding(btn, ".");
	if (isAnalog)	{
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			url: WSROOT + "ethClient.asmx/LoadCapSensorConfig",
			data: "{id: '" + tag.slaveId + "'}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				msConfig = retval.d;
				$.mobile.changePage($("#capOptionPage"), { transition: device_transition, role: "dialog" });

				$("#th_window_cap").unbind("change").change(function () { $("#cap_range").data("rangeslider").thwnd = parseFloat(this.value); });

				rnc_toowet = null; rnc_toodry = null;
				$.ajax({
					url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 2 }),
					success: function (retval, textStatus) {
						for (var i = 0; i < retval.d.length; i++) {
							if (retval.d[i].eventType == 4) {
								rnc_toowet = retval.d[i];
							} else if (retval.d[i].eventType == 3) {
								rnc_toodry = retval.d[i];
							}
						}
						$("#rn_toowet").val(rnc_toowet == null ? 0 : rnc_toowet.intervalSec).selectmenu("refresh");
						$("#rn_toodry").val(rnc_toodry == null ? 0 : rnc_toodry.intervalSec).selectmenu("refresh");
					}
				});

				$(".hide-for-flat").hide(); $(".show-for-flat").show();
				$(".water-sensor-only").hide();
				$("#capCalibration").hide();
				$(".rh-sensor-only").hide();
				$("#capOptionTitle").text("Analog Voltage Options for " + tag.name);
				$("#enableCapEvent").parent().find(".ui-btn-text").text("Monitor Analog Voltage ...");

				$("#analog_range").rangeslider("setSolidBgAt", tag.lux, "gray");
				$("#analog_min").val(msConfig.th_low).slider("refresh");
				$("#analog_max").val(msConfig.th_high).slider("refresh");
				$("#th_window_analog").val(msConfig.th_window).slider("refresh");

				$("#enableCapEvent").attr("checked", tag.capEventState > 1).checkboxradio("refresh").trigger("change");
				$("#capresponsiveness").parent().parent().parent().show();
				$("#capresponsiveness").val(msConfig.interval).selectmenu("refresh");
				$("#send_email_cap").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
				$("#send_tweet_cap").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
				$("#send_email_to_cap").val(msConfig.email || loginEmailAddress);
				$("#beep_at_pc_cap").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
				$("#beep_at_pc_tts_cap").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
				$("#apns_sound_cap").val(msConfig.apnsSound).selectmenu("refresh");
				$("#apns_pause_cap").val(msConfig.apns_pause).selectmenu("refresh");
				$("#beep_at_pc_vibrate_cap").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

				$("#capOptionForm").unbind("submit").submit(function (event) {
					event.preventDefault();
					$("#capOptionForm input:visible").trigger('blur');

					var btn1 = $("#btnOptionSubmit_cap");
					var oldhtml = show_finding(btn1, "Saving...");
					var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
					var oldhtml2 = show_finding(btn2, "Saving...");

					var applyAll = $("#applyAll_cap").is(":checked");

					var org_th_low = msConfig.th_low, org_th_high = msConfig.th_high, org_th_window = msConfig.th_window, org_interval = msConfig.interval;
					msConfig.th_low = $("#analog_min").val();
					msConfig.th_high = $("#analog_max").val();
					msConfig.th_window = $("#th_window_analog").val();

					msConfig.interval = $("#capresponsiveness").val();
					msConfig.send_email = $("#send_email_cap").is(":checked");
					msConfig.send_tweet = $("#send_tweet_cap").is(":checked");
					msConfig.email = $("#send_email_to_cap").val();
					msConfig.beep_pc = $("#beep_at_pc_cap").is(":checked");
					msConfig.beep_pc_tts = $("#beep_at_pc_tts_cap").is(":checked");
					msConfig.apnsSound = $("#apns_sound_cap").val();
					msConfig.apns_pause = $("#apns_pause_cap").val();

					msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_cap").is(":checked");

					if ($("#rn_toowet").val() != 0 || rnc_toowet) rnc_toowet = { eventType: 4, intervalSec: $("#rn_toowet").val() };
					if ($("#rn_toodry").val() != 0 || rnc_toodry) rnc_toodry = { eventType: 3, intervalSec: $("#rn_toodry").val() };
					if (rnc_toodry || rnc_toowet)
						$.ajax({
							url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 2, config: [rnc_toowet, rnc_toodry] })
						});

					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveCapSensorConfig",
						data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						complete: function () { restore_finding(btn1, oldhtml); restore_finding(btn2, oldhtml2) },
						success: function (retval, textStatus) {
							$.mobile.changePage("#indexPage", { transition: device_transition }, true);

							if ($("#enableCapEvent").is(":checked") && (tag.capEventState <= 1 || org_interval != msConfig.interval || org_th_high != msConfig.th_high || org_th_low != msConfig.th_low || org_th_window != msConfig.th_window)) {
								if (applyAll)
									all_tag_action(btn, "ArmAnalogSensorAll", "Configuring...");
								else {
									var oldhtml = show_finding(btn, "Configuring...");
									$.ajax({
										url: WSROOT + "ethClient.asmx/ArmCapSensor",
										data: "{id: '" + tag.slaveId + "'}",
										headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
										success: function (retval, textStatus) {
											restore_finding(btn, oldhtml);
											updateTag(retval.d, true);
										},
										error: function (xhr, textStatus, exception) {
											restore_finding(btn, oldhtml);
											popup_error(xhr, null, null, exception.message);
										}
									});
								}
							}
							else if (!$("#enableCapEvent").is(":checked") && tag.capEventState > 1) {
								if (applyAll) {
									all_tag_action(btn, "DisarmAnalogSensorAll", "Configuring...");
								}
								else {
									var oldhtml = show_finding(btn, "Configuring...");
									$.ajax({
										url: WSROOT + "ethClient.asmx/DisarmCapSensor",
										data: "{id: '" + tag.slaveId + "'}",
										headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
										success: function (retval, textStatus) {
											restore_finding(btn, oldhtml);
											updateTag(retval.d);
										},
										error: function (xhr, textStatus, exception) {
											restore_finding(btn, oldhtml);
											popup_error(xhr, null, null, exception.message);
										}
									});
								}
							}
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				});
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn, null, exception.message);
			}
		});
	}
	else if (tag.isFlat) {
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			url: WSROOT + "ethClient.asmx/LoadWaterSensorConfig",
			data: "{id: '" + tag.slaveId + "'}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				cap2Config = retval.d;
				$.mobile.changePage($("#flatOptionPage"), { transition: device_transition, role: "dialog" });

				$("#flatOptionTitle").text("Water Detect Options for " + tag.name);

				rnc_cap2 = null;
				$.ajax({
					url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 3 }),
					success: function (retval, textStatus) {
						for (var i = 0; i < retval.d.length; i++) {
							if (retval.d[i].eventType == 1) {
								rnc_cap2 = retval.d[i];
							}
						}
						$("#rn_cap3").val(rnc_cap2 == null ? 0 : rnc_cap2.intervalSec).selectmenu("refresh");
					}
				});

				$("#send_email_cap3").attr("checked", cap2Config.send_email).checkboxradio("refresh").trigger("change");
				$("#send_tweet_cap3").attr("checked", cap2Config.send_tweet).checkboxradio("refresh").trigger("change");
				$("#send_email_to_cap3").val(cap2Config.email || loginEmailAddress);
				$("#beep_at_pc_cap3").attr("checked", cap2Config.beep_pc).checkboxradio("refresh").trigger("change");
				$("#beep_at_pc_tts_cap3").attr("checked", cap2Config.beep_pc_tts).checkboxradio("refresh").trigger("change");
				$("#apns_sound_cap3").val(cap2Config.apnsSound).selectmenu("refresh");
				$("#beep_at_pc_vibrate_cap3").attr("checked", cap2Config.beep_pc_vibrate).checkboxradio("refresh");
				$("#notify_open_cap3").attr("checked", cap2Config.notify_open).checkboxradio("refresh");

				$("#shorted_threshold").val(tag.capCalOffset).selectmenu("refresh");
				$("#wpu1").val(tag.az2 & 1);
				$("#wpu2").val(tag.az2 & 50);
				$("#wpu3").val(tag.az2 & 116).trigger("change");		// if bit7~6 indicates analog is in 3 or 4, it will still contain bit4 = 16 which indicates analog is on. only bit7~6=0 and bit4=1 indicates analog is pin2. 
				$("#wpu4").val(tag.az2 & 184).trigger("change");

				$("#flatOptionForm").unbind("submit").submit(function (event) {
					event.preventDefault();
					$("#flatOptionForm input:visible").trigger('blur');
					var wpu = parseInt($("#wpu1").val()) + parseInt($("#wpu2").val()) + parseInt($("#wpu3").val()) + parseInt($("#wpu4").val());

					var btn1 = $("#btnOptionSubmit_flat");
					var task = wpu != tag.az2 ? "Configuring..."  : "Saving..."
					var oldhtml = show_finding(btn1, task);
					var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
					var oldhtml2 = show_finding(btn2, task);
					var applyAll = $("#applyAll_flat").is(":checked");

					cap2Config.send_email = $("#send_email_cap3").is(":checked");
					cap2Config.send_tweet = $("#send_tweet_cap3").is(":checked");
					cap2Config.email = $("#send_email_to_cap3").val();
					cap2Config.beep_pc = $("#beep_at_pc_cap3").is(":checked");
					cap2Config.beep_pc_tts = $("#beep_at_pc_tts_cap3").is(":checked");
					cap2Config.apnsSound = $("#apns_sound_cap3").val();

					cap2Config.beep_pc_vibrate = $("#beep_at_pc_vibrate_cap3").is(":checked");
					cap2Config.notify_open = $("#notify_open_cap3").is(":checked");

					if ($("#rn_cap3").val() != 0 || rnc_cap2) {
						rnc_cap2 = { eventType: 1, intervalSec: $("#rn_cap3").val() };
						$.ajax({
							url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 3, config: [rnc_cap2] })
						});
					}

					var need_update_analog = (tag.az2 & 16) == 0 && (wpu & 16) != 0; 

					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveWaterSensorConfig3",
						data: JSON.stringify({ "id": tag.slaveId, "config": cap2Config, "applyAll": applyAll, "threshold": $("#shorted_threshold").val(), "wpu":wpu }),
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						success: function (retval, textStatus) {
							$.mobile.changePage("#indexPage", { transition: device_transition }, true);
							updateTag(retval.d);

							if (need_update_analog) {
								var analog_btn = $("#analog-btn-" + tag.wid);
								var oldhtml = show_finding(analog_btn , "Updating...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
									data: "{id: '" + tag.slaveId + "'}",
									headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
									success: function (retval, textStatus) {
										updateTag(retval.d, true);
									},
									complete: function () {
										restore_finding(analog_btn, oldhtml);
									},
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null, null, exception.message);
									}
								});
							}

						},
						complete: function () {
							restore_finding(btn1, oldhtml);
							restore_finding(btn2, oldhtml2);
						},
						error: function (xhr, textStatus, exception) { popup_error(xhr, null, null, exception.message); }
					});
				});
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn, null, exception.message);
			}
		});
	} else {
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			url: WSROOT + "ethClient.asmx/LoadCapSensorConfig2",
			data: "{id: '" + tag.slaveId + "'}",
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			success: function (retval, textStatus) {
				msConfig = retval.d.rhEvent;
				cap2Config = retval.d.shortedEvent;
				$.mobile.changePage($("#capOptionPage"), { transition: device_transition, role: "dialog" });

				$("#th_window_cap").unbind("change").change(function () { $("#cap_range").data("rangeslider").thwnd = parseFloat(this.value); });

				rnc_toowet = null; rnc_toodry = null;
				$.ajax({
					url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 2 }),
					success: function (retval, textStatus) {
						for (var i = 0; i < retval.d.length; i++) {
							if (retval.d[i].eventType == 4) {
								rnc_toowet = retval.d[i];
							} else if (retval.d[i].eventType == 3) {
								rnc_toodry = retval.d[i];
							}
						}
						$("#rn_toowet").val(rnc_toowet == null ? 0 : rnc_toowet.intervalSec).selectmenu("refresh");
						$("#rn_toodry").val(rnc_toodry == null ? 0 : rnc_toodry.intervalSec).selectmenu("refresh");
					}
				});

				$(".hide-for-flat").show(); $(".show-for-flat").hide();
				if (tag.isWMETag) {
					$("#capCalibration").hide();
					$(".rh-sensor-only").hide();
					$("#capOptionTitle").text("WME Sensor Options for " + tag.name);
					$("#enableCapEvent").parent().find(".ui-btn-text").text("Monitor wood moisture equivalent (WME)...");
				}
				else if (tag.isHTU) {
					$('#radio-RH').attr("checked", !dewPointMode).checkboxradio("refresh");
					$('#radio-DP').attr("checked", dewPointMode).checkboxradio("refresh");

					$("#rawCapReading").html((tag.cap - tag.capCalOffset).toFixed(1));
					$("#capCalibration").show();
					$(".rh-sensor-only").show();
					$("#capOptionTitle").text("Humidity Sensor Options for " + tag.name);
					$("#enableCapEvent").parent().find(".ui-btn-text").text("Monitor humidity...");
				} else {
					$("#rawCapReading").html(((1.0 / tag.capRaw - 1.0 / 240.0) * (-100) / (1.0 / 240.0 - 1.0 / 8.0)).toFixed(1));
					$("#capCalibration").show();
					$("#capOptionTitle").text("Moisture Sensor Options for " + tag.name);
					$("#enableCapEvent").parent().find(".ui-btn-text").text("Monitor water-level/soil moisture...");
					$(".rh-sensor-only").hide();
				}
				if (cap2Config != null) {
					rnc_cap2 = null;
					$.ajax({
						url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 3 }),
						success: function (retval, textStatus) {
							for (var i = 0; i < retval.d.length; i++) {
								if (retval.d[i].eventType == 1) {
									rnc_cap2 = retval.d[i];
								}
							}
							$("#rn_cap2").val(rnc_cap2 == null ? 0 : rnc_cap2.intervalSec).selectmenu("refresh");
						}
					});

					$("#send_email_cap2").attr("checked", cap2Config.send_email).checkboxradio("refresh").trigger("change");
					$("#send_tweet_cap2").attr("checked", cap2Config.send_tweet).checkboxradio("refresh").trigger("change");
					$("#send_email_to_cap2").val(cap2Config.email || loginEmailAddress);
					$("#beep_at_pc_cap2").attr("checked", cap2Config.beep_pc).checkboxradio("refresh").trigger("change");
					$("#beep_at_pc_tts_cap2").attr("checked", cap2Config.beep_pc_tts).checkboxradio("refresh").trigger("change");
					$("#apns_sound_cap2").val(cap2Config.apnsSound).selectmenu("refresh");
					$("#beep_at_pc_vibrate_cap2").attr("checked", cap2Config.beep_pc_vibrate).checkboxradio("refresh");
					$("#notify_open_cap2").attr("checked", cap2Config.notify_open).checkboxradio("refresh");
					$(".water-sensor-only").show();
				} else {
					$(".water-sensor-only").hide();
				}

				$("#capCal").val(tag.cap).slider("refresh");
				$("#cap_range").rangeslider("setSolidBgAt", tag.cap, "gray");
				$("#cap_min").val(msConfig.th_low).slider("refresh");
				$("#cap_max").val(msConfig.th_high).slider("refresh");

				$("#th_window_cap").val(msConfig.th_window).slider("refresh");


				$("#enableCapEvent").attr("checked", tag.capEventState > 1).checkboxradio("refresh").trigger("change");

				//if (tag.rev >= 0x2F) {
				//	$("#capresponsiveness").parent().parent().parent().hide();
				//} else {
				$("#capresponsiveness").parent().parent().parent().show();
				$("#capresponsiveness").val(msConfig.interval).selectmenu("refresh");
				//}

				$("#send_email_cap").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
				$("#send_tweet_cap").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
				$("#send_email_to_cap").val(msConfig.email || loginEmailAddress);
				$("#beep_at_pc_cap").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
				$("#beep_at_pc_tts_cap").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
				$("#apns_sound_cap").val(msConfig.apnsSound).selectmenu("refresh");
				$("#apns_pause_cap").val(msConfig.apns_pause).selectmenu("refresh");

				$("#beep_at_pc_vibrate_cap").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");


				$("#btnCapCalReset").unbind("click").click(function (event) {
					event.preventDefault();
					var btn2 = $("#btnCapCalReset");
					var oldhtml = show_finding(btn2, "Saving...");
					$.ajax({
						url: WSROOT + "ethClient.asmx/ResetCapCalibration",
						data: "{id: '" + tag.slaveId + "'}",
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, btn2, null, exception.message);
							restore_finding(btn2, oldhtml);
						},
						success: function (retval, textStatus) {
							restore_finding(btn2, oldhtml);
							$("#cap_range").rangeslider("setSolidBgAt", retval.d.cap, "gray");
							$("#capCal").val(retval.d.cap).slider("refresh");
							updateTag(retval.d);
						}
					});
				});
				$("#btnCapCal").unbind("click").click(function (event) {
					event.preventDefault();
					var cap = $("#capCal").val();
					var btn2 = $("#btnCapCal");
					var oldhtml = show_finding(btn2, "Calibrating...");

					$.ajax({
						url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
						data: "{id: '" + tag.slaveId + "'}",
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						success: function (retval, textStatus) {
							tag = retval.d;
							$.ajax({
								url: WSROOT + "ethClient.asmx/CalibrateCapSensor",
								data: "{id: '" + tag.slaveId + "', capRaw: '" + tag.capRaw + "', to: '" + cap + "'}",
								headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
								complete: function () {
									$("#cap_range").rangeslider("setSolidBgAt", cap, "gray");
								},
								error: function (xhr, textStatus, exception) {
									popup_error(xhr, btn2, null, exception.message);
									restore_finding(btn2, oldhtml);
								},
								success: function (retval, textStatus) {
									restore_finding(btn2, oldhtml);
									updateTag(retval.d);
								}
							});

						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, btn2, null, exception.message);
							restore_finding(btn2, oldhtml);
						}
					});

				});



				$("#capOptionForm").unbind("submit").submit(function (event) {
					event.preventDefault();
					$("#capOptionForm input:visible").trigger('blur');
					//if ($("label.error").length == 0) {
					var btn1 = $("#btnOptionSubmit_cap");
					var oldhtml = show_finding(btn1, "Saving...");
					var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
					var oldhtml2 = show_finding(btn2, "Saving...");

					var applyAll = $("#applyAll_cap").is(":checked");

					var org_th_low = msConfig.th_low, org_th_high = msConfig.th_high, org_th_window = msConfig.th_window, org_interval = msConfig.interval;
					msConfig.th_low = $("#cap_min").val();
					msConfig.th_high = $("#cap_max").val();
					msConfig.th_window = $("#th_window_cap").val();

					msConfig.interval = $("#capresponsiveness").val();
					msConfig.send_email = $("#send_email_cap").is(":checked");
					msConfig.send_tweet = $("#send_tweet_cap").is(":checked");
					msConfig.email = $("#send_email_to_cap").val();
					msConfig.beep_pc = $("#beep_at_pc_cap").is(":checked");
					msConfig.beep_pc_tts = $("#beep_at_pc_tts_cap").is(":checked");
					msConfig.apnsSound = $("#apns_sound_cap").val();
					msConfig.apns_pause = $("#apns_pause_cap").val();

					msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_cap").is(":checked");

					if (cap2Config != null) {
						cap2Config.send_email = $("#send_email_cap2").is(":checked");
						cap2Config.send_tweet = $("#send_tweet_cap2").is(":checked");
						cap2Config.email = $("#send_email_to_cap2").val();
						cap2Config.beep_pc = $("#beep_at_pc_cap2").is(":checked");
						cap2Config.beep_pc_tts = $("#beep_at_pc_tts_cap2").is(":checked");
						cap2Config.apnsSound = $("#apns_sound_cap2").val();

						cap2Config.beep_pc_vibrate = $("#beep_at_pc_vibrate_cap2").is(":checked");
						cap2Config.notify_open = $("#notify_open_cap2").is(":checked");

						if ($("#rn_cap2").val() != 0 || rnc_cap2) {
							rnc_cap2 = { eventType: 1, intervalSec: $("#rn_cap2").val() };
							$.ajax({
								url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 3, config: [rnc_cap2] })
							});
						}
						$.ajax({
							url: WSROOT + "ethClient.asmx/SaveWaterSensorConfig",
							data: JSON.stringify({ "id": tag.slaveId, "config": cap2Config, "applyAll": applyAll }),
							headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
							error: function (xhr, textStatus, exception) { popup_error(xhr, null, null, exception.message); }
						});
					}

					if ($("#rn_toowet").val() != 0 || rnc_toowet) rnc_toowet = { eventType: 4, intervalSec: $("#rn_toowet").val() };
					if ($("#rn_toodry").val() != 0 || rnc_toodry) rnc_toodry = { eventType: 3, intervalSec: $("#rn_toodry").val() };
					if (rnc_toodry || rnc_toowet)
						$.ajax({
							url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 2, config: [rnc_toowet, rnc_toodry] })
						});

					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveCapSensorConfig",
						data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
						headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
						complete: function () { restore_finding(btn1, oldhtml); restore_finding(btn2, oldhtml2) },
						success: function (retval, textStatus) {
							$.mobile.changePage("#indexPage", { transition: device_transition }, true);

							if ($("#enableCapEvent").is(":checked") && (tag.capEventState <= 1 || org_interval != msConfig.interval || org_th_high != msConfig.th_high || org_th_low != msConfig.th_low || org_th_window != msConfig.th_window)) {
								if (applyAll)
									all_tag_action(btn, "ArmCapSensorAll", "Configuring...");
								else {
									var oldhtml = show_finding(btn, "Configuring...");
									$.ajax({
										url: WSROOT + "ethClient.asmx/ArmCapSensor",
										data: "{id: '" + tag.slaveId + "'}",
										headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
										success: function (retval, textStatus) {
											restore_finding(btn, oldhtml);
											updateTag(retval.d, true);
										},
										error: function (xhr, textStatus, exception) {
											restore_finding(btn, oldhtml);
											popup_error(xhr, null, null, exception.message);
										}
									});
								}
							}
							else if (!$("#enableCapEvent").is(":checked") && tag.capEventState > 1) {
								if (applyAll) {
									all_tag_action(btn, "DisarmCapSensorAll", "Configuring...");
								}
								else {
									var oldhtml = show_finding(btn, "Configuring...");
									$.ajax({
										url: WSROOT + "ethClient.asmx/DisarmCapSensor",
										data: "{id: '" + tag.slaveId + "'}",
										headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
										success: function (retval, textStatus) {
											restore_finding(btn, oldhtml);
											updateTag(retval.d);
										},
										error: function (xhr, textStatus, exception) {
											restore_finding(btn, oldhtml);
											popup_error(xhr, null, null, exception.message);
										}
									});
								}
							}
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				});
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn, null, exception.message);
			}
		});
	}
}
Array.prototype.sum = function () {
	for (var i = 0, sum = 0; i < this.length; sum += this[i++]) { };
	return sum;
}
function currentGetRms(tag) {
	return currentGetRmsRaw(tag) * tag.ampData.gain_cal;
}
function currentRemoveDC(ampData) {
	if (ampData == null) return;
	var waveform = ampData.waveform;
	if (waveform != null) {
		var avg = waveform.sum() / waveform.length;
		for (var i = 0; i < waveform.length; i++) {
			ampData.waveform[i] = waveform[i] - avg;
		}
	}
}
function currentGetRmsRaw(tag) {
	if (tag.ampData == null || tag.ampData.waveform == null) return 0;
	var waveform = tag.ampData.waveform;
	var power = 0;
	for (var i = 0; i < waveform.length; i++) {
		power += Math.pow(waveform[i], 2);
	}
	power = power / waveform.length;
	return Math.sqrt(power);
}

function toggleDS18(btn, id) {
	if(btn.val()=="1") {		// ds18
		applyDs18(taglist_cache[id],true,false,false,btn);
	} else if(btn.val()=="0") {		// thermocouple
		applyDs18(taglist_cache[id],false,false,false,btn);
	} else if(btn.val()=="2") {   // SHT20
		applyDs18(taglist_cache[id],false,true,false,btn);
	} else if(btn.val()=="4") {  // SHT3x
		applyDs18(taglist_cache[id],false,true,true,btn);
	} else if(btn.val()=="5") {  // RCO + DS18
		applyDs18(taglist_cache[id],true,false,true,btn);
	} else if(btn.val()=="6") {  // RCO + no DS18
		applyDs18(taglist_cache[id],false,false,true,btn);
	}
}
function updateDs18RadioBtn(tag) {

	$('#ds18-off').attr("checked",!tag.ds18&&!tag.shorted).checkboxradio("refresh");
	$('#ds18-off-sht20').attr("checked",!tag.ds18&&tag.shorted&&tag.az2!=1).checkboxradio("refresh");
	$('#ds18-off-sht3x').attr("checked",!tag.ds18&&tag.shorted&&tag.az2==1).checkboxradio("refresh");
	$('#ds18-on').attr("checked",tag.ds18&&!tag.shorted&&tag.az2!=1).checkboxradio("refresh");
	$("#ds18-rco").attr("checked",tag.ds18&&!tag.shorted&&tag.az2==1).checkboxradio("refresh");
	$("#ds18-off-rco").attr("checked",!tag.ds18&&!tag.shorted&&tag.az2==1).checkboxradio("refresh");
}
function applyDs18(tag, on, useSHT20, useSHT3x, btn2) {
	var oldhtml;
	var isButton = (btn2 != null);
	if (!isButton) {
		$("#ds18-off").checkboxradio("disable");
		$("#ds18-off-sht20").checkboxradio("disable");
		$("#ds18-off-sht3x").checkboxradio("disable");
		$("#ds18-on").checkboxradio("disable");
		$("#ds18-rco").checkboxradio("disable");
		$("#ds18-off-rco").checkboxradio("disable");

		btn2=on? (useSHT3x? $("#ds18-rco"):$("#ds18-on")) : (useSHT20? (useSHT3x? $("#ds18-off-sht3x"):$("#ds18-off-sht20")): (useSHT3x? $("#ds18-off-rco"):  $("#ds18-off") ));
		var btn_text = btn2.parent().find(".ui-btn-text");
		oldhtml = btn_text.text();
		btn_text[0].innerHTML = "Switching...";
	}
	else {
		oldhtml = show_finding(btn2, "Detecting...");
	}
	$.ajax({
		url: WSROOT + "ethClient.asmx/DetectExtTempSensor3",
		data: "{id: '" + tag.slaveId + "', detect: " + on + ", useSHT20: " + useSHT20 + ", useSHT3x: " + useSHT3x + "}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		complete: function () {
			if (isButton) restore_finding(btn2, oldhtml);
			else {
				$("#ds18-off").checkboxradio("enable");
				$("#ds18-off-sht20").checkboxradio("enable");
				$("#ds18-off-sht3x").checkboxradio("enable");
				$("#ds18-on").checkboxradio("enable");
				$("#ds18-rco").checkboxradio("enable");
				$("#ds18-off-rco").checkboxradio("enable");
				btn_text[0].innerHTML = oldhtml;
			}
		},
		error: function (xhr, textStatus, exception) {
			if(!isButton) {
				updateDs18RadioBtn(tag);
			}
			popup_error(xhr, btn2, null, exception.message);
		},
		success: function (retval, textStatus) {
			if (on) {
				var rom = retval.d;
				if (rom != null) {
					popup("Detected DS18B20 probe {0}-{1}-{2}-{3}-{4}-{5}, taking initial readings...".format(
						rom.s1.toString(16), rom.s2.toString(16), rom.s3.toString(16), rom.s4.toString(16), rom.s5.toString(16), rom.s6.toString(16)), btn2);

				} else {
					popup("Detected DS18B20 probe, taking initial readings...", btn2);
				}
			} else {
				popup("Changed to "+(useSHT20? "temp/humidity sensor":(useSHT3x?"soil moisture sensor":"k-Type thermocouple"))+", taking initial readings...",btn2);
			}
			$.ajax({
				url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
				data: "{id: '" + tag.slaveId + "'}",
				headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
				success: function (retval, textStatus) {
					popup("Temperature is {0}°C/{1}°F".format(
						Math.round(retval.d.temperature*10)/10, Math.round(10*(retval.d.temperature*9/5+32))/10),  btn2);
					updateTag(retval.d);

					if (retval.d.tempEventState > 0) {
						$.ajax({
							url: WSROOT + "ethClient.asmx/ArmTempSensor",
							data: "{id: '" + tag.slaveId + "'}",
							headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
							success: function (retval, textStatus) {
								popup("Reconfigured temperature monitoring");
							},
							error: function (xhr, textStatus, exception) {
								popup_error(xhr, btn2, null, exception.message);
							}
						});
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn2, null, exception.message);
				}
			});
		}
	});
}

function tempOptions(btn, wid) {
	if (localStorage) {
		if (wid == null) wid = localStorage["tempOptions_wid"];
		else localStorage["tempOptions_wid"] = wid;
	}
	var tag = option_tag =  taglist_cache[wid];

	$(".msg_template").unbind("click").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});
	var oldhtml = show_finding(btn, ".");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadTempSensorConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#tempOptionPage"), { transition: device_transition, role: "dialog" });
			$("#th_window_temp").unbind("change").change(function () { $("#temp_range").data("rangeslider").thwnd = parseFloat(this.value); });

			if (!degCmode) 
				$("#rawTempReading").html(((tag.temperature - tag.tempCalOffset) * 9.0 / 5.0 + 32).toFixed(1) + "°F");
			else
				$("#rawTempReading").html((tag.temperature - tag.tempCalOffset).toFixed(1) + "°C");

			$("#tempOptionTitle").text("Temperature Sensor Options for " + tag.name);
			if (tag.isTcProbe && tag.isThermocouple) {
				$("#ds18-off").parent().find(".ui-btn-text").text("Thermocouple (k-Type)")
			} else {
				$("#ds18-off").parent().find(".ui-btn-text").text("Internal")
			}
	
			rnc_toohot = null; rnc_toocold = null;
			$.ajax({
				url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 1 }),
				success: function (retval, textStatus) {
					for (var i = 0; i < retval.d.length; i++) {
						if (retval.d[i].eventType == 2) {
							rnc_toohot = retval.d[i];
						} else if (retval.d[i].eventType == 3) {
							rnc_toocold = retval.d[i];
						}
					}
					$("#rn_toohot").val(rnc_toohot == null ? 0 : rnc_toohot.intervalSec).selectmenu("refresh");
					$("#rn_toocold").val(rnc_toocold == null ? 0 : rnc_toocold.intervalSec).selectmenu("refresh");
				}
			});

			$("#btnDeleteTempEvent").unbind("click").click(function (event) {
				event.preventDefault();
				var btn2 = $(this);
				if(confirm( "This will permanently delete all too hot/too cold/back to normal event record for this sensor/tag. Continue?") ){
					var oldhtml2 = show_finding(btn2, "Deleting...");
					$.ajax({
						url: WSROOT + "ethLogs.asmx/DeleteEventData2",
						data: JSON.stringify({ id: tag.slaveId, sensorType: 1 }),
						complete: function () { restore_finding(btn2, oldhtml2); },
						success: function (retval, textStatus) {
							popup("Permanently deleted " + retval.d + " records.")
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null, null, exception.message);
						}
					});
				}
			});


			/*if (tag.isHTU) {
				$(".htuExclude").hide();
			} else {
				$(".htuExclude").show();
			}*/
			if (tag.hasDS18Switch) {
				if(tag.isTcProbe) {
					updateDs18RadioBtn(tag);
				} else {
					$('#ds18-on').attr("checked", tag.ds18).checkboxradio("refresh");
					$('#ds18-off').attr("checked", !tag.ds18).checkboxradio("refresh");
				}
				$("#ds18opt").show();
				if (tag.isTcProbe && tag.rev > 0x80) {
					$('#ds18-off-sht20-option').show();
					if (tag.rev > 0xB0) 
						$('#ds18-off-sht3x-option').show();
					else
						$('#ds18-off-sht3x-option').hide();
				} else {
					$('#ds18-off-sht20-option').hide();
					$('#ds18-off-sht3x-option').hide();
				}
				if(tag.isTcProbe&&tag.rev>0xD0) {
					$("#ds18-rco-option").show();
				} else {
					$("#ds18-rco-option").hide();
				}
				if (tag.isThermocouple || tag.isReed)
					$('#ds18-off-option').show();
				else
					$('#ds18-off-option').hide();

			} else {
				$("#ds18opt").hide();
			}
			$("#enableTempEvent").attr("checked", tag.tempEventState != 0).checkboxradio("refresh").trigger("change");

			degCmode = (msConfig.temp_unit == 0);
			if (tag.thermostatRef != null) { msConfig.threshold_q.min = 9; msConfig.threshold_q.max = 32; }
			applyTempThresholdQ(msConfig.threshold_q);

			if (!degCmode) {
				$('#radio-degF').attr("checked", true).checkboxradio("refresh");
				$('#radio-degC').attr("checked", false).checkboxradio("refresh");

				$("#th_window_temp").attr("min", 0).attr("max", Math.max(4.5, msConfig.threshold_q.step*9)).attr("step", msConfig.threshold_q.step * 9.0 / 5.0).val(msConfig.th_window * 9.0 / 5.0).slider("refresh");

				try{$("#slider_min").attr("min", degF_min).attr("max", degF_max).attr("step", msConfig.threshold_q.step*9.0/5.0).val(msConfig.th_low * 9.0 / 5.0 + 32).slider("refresh"); } catch (e) { }
				try{$("#slider_max").attr("min", degF_min).attr("max", degF_max).attr("step", msConfig.threshold_q.step * 9.0 / 5.0).val(msConfig.th_high * 9.0 / 5.0 + 32).slider("refresh"); } catch (e) { }
				//if(!tag.isHTU)
					$("#tempcal").attr("min", degF_min).attr("max", degF_max).val(tag.temperature * 9.0 / 5.0 + 32).slider("refresh");
				$("#temp_range").rangeslider("setSolidBgAt", tag.temperature * 9.0 / 5.0 + 32, "gray");
				$("#tempcal,#slider_min,#slider_max,#th_window_temp").data("unit", "°F");
			}
			else {
				$('#radio-degC').attr("checked", true).checkboxradio("refresh");
				$('#radio-degF').attr("checked", false).checkboxradio("refresh");

				$("#th_window_temp").attr("min", 0).attr("max", Math.max(2.5, msConfig.threshold_q.step*5)).attr("step", msConfig.threshold_q.step).val(msConfig.th_window).slider("refresh");
			    try { $("#slider_min").attr("min", degC_min).attr("max", degC_max).attr("step", msConfig.threshold_q.step).val(msConfig.th_low).slider("refresh"); } catch (e) { }
			    try { $("#slider_max").attr("min", degC_min).attr("max", degC_max).attr("step", msConfig.threshold_q.step).val(msConfig.th_high).slider("refresh"); } catch (e) { }
				//if (!tag.isHTU)
					$("#tempcal").attr("min", degC_min).attr("max", degC_max).val(tag.temperature).slider("refresh");
				$("#temp_range").rangeslider("setSolidBgAt", tag.temperature, "gray");
				$("#tempcal,#slider_min,#slider_max,#th_window_temp").data("unit", "°C");
			}
			if (tag.rev >= 0x2F) {
				$("#temp_monitor_interval").val(msConfig.interval).selectmenu("refresh");
				$("#temp_toocold_delay").val(msConfig.th_low_delay);
				$("#temp_toohot_delay").val(msConfig.th_high_delay);
				$(".rev2f_temp_options").show();
			} else {
				$(".rev2f_temp_options").hide();
			}
			$("#send_email_temp").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
			$("#send_tweet_temp").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to_temp").val(msConfig.email || loginEmailAddress);

			$("#notify_normal_temp").attr("checked", msConfig.notify_normal).checkboxradio("refresh").trigger("change");
			
			$("#beep_at_pc_temp").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_tts_temp").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
			$("#apns_sound_temp").val(msConfig.apnsSound).selectmenu("refresh");
			$("#apns_pause_temp").val(msConfig.apns_pause).selectmenu("refresh");

			$("#beep_at_pc_vibrate_temp").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

			var ds18Changed = false;
			if (tag.hasDS18Switch) {
				$("#ds18-off").unbind("change");
				$("#ds18-off-sht20").unbind("change");
				$("#ds18-off-sht3x").unbind("change");
				$("#ds18-rco").unbind("change");
				$("#ds18-on").unbind("change");

				$("#ds18-off").change(function() {			// k-type
					applyDs18(tag,false,false,false);
					ds18Changed=true;
				});
				$("#ds18-off-sht20").change(function() {			// sht20
					applyDs18(tag,false,true,false);
					ds18Changed=true;
				});
				$("#ds18-off-sht3x").change(function() {			// sht3x
					applyDs18(tag,false,true,true);
					ds18Changed=true;
				});
				$("#ds18-on").change(function() {			// ds18
					applyDs18(tag,true,false,false);
					ds18Changed=true;
				});
				$("#ds18-rco").change(function() {			// RCO+DS18
					applyDs18(tag,true,false,true);
					ds18Changed=true;
				});
				$("#ds18-off-rco").change(function() {			// RCO
					applyDs18(tag,false,false,true);
					ds18Changed=true;
				});
			}


			$("#btnTempCalReset").unbind("click").click(function (event) {
				event.preventDefault();

				var cap = $("#tempcal").val();
				var btn2 = $("#btnTempCalReset");
				var oldhtml = show_finding(btn2, "Saving...");
				var orgTempDegC = tag.temperature - tag.tempCalOffset;
				$.ajax({
					url: WSROOT + "ethClient.asmx/CalibrateTempSensor",
					data: "{id: '" + tag.slaveId + "', degCRaw: '" + (orgTempDegC) + "', to: '" + (orgTempDegC) + "'}",
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () {
						restore_finding(btn2, oldhtml);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn2, null, exception.message);
					},
					success: function (retval, textStatus) {
						$("#tempcal").val(degCmode ? orgTempDegC : (orgTempDegC * 9.0 / 5.0 + 32)).slider("refresh");
						$("#temp_range").rangeslider("setSolidBgAt", $("#tempcal").val(), "gray");
						updateTag(retval.d);
						updateTempThresholdQ(tag, $('#slider_min'), $('#slider_max'));
					}
				});
			});

			$("#btnTempCal").unbind("click").click(function (event) {
				event.preventDefault();

				var btn2 = $("#btnTempCal");
				var oldhtml = show_finding(btn2, "Calibrating...");
				var tempCalDegC = degCmode ? $("#tempcal").val() : ($("#tempcal").val() - 32) * 5.0 / 9.0;

				$.ajax({
					url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
					data: "{id: '" + tag.slaveId + "'}",
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					success: function (retval, textStatus) {

						tag = retval.d;
						$.ajax({
							url: WSROOT + "ethClient.asmx/CalibrateTempSensor",
							data: "{id: '" + tag.slaveId + "', degCRaw: '" + (tag.temperature - tag.tempCalOffset) + "', to: '" + tempCalDegC + "'}",
							headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
							complete: function () {
								restore_finding(btn2, oldhtml);
							},
							error: function (xhr, textStatus, exception) {
								popup_error(xhr, btn2, null, exception.message);
							},
							success: function (retval, textStatus) {
								$("#temp_range").rangeslider("setSolidBgAt", $("#tempcal").val(), "gray");
								updateTag(retval.d);
								updateTempThresholdQ(tag, $('#slider_min'), $('#slider_max'));
							}
						});

					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn2, null, exception.message);
						restore_finding(btn2, oldhtml);
					}
				});

			});
		//}
			$("#tempOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#tempOptionForm input:visible").trigger('blur');
				//if ($("label.error").length == 0) {
				var btn1 = $("#btnOptionSubmit_temp");
				var oldhtml = show_finding(btn1, "Saving...");
				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_temp").is(":checked");

				var org_th_low = msConfig.th_low, org_th_high = msConfig.th_high, org_window=msConfig.th_window, org_interval=msConfig.interval, org_th_low_delay=msConfig.th_low_delay, org_th_high_delay=msConfig.th_high_delay ;
				msConfig.th_low = degCmode ? $("#slider_min").val() : ($("#slider_min").val() - 32) * 5.0 / 9.0;
				msConfig.th_high = degCmode ? $("#slider_max").val() : ($("#slider_max").val() - 32) * 5.0 / 9.0;
				msConfig.th_window = degCmode ? $("#th_window_temp").val() : $("#th_window_temp").val() * 5.0 / 9.0;
				if(tag.rev>=0x2F){
					msConfig.th_low_delay = $("#temp_toocold_delay").val();
					msConfig.th_high_delay = $("#temp_toohot_delay").val();
					msConfig.interval = $("#temp_monitor_interval").val();					
				}
				msConfig.send_email = $("#send_email_temp").is(":checked");
				msConfig.send_tweet = $("#send_tweet_temp").is(":checked");

				msConfig.email = $("#send_email_to_temp").val();
				msConfig.beep_pc = $("#beep_at_pc_temp").is(":checked");
				msConfig.notify_normal = $("#notify_normal_temp").is(":checked");

				msConfig.beep_pc_tts = $("#beep_at_pc_tts_temp").is(":checked");
				msConfig.apnsSound = $("#apns_sound_temp").val();
				msConfig.apns_pause = $("#apns_pause_temp").val();
				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_temp").is(":checked");
				msConfig.temp_unit = degCmode ? 0 : 1;

				if ($("#rn_toohot").val() != 0 || rnc_toohot) rnc_toohot = { eventType: 2, intervalSec: $("#rn_toohot").val() };
				if ($("#rn_toocold").val() != 0 || rnc_toocold) rnc_toocold = { eventType: 3, intervalSec: $("#rn_toocold").val() };
				if (rnc_toohot || rnc_toocold)
					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 1, config: [rnc_toohot, rnc_toocold] })
					});

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveTempSensorConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn1, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);

						if ($("#enableTempEvent").is(":checked") &&
							(ds18Changed || tag.tempEventState == 0 || org_th_high != msConfig.th_high || org_th_low != msConfig.th_low || org_window != msConfig.th_window ||
							org_interval!=msConfig.interval || org_th_low_delay!=msConfig.th_low_delay || org_th_high_delay!=msConfig.th_high_delay)) {

							if (applyAll)
								all_tag_action(btn, "ArmTempSensorAll", "Configuring...");
							else {

								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/ArmTempSensor",
									data: "{id: '" + tag.slaveId + "'}",
									headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
									success: function (retval, textStatus) {
										restore_finding(btn, oldhtml);
										updateTag(retval.d, true);
									},
									error: function (xhr, textStatus, exception) {
										restore_finding(btn, oldhtml);
										popup_error(xhr, null, null, exception.message); 
									}
								});
							}
						}
						else if (!$("#enableTempEvent").is(":checked") && tag.tempEventState != 0) {
							if (applyAll)
								all_tag_action(btn, "DisarmTempSensorAll", "Configuring...");
							else {

								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/DisarmTempSensor",
									data: "{id: '" + tag.slaveId + "'}",
									headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
									success: function (retval, textStatus) {
										restore_finding(btn, oldhtml); updateTag(retval.d); 
									},
									error: function (xhr, textStatus, exception) {
										restore_finding(btn, oldhtml);
										popup_error(xhr, null, null, exception.message); 
									}
								});
							}
						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}

$("#wemo_autosearch").change(function () {
	var btn = $(this);
	$.ajax({
		url: WSROOT + "WeMoLink.asmx/SetAutoSearchWeMo",
		data: JSON.stringify({ enable: this.checked }),
		success: function (retval, textStatus) {},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
});

var oorGraceTag;
$("#oorGrace").change(function () {
	var btn = $(this);
	$.ajax({
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		},
		url: WSROOT + "ethClient.asmx/SetOutOfRangeGrace",
		data: "{id: " + oorGraceTag.slaveId + ", oorGrace:" + $(this).val() + ", applyAll:" + ($("#applyAll_oor").is(":checked") ? "true" : "false") + "}",
		headers: allTagManager ? { 'X-Set-Mac': oorGraceTag.mac } : null,
		success: function (retval, textStatus) {
			updateTag(retval.d);
			popup("Successfully configured to " + $("#oorGrace option:selected").text().toLowerCase(), btn);
		}
	});
});
$(".notification_email_address").blur(function () {	
	var btn = $(this);
	var new_email=$(this).val();
	var config=(msConfig==null||msConfig.email==null)? cap2Config:msConfig;
	if (new_email.trim() != config.email.trim()) {
		config.email = new_email;
		$.ajax({
			url: WSROOT + "ethAccount.asmx/ValidateEmail",
			data: JSON.stringify({ emails: new_email, send_test_email: true }),
			success: function (retval, textStatus) {
				var msg = "";
				for (var i = 0; i < retval.d.length; i++) {
					if (retval.d[i].success) {
						msg += "Sent a test email to '<b>" + retval.d[i].email + "</b>'. Please check if it has been received.<br/>"; 
					} else {
						msg += "Could not send email to '<b>" + retval.d[i].email + "</b>'. <b>Cause</b>: " + retval.d[i].error.replace(/\</g, "<").replace(/\>/g, ">") + ".<b>Recommendation</b>: " + retval.d[i].solution + "<br/>";
					}
				}
				popup(msg, null);
			}
		});
	}
});
function oorOptions(btn, id) {
	var tag = taglist_cache[id];
	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), tag);
	});

	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadOutOfRangeConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#oorOptionPage"), { transition: device_transition, role: "dialog" });
			$("#oorOptionTitle").text("Out of Range Notification Options for " + tag.name);

			rnc_oor = null;
			$.ajax({
				url: WSROOT + "ethClient.asmx/LoadRepeatNotifyConfig", data: JSON.stringify({ uuid: tag.uuid, sensorType: 4 }),
				success: function (retval, textStatus) {
					for (var i = 0; i < retval.d.length; i++) {
						if (retval.d[i].eventType == 1) {
							rnc_oor = retval.d[i];
						}
					}
					$("#rn_oor").val(rnc_oor == null ? 0 : rnc_oor.intervalSec).selectmenu("refresh");
				}
			});

			oorGraceTag = tag;
			$("#oorGrace").val(tag.oorGrace).selectmenu("refresh");

			$("#send_email_oor").attr("checked", msConfig.send_email_oor).checkboxradio("refresh").trigger("change");
			$("#send_tweet_oor").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to_oor").val(msConfig.email=msConfig.email_oor || loginEmailAddress);
			$("#beep_at_pc_oor").attr("checked", msConfig.beep_pc_oor).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_tts_oor").attr("checked", msConfig.beep_pc_tts_oor).checkboxradio("refresh").trigger("change");
			$("#apns_sound_oor").val(msConfig.apnsSound).selectmenu("refresh");
			$("#beep_at_pc_vibrate_oor").attr("checked", msConfig.beep_pc_vibrate_oor).checkboxradio("refresh");

			$("#oorOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#oorOptionForm input:visible").trigger('blur');
				//if ($("label.error").length == 0) {
				var btn = $("#btnOptionSubmit_oor");
				var oldhtml = show_finding(btn, "Saving...");
				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				var applyAll = $("#applyAll_oor").is(":checked");

				msConfig.send_email_oor = $("#send_email_oor").is(":checked");
				msConfig.send_tweet = $("#send_tweet_oor").is(":checked");
				msConfig.email_oor = $("#send_email_to_oor").val();
				msConfig.beep_pc_oor = $("#beep_at_pc_oor").is(":checked");
				msConfig.apnsSound = $("#apns_sound_oor").val();
				msConfig.beep_pc_tts_oor = $("#beep_at_pc_tts_oor").is(":checked");
				msConfig.beep_pc_vibrate_oor = $("#beep_at_pc_vibrate_oor").is(":checked");

				if ($("#rn_oor").val() != 0 || rnc_oor) {
					rnc_oor = { eventType: 1, intervalSec: $("#rn_oor").val() };
					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveRepeatNotifyConfig", data: JSON.stringify({ uuid: applyAll ? guid_empty : tag.uuid, sensorType: 4, config: [rnc_oor] })
					});
				}

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveOutOfRangeConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": msConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
						//location.hash = "#indexPage";
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
				//}
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
// { auth1: {nest_id1:tag1, nest_id2: tag2} .... }
//var nest_watcher = {};

var scannedNestThermostats = [];
$("#addNestBtn").bind("click", function (event) {
	event.preventDefault();
	var btn = $(this);
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "NestLink.asmx/ScanThermostats",
		data: "{}",
		success: function (retval, textStatus) {
			scannedNestThermostats = retval.d;
			var html = '<fieldset data-role="controlgroup" data-theme="c">';
			scannedNestThermostats.forEach(function (p) {
				html += "<input type='checkbox' name='nest-entry' id='nest-entry-{0}' {2} value='{0}' /><label for='nest-entry-{0}'>{1}</label>".format(
					p.device_id, p.name + (p.renamed_to? " (renamed to " + p.renamed_to+")":""), p.slaveId!=0?"checked" : "");
			});
			html += "</fieldset>";
			$("#edit-nest-link-choices").html(html).trigger('create');
			$("#nestLinkForm").show();
		},
		error: function (xhr, textStatus, exception) {
			//popupDebug(xhr, btn);
			nestLogin(btn);
		}
	});

});

$("#nestLinkForm").bind("submit", function (event) {
	event.preventDefault();
	var btn = $("#nestLink_submitBtn");
	var oldhtml = show_finding(btn, "Updating...");
	var npending = 0;
	scannedNestThermostats.forEach(function (p) {
		if (p.slaveId== 0 && $("#nest-entry-" + p.device_id).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "NestLink.asmx/Associate",
				data: JSON.stringify({ nest: p }),
				success: function (retval, textStatus) {
					//updateTag(retval.d);		// needed?
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		} else if (p.slaveId != 0 && !$("#nest-entry-" + p.device_id).is(":checked")) {
			npending++;
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "ethClient.asmx/DeleteTag",
				data: "{id: " + p.slaveId + "}",
				success: function (retval, textStatus) {
					var tag = taglist_cache[p.slaveId];
					/*if (tag) {
						delete nest_watcher[tag.thermostat.nest_auth][tag.thermostat.nest_id];
					}*/
					$("#collapsible-" + p.slaveId).remove();		// not wid because scanning nest is not accessible in all tag manager mode. 
					$("#taglist").resetRoundedEdges();
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn, null, exception.message);
				}
			});
		}
	});
	if (npending == 0) 
		$.mobile.changePage("#indexPage", { transition: device_transition }, true);

});

function honeywellLogin(btn) {
	var oldhtml = show_finding(btn, "Redirecting...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "HoneywellLink.asmx/GetAuthorizeURL",
		data: "{}",
		success: function (retval, textStatus) {
			if (retval.d != null) window.location.href = (retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function nestLogin(btn) {
	var oldhtml = show_finding(btn, "Redirecting...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "NestLink.asmx/GetAuthorizeURL",
		data: "{}",
		success: function (retval, textStatus) {
			if (retval.d != null) window.location.href = (retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function facebookLogin(btn) {
	var oldhtml = show_finding(btn, "Redirecting...");
	$.ajax({
		complete: function () {  },
		url: WSROOT + "ethAccount.asmx/GetFacebookLoginURL",
		data: "{}",
		success: function (retval, textStatus) {
			if (retval.d != null) window.location.href = (retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}

function twitterLogin(btn) {
	var oldhtml = show_finding(btn, "Redirecting...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethMobileNotifications.asmx/GetTwitterAuthorizeURL",
		data: "{}",
		success: function (retval, textStatus) {
			if (retval.d != null) window.location.href = (retval.d); //$.mobile.changePage(retval.d, { transition: device_transition, role: "dialog" });
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function removeTagManager(mac){
	$.ajax({
		url: WSROOT + "ethAccount.asmx/RemoveTagManager",
		data: JSON.stringify({ "mac": mac }),
		success: function (retval, textStatus) {
			$("#tm-" + mac).remove();
			$("#tagmanagerlist").resetRoundedEdges();
			needRefreshTagManagers = true;
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function UngroupTagManager(mac) {
	$.ajax({
		url: WSROOT + "ethAccount.asmx/UngroupTagManager",
		data: JSON.stringify({ "mac": mac }),
		success: function (retval, textStatus) {
			for (var i = 0; i < accountConfig.managers.length; i++) {
				var mgr = accountConfig.managers[i];
				if (mgr.mac == mac) {
					mgr.linkedToMac = "";
					processTagManagerList();
					break;
				}
			}
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}

var tmgrs = {}, tmgrs_changed = {};
function editname_mgr(btn, mac) {
	switch (btn.val()) {
		case "1":
			promptAsync("New tag manager name:", tmgrs[mac].name, function (newname) {
				if (newname) {
					tmgrs[mac].name = newname;
					tmgrs_changed[mac] = tmgrs[mac];
					$("#tmname-" + mac).text(newname);
				}
			});
			break;
		case "2":
			if (tmgrs[mac].selected) {
				alert("Cannot remove currently selected tag manager; please select a different tag manager from drop down menu in the main screen, then open Account Settings and try again");
				break;
			}
			if (!tmgrs[mac].allowMore) {
				confirmAsync("This tag manager is currently set not to allow adding more accounts. If you remove it now, you may never be able to add it back. Do you want to proceed?",
				function (ret) {
					if (ret) {
						removeTagManager(mac);
					}
				});
			}else
				removeTagManager(mac);
			break;
		case "3":
			UngroupTagManager(mac);

			break;
	}
}
function editNotifyOfflineEmail_mgr(mac, tb) {
	tmgrs[mac].notifyOfflineEmail = $(tb).val();
	tmgrs_changed[mac] = tmgrs[mac];
	return true;
}
function editNotifyOffline_mgr(mac, cb) {
	tmgrs[mac].notifyOffline = cb.checked;
	if(cb.checked)
		$("#send_email_nog_"+mac).show();
	else
		$("#send_email_nog_" + mac).hide();

	tmgrs_changed[mac] = tmgrs[mac];
	return true;
}
function editNotifyOfflinePush_mgr(mac, cb) {
	tmgrs[mac].notifyOfflinePush = cb.checked;
	tmgrs_changed[mac] = tmgrs[mac];
	return true;
}
function editallowmore_mgr(mac, cb) {
	tmgrs[mac].allowMore = cb.checked;
	tmgrs_changed[mac] = tmgrs[mac];
	return true;
}
$("#new_mac").blur(function (event) { event.target.value = $(event.target).val().toUpperCase(); });
$("#new_mac").blur({ regex: "^\\S{12}$", message: "Serial number is 12 character long.", remote: "ethAccount.asmx/GetTagManagerName", remote_retval: "#new_tgmr_name" }, validate);
$("#btnAddNewManager").click(function (event) {
	event.preventDefault();
	$.mobile.changePage($("#addTagManagerPage"), { transition: device_transition, role: "dialog" });

	$("#new_tgmr_allowmore").attr("checked", true).checkboxradio("refresh");
	$("#new_tgmr_name").val("");
	$("#new_mac").val("");
	$("#new_tgmr_groupwith").children().remove();
	$('<option />').val("none").text("Do not add as clone").appendTo('#new_tgmr_groupwith')

	for (var mac in tmgrs) {
		if (!tmgrs[mac].linkedToMac)
			$('<option/>').val(mac).text(tmgrs[mac].name).appendTo('#new_tgmr_groupwith')
	}
	$('#new_tgmr_groupwith').val("none").selectmenu("refresh");

	$("#addtagmanagerform").unbind("submit").submit(function (event) {
		event.preventDefault();
		$("#addtagmanagerform input").trigger('blur');
		if ($("label.error").length == 0) {
			var btn = $("#btnSubmit_addtagmanager");
			var oldhtml = show_finding(btn, "Adding...");
			var mac = $("#new_mac").val();
			var name = $("#new_tgmr_name").val();
			var allowmore = $("#new_tgmr_allowmore").is(":checked");
			var linkTo = $("#new_tgmr_groupwith").val();
			$.ajax({
				url: WSROOT + "ethAccount.asmx/AddTagManager",
				data: "{mac:'" + mac + "', name:'" + name + "', allowMore:'" + allowmore + "', makeSelected:true, linkToMac:'" + linkTo + "'}",
				success: function (retval, textStatus) {
					needRefreshTagManagers = true;			// forces update of the tag manager drop down box. 

					//$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					
					refreshNewMac();		// forces update of the tag list. 

					$.ajax({
						complete: function () { restore_finding(btn, oldhtml); },
						url: WSROOT + "ethClient.asmx/LoadAccountConfig",
						data: "{}",
						success: function (retval, textStatus) {
							if (retval.d != null) accountConfig = retval.d;
							processTagManagerList(); history.back();
						},
						error: function (xhr, textStatus, exception) {
							history.back();
							popup_error(xhr, btn, null, exception.message);
						}
					});

					if (linkTo != 'none') {
						$("#pingAllTagBtn").trigger('click');
					}
				},
				complete: function () { restore_finding(btn, oldhtml); },
				error: function (xhr, textStatus, exception) {
					restore_finding(btn, oldhtml);
					popup_error(xhr, null, null, exception.message);
				}
			});
		}
	});
});
function doEditLimitedUser(userid) {
	var granted = [];
	var setLimited = $("#is-limited-user").is(":checked");
	//if (setLimited) {
		$('#edit-grant-tag-choices').find('input:checked').each(function () {
			granted.push({ uuid: $(this).val(), visible: true, allowRename: false, allowLightOn: false });
		});
	//}

	$.ajax({
		complete: function () { },
		url: WSROOT + "ethClient.asmx/ApplyUserPermissions",
		data: JSON.stringify({ userId: userid, granted: granted, setLimited: setLimited }),
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message);
		},
		success: function () {
			$("#edit-user-dialog").simpledialog('close');
			user_cache[userid].isLimited = setLimited;
			var newName = user_cache[userid].name + (setLimited ? " (Limited)" : "");
			$(".edituser-" + userid).data('toptext', newName).parent().find(".ui-btn-text").text(newName);
		}
	});
}
function limitedCBChanged(btn) {
	if ($(btn).is(':checked')) {
		$('#edit-grant-tag-choices input').checkboxradio('enable').checkboxradio('refresh');
	} else {
		$('#edit-grant-tag-choices input').attr('checked', true).checkboxradio('disable').checkboxradio('refresh');
	}
}
function limitedCBChanged2(btn) {
	if ($(btn).is(':checked')) {
		$('#add-grant-tag-choices').show();
	} else {
		$('#add-grant-tag-choices').hide();
	}
}

function editUser(userid, mac, btn) {
	var isLimited = user_cache[userid].isLimited;
	if (btn.val() == 1) {
		//var oldhtml = show_finding(btn, "Loading...");
		$.ajax({
			url: WSROOT + "ethClient.asmx/QueryLimitedUserPermissionsForTagManager",
			data: JSON.stringify({ userId: userid, mac:  mac}), 
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn, null, exception.message);
			},
			complete: function () { },
			success: function (retval, textStatus) {
				var perms = retval.d;
				var html = ("<div style='padding: 15px'><fieldset data-role='controlgroup'><input type='checkbox' onchange='limitedCBChanged(this)' name='is-limited-user' id='is-limited-user' {0} />").format(isLimited ? "checked" : "");
				html += "<label for='is-limited-user'>Limited User</label></fieldset><b>This user can access:</b><fieldset data-role='controlgroup' id='edit-grant-tag-choices'>";
				perms.forEach(function (p) {
					html += "<input type='checkbox' name='grant-tag' id='grant-tag-{0}' {2} {3} value='{0}' /><label for='grant-tag-{0}'>{1}</label>".format(p.uuid, p.name, p.visible | !isLimited ? "checked" : "", isLimited ? "" : "disabled");
				});
				html += "</fieldset><a onclick='doEditLimitedUser(\"" + userid +
					"\")' data-role='button' data-theme='b' href='#' >Apply</a></div>";

				var holder = $("#edit-user-dialog");
				if (holder.data('simpledialog')) {
					holder.data('simpledialog').options.fullHTML = html;
					holder.simpledialog('refresh').simpledialog('open');
				} else {
					holder.simpledialog({
						'mode': 'blank',
						'prompt': false,
						'useDialog': false,
						'useDialogForceFalse': true, 
						'forceInput': false,
						'useModal': true,
						pickPageTheme: 'c',
						'fullHTML': html
					});
				}
			}
		});
	}
	else{		// delete
		confirmAsync("Do you really want to delete " + user_cache[userid].name + " from tag manager " + mac, function (ret) {
			if (ret) {
				var oldhtml = show_finding(btn, "Deleting...");
				$.ajax({
					complete: function () { restore_finding(btn, oldhtml); },
					url: WSROOT + "ethClient.asmx/RemoveUserFromTagManager",
					data: JSON.stringify({ userId: userid, mac: mac }),
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn, null, exception.message);
					},
					complete: function () { restore_finding(btn, oldhtml); },
					success: function (retval, textStatus) {
						btn.parent().remove();
						//$(".edituser-" + userid).parent().remove();
					}
				});
			}
		} );
	}
}
function doAddLimitedUser(mac) {
	var granted = null;
	if ($("#is-limited-user2").is(":checked")) {
		granted = [];
		$('#add-grant-tag-choices').find('input:checked').each(function () {
			granted.push({ uuid: $(this).val(), visible: true, allowRename: false, allowLightOn: false });
		});
	}
	var username = $("#limited-user-email").val();
	$.ajax({
		url: WSROOT + "ethClient.asmx/CreateLimitedUser2",
		data: JSON.stringify({ email: username, password: $("#limited-user-pwd").val(), granted: granted, MAC: mac }),
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message);
		},
		success: function (retval, textStatus) {
			$("#add-user-dialog").simpledialog('close');
			var userid = retval.d;
			user_cache[userid] = { name: username, id: userid, isLimited: granted !=null };
			$(('<select data-inine="1"  data-icon="gear" class="edituser-{0}" data-toptext="{1}{3}" onchange="editUser(\'{0}\',\'{2}\', $(this)); return false;" data-native-menu="false"><option value="1">Edit Permissions...</option><option value="2">Delete</option></select>')
				.format(userid, username, mac, granted != null ?" (Limited)":"")).insertBefore($("#adduser-" + mac).parent());
			$("#adduser-" + mac).parent().parent().trigger("create");
		}
	});
}
function addUser(mac, btn) {
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/GetEmptyLimitedUserPermissions",
		data: "{MAC:'" + mac + "'}",
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		},
		complete: function () { restore_finding(btn, oldhtml); },
		success: function (retval, textStatus) {
			var perms = retval.d;
			var html = "<div style='padding: 20px; width: 500px'><fieldset  data-role='controlgroup'  ><label for='limited-user-email'>Email: </label><input type='text' id='limited-user-email'></input></fieldset><fieldset  data-role='controlgroup' ><label for='limited-user-pwd'>Password: </label><input type='text' id='limited-user-pwd'></input></fieldset><fieldset data-role='controlgroup'><input type='checkbox' onchange='limitedCBChanged2(this)' name='is-limited-user2' id='is-limited-user2'  /><label for='is-limited-user2'>Limited User</label></fieldset><fieldset data-role='controlgroup' id='add-grant-tag-choices' style='display:none'><b>This user can access:</b>";
			perms.forEach(function (p) {
				html += "<input type='checkbox' name='grant-tag' id='grant-tag-{0}' value='{0}' /><label for='grant-tag-{0}'>{1}</label>".format(p.uuid, p.name);
			});
			html += ("</fieldset><a onclick='doAddLimitedUser(\"{0}\")' data-role='button' data-theme='b' href='#' >Create User Account</a></div>").format(mac);

			var holder = $("#add-user-dialog");
			if (holder.data('simpledialog')) {
				holder.data('simpledialog').options.fullHTML = html;
				holder.simpledialog('refresh').simpledialog('open');
			} else {
				holder.simpledialog({
					'mode': 'blank',
					'prompt': false,
					'useDialog': false,
					'useDialogForceFalse': true, 
					'forceInput': false,
					'useModal': true,
					pickPageTheme: 'c',
					'fullHTML': html
				});
			}

			/*$("#limited-user-email").blur({
				regex: "^[^\\W][a-zA-Z0-9\\_\\-\\.]+([a-zA-Z0-9\\_\\-\\.]+)*\\@[-a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)*\\.[a-zA-Z]{2,4}$",
				message: "Valid email address required for password recovery."
			}, validate);
			$("#limited-user-pwd").blur({ regex: "^\\S{3,}$", message: "password must be at least 3 characters" }, validate);*/

		}
	});
}
function fileTimeToDate(fileTime) {
	return new Date(fileTime / 10000 - 11644473600000);
}

function dateToFileTime(date) {
	return dateToFileTime2(date.getTime());
}
function dateToFileTime2(date2) {
	return (date2 + 11644473600000) * 10000;
}

function revoke_token(client_id) {
	
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethAccount.asmx/RevokeOauth2Token",
		data: JSON.stringify({ client_id: client_id }),
		success: function (retval, textStatus) {
			$("#otoken-" + client_id).remove();
			if ($("#oauth2_token_list").text().length == 0)
				$("#oauth2tokens").hide();
		}
	});
}
var user_cache = {};
var accountConfig = { loginEmail: null, loginPwd: null, twitterID: null, twitterPwd: null, allowMore: true, managers: [] };
function processTagManagerList() {
	tmgrs_changed = {}; tmgrs = {};
	if (accountConfig.managers == null) return;  
	for (var i = 0; i < accountConfig.managers.length; i++) {
		var mgr = accountConfig.managers[i];
		tmgrs[mgr.mac] = mgr;
	}

	var html = ""; var hasDBID1 = false, hasDBID2 = false;
	for (var mac in tmgrs) {
		var mgr = tmgrs[mac];
		if (mgr.dbid == 1) hasDBID1 = true;
		else if (mgr.dbid == 2) hasDBID2 = true;

		html += ('<div id="tm-{3}" data-role="collapsible" {0}><h3 id=tmtitle-{3}><span id=tmname-{3}>{1}</span>, {2}</h3>')
					.format(mgr.online ? "" : "class=oor", mgr.name, (mgr.online ? "online" : "offline") + (mgr.selected ? ", selected" : ""), mgr.mac);

		html += ('<select data-inline=1 data-corners=0 data-shadow=0 data-theme="d" data-toptext="Edit..." onchange="editname_mgr($(this), \'{0}\'); return false;" id="tmedit-{0}" data-native-menu="false" data-icon="gear"><option value="1">Change Name...</option>').format(mgr.mac);
		//if (!mgr.selected)
		html += '<option value="2">Remove</option>';
		if (mgr.linkedToMac)
			html += '<option value="3">Stop acting as clone</option>';
		html += '</select>';

		//html += ('<button data-inline=1 id="tmcn-btn-{0}" data-corners=0 data-shadow=0 data-theme="c" onclick="editname_mgr(\'{0}\'); return false;"  data-icon="gear">Edit...</button>').format(mgr.mac);

		if (mgr.linkedToMac) {
			html += "Acting as clone of <b>";
			if (tmgrs[mgr.linkedToMac])
				html += tmgrs[mgr.linkedToMac].name;
			else
				html += ("#" + mgr.linkedToMac);
			html += "</b>, "
		}
		var drkbps = Math.round((10e3 / 29.0 / (mgr.wirelessConfig.dataRate + 1.0)) * 10) / 10;
		var freq = Math.round((430 + 0.0025 * mgr.wirelessConfig.Freq) * 100) / 100;
		html += ('Serial#: <b>{3}</b>, Revision:<b>{4}</b>, Hosted by: <b>{5}</b>, Radio ID: <b>{0}</b>, Data Rate: <b>{1}kbps</b>, Frequency: <b>{2}MHz</b><div>').format(mgr.radioId, drkbps, freq, mgr.mac, mgr.rev, mgr.dbid == 2 ? "my.wirelesstag.net" : "mytaglist.com");
		//html += '<fieldset data-role="controlgroup" data-type="horizontal">';

		mgr.users.forEach(function (user) {
			user_cache[user.id] = user;
			html += ('<select data-inine="1"  data-icon="gear" class="edituser-{0}" data-toptext="{1} {2}" onchange="editUser(\'{0}\', \'{3}\',$(this)); return false;" data-native-menu="false"><option value="1">Edit Permissions...</option><option value="2">Delete</option></select>')
					.format(user.id, user.name, user.isLimited ? "(Limited)" : "", mgr.mac);
		});
		html += ('<button data-inline="1" id="adduser-{0}" onclick="addUser(\'{0}\', $(this)); return false;" data-theme="a" data-icon="plus" >Add User</button>').format(mac);
		html += ('<label for="tz-' + mgr.mac + '" class="select"> Time zone:  </label> <select onchange="specify_tzo(this,\''+mgr.mac+'\');" title="Configure time zone to use to display data gathered by this tag manager" data-inline=1 id="tz-' + mgr.mac + '">');
		html += '<option value="-12">(GMT -12:00) Eniwetok, Kwajalein</option><option value="-11">(GMT -11:00) Midway Island, Samoa</option><option value="-10">(GMT -10:00) Hawaii</option><option value="-9">(GMT -9:00) Alaska</option><option value="-8">(GMT -8:00) Pacific Time (US & Canada)</option><option value="-7">(GMT -7:00) Mountain Time (US & Canada)</option><option value="-6">(GMT -6:00) Central Time (US & Canada), Mexico City</option><option value="-5">(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima</option><option value="-4">(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz</option><option value="-3.5">(GMT -3:30) Newfoundland</option><option value="-3">(GMT -3:00) Brazil, Buenos Aires, Georgetown</option><option value="-2">(GMT -2:00) Mid-Atlantic</option><option value="-1">(GMT -1:00) Azores, Cape Verde Islands</option><option value="0">(GMT) Western Europe Time, London, Lisbon, Casablanca</option><option value="1">(GMT +1:00) Brussels, Copenhagen, Madrid, Paris</option><option value="2">(GMT +2:00) Kaliningrad, South Africa</option><option value="3">(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg</option><option value="3.5">(GMT +3:30) Tehran</option><option value="4">(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi</option><option value="4.5">(GMT +4:30) Kabul</option><option value="5">(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent</option><option value="5.5">(GMT +5:30) Bombay, Calcutta, Madras, New Delhi</option><option value="5.75">(GMT +5:45) Kathmandu</option><option value="6">(GMT +6:00) Almaty, Dhaka, Colombo</option><option value="7">(GMT +7:00) Bangkok, Hanoi, Jakarta</option><option value="8">(GMT +8:00) Beijing, Perth, Singapore, Hong Kong</option><option value="9">(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk</option><option value="9.5">(GMT +9:30) Adelaide, Darwin</option><option value="10">(GMT +10:00) Eastern Australia, Guam, Vladivostok</option><option value="11">(GMT +11:00) Magadan, Solomon Islands, New Caledonia</option><option value = "12"> (GMT + 12: 00) Auckland, Wellington, Fiji, Kamchatka"</option></select>'; 
		html += '</div><fieldset data-role="controlgroup" style="margin: .5em 1em 1em;">';
		html += ('<input type="checkbox" id="allowmore-{0}" {1} class="custom" onchange="editallowmore_mgr(\'{0}\', this);"/><label for="allowmore-{0}">Allow creating more accounts to access this Tag Manager (with knowledge of its serial number)</label>').format(mgr.mac, mgr.allowMore ? "checked" : "");
		html += ('<input type="checkbox" id="notifyOffline-{0}" {1} class="custom" onchange="editNotifyOffline_mgr(\'{0}\', this);"/><label for="notifyOffline-{0}">Send emails when online/offline status changes</label>').format(mgr.mac, mgr.notifyOffline ? "checked" : "");
		html += ('<div data-role="fieldcontain" id="send_email_nog_{0}" style="margin-left: 20px; {2}"><label for="send_email_no_{0}">Email addresses (separate by ;):</label><input onchange="editNotifyOfflineEmail_mgr(\'{0}\', this);" type="text" name="send_email_no_{0}" id="send_email_no_{0}" value="{1}" /></div>')
			.format(mgr.mac, mgr.notifyOfflineEmail || loginEmailAddress, mgr.notifyOffline ? "" : "display: none;");
		html += ('<input type="checkbox" id="notifyOfflinePush-{0}" {1} class="custom" onchange="editNotifyOfflinePush_mgr(\'{0}\', this);"/><label for="notifyOfflinePush-{0}">Send push notifications when online/offline status changes</label>').format(mgr.mac, mgr.notifyOfflinePush ? "checked" : "");
		html += '</fieldset></div>';
	}
	/*if (hasDBID1 && hasDBID2) {
		$("#mixed_dbid_notice").show();
		$("#mixed_dbid_notice_list").html("");
		for (var mac in tmgrs) {
			var mgr = tmgrs[mac];
			if (mgr.dbid == 1) $("<li><a target='_blank' data-ajax=0 href='https://my.wirelesstag.net/moveTagManagerDB.aspx?MAC={0}'>Migrate tag manager '{1}'</a></li>".format(mgr.mac, mgr.name)).appendTo("#mixed_dbid_notice_list");
			//if (mgr.dbid == 2) $("<li><a target='_blank' data-ajax=0 href='https://mytaglist.com/moveTagManagerDB.aspx?MAC={0}'>Migrate tag manager '{1}'</a></li>".format(mgr.mac, mgr.name)).appendTo("#mixed_dbid_notice_list");
		}
	} else {*/
		$("#mixed_dbid_notice").hide();
	//}
	$("#tagmanagerlist").html(html).trigger('create');
	for (var mac in tmgrs) {
		$("#tz-" + mac).val(tmgrs[mac].tzo / (-60)).selectmenu("refresh");
	}
	$("#tagmanagerlist").resetRoundedEdges();
}
function specify_tzo(s, mac) {
	$.ajax({
		error: function (xhr, textStatus, exception) { popup_error(xhr, $(s), null, exception.message); },
		url: WSROOT + "ethClient.asmx/SpecifyTimeZone",
		data: JSON.stringify({ "mac": mac, "tzo": $(s).val()*(-60)})
	});
}
$("#connect_suggest").change(function () {
	var btn = $(this);
	var suggestion = btn.val();
	if (suggestion == tmSetting.connectSuggest) return;
	$.ajax({
		error: function (xhr, textStatus, exception) { popup_error(xhr, btn, null, exception.message); },
		url: WSROOT + "ethClient.asmx/SuggestIFTTTConnection",
		data: JSON.stringify({ "suggestion": suggestion }),
		success: function () {
			if (suggestion.length>0)
				popup("Thank you for suggesting " + suggestion);
			else
				popup("Thank you for updating your suggestion");
		}
	});

});

function manageConn(btn, conn_id) {
	if (btn.val() == "1") {
		window.open("https://ifttt.com/connections/" + conn_id + "/edit", "_blank");
	}
	else if (btn.val() == "2") {
		var oldhtml = show_finding(btn, "Synchronizing...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) { popup_error(xhr, null, null, exception.message); },
			url: WSROOT + "ethClient.asmx/UpdateIFTTTConnection",
			data: JSON.stringify({ "connection": conn_id }),
			success: function (retval, textStatus) {
				if (retval.d != null) {
					for (var i = 0; i < retval.d.length; i++) {
						updateTag(retval.d[i]);
					}
					popup("Updated " + retval.d.map(function (t) { return t.name; }).join(", "));
				} else {
					popup("IFTTT returned nothing about this Connection. If you have turned it off at IFTTT you can go back to Associate screen to re-enable it. ");
				}
			}
		});
	} else {
		window.location.href = 'https://ifttt.com/connect/' + conn_id + '?email=' + loginEmailAddress + '&redirect_uri=' + encodeURIComponent(window.location.origin + '/eth/index.html?update_account');
	}
}

function accountOptions(btn) {
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadAccountConfig",
		data: "{}",
		success: function (retval, textStatus) {
			if (retval.d != null) accountConfig = retval.d;

			$.mobile.changePage($("#accountOptionPage"), { transition: device_transition, role: "dialog" });

			//$("#allowmore").attr("checked", accountConfig.allowMore).checkboxradio("refresh");
			$("#loginEmail").val(accountConfig.loginEmail);
			$("#loginPwd").val(accountConfig.loginPwd);
			$("#loginEmail").blur({
				regex: VALID_EMAIL_REGEX,
				message: "Valid email address required for password recovery."
			}, validate);
			$("#loginPwd").blur({ regex: "^\\S{3,}$", message: "password must be at least 3 characters and must not contain space characters." }, validate);

			processTagManagerList();

			if (accountConfig.tokens.length > 0) {
				html = "";
				for (var i = 0; i < accountConfig.tokens.length; i++) {
					var token = accountConfig.tokens[i];
					html += ('<div id="otoken-{3}" class="otoken"><img src="{0}" height=60 /><h2>{1}</h2><p> Granted on {4}.  (<a href="mailto:{2}">Contact developer</a>)</p>' +
						'<button data-inline=1 data-theme="e" data-icon="delete" onclick="revoke_token(\'{3}\'); return false; ">Revoke Access</button></div>')
					.format(token.icon_url, token.client_name, token.contact_email, token.client_id, fileTimeToDate(token.created).toLocaleDateString());
				}
				$("#oauth2_token_list").html(html).trigger("create");
				$("#oauth2tokens").show();
			}
			else $("#oauth2tokens").hide();

			$("#accountOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				$("#accountOptionForm input:visible").trigger('blur');
				if ($("label.error").length == 0) {
					var btn = $("#btnOptionSubmit_account");
					var oldhtml = show_finding(btn, "Saving...");
					var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
					var oldhtml2 = show_finding(btn2, "Saving...");

					//accountConfig.allowMore = $("#allowmore").is(":checked");
					accountConfig.loginEmail = $("#loginEmail").val();
					accountConfig.loginPwd = $("#loginPwd").val();
					accountConfig.managers = [];
					$.each(tmgrs_changed, function (k, v) { accountConfig.managers.push(v); });
					$.ajax({
						url: WSROOT + "ethClient.asmx/SaveAccountConfig",
						data: JSON.stringify({ "config": accountConfig }),
						complete: function () { restore_finding(btn, oldhtml); restore_finding(btn2, oldhtml2); },
						success: function (retval, textStatus) {
							needRefreshTagManagers = true;
							$.mobile.changePage("#indexPage", { transition: device_transition }, true);
						},
						error: function (xhr, textStatus, exception) {
							if (xhr.responseText.toLowerCase().indexOf("unauthorized") != -1 || exception.toLowerCase().indexOf("unauthorized") != -1 || xhr.responseText.toLowerCase().indexOf("authentication failed") != -1)
								location.replace(WSROOT+"eth/signin.html");
							else
								popup_error(xhr, null, null, exception.message);
						}
					});
				}
			});

			refreshTagManagerDropDown(accountConfig.managers);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
/*function readTagTypeInfo(btn, id) {
	var oldhtml = show_finding(btn, "Finding...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/ReadTagTypeInfo",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			var newTagInfo = retval.d;
			popup(newTagInfo.description + " (rev." + newTagInfo.version2.toString(16).toUpperCase() + ")", btn,
				"Battery: <b>" + (Math.round(100.0 * retval.d.batteryVolt) / 100) + " volt</b>, Signal strength: <b>" + newTagInfo.signaldBm + "dBm</b>, Frequency offset: <b>"+newTagInfo.freqOffset+"Hz</b>");
			if (newTagInfo.tagType1 != taglist_cache[id].tagType) {
				alert("Read tag type (" + newTagInfo.tagType1 + ") differs from the type (" + taglist_cache[id].tagType + ") the tag is associated as. If the tag is not operating as expected, please unassociate the tag and associate it again");
			}
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr);
		}
	});
}*/
var eventURLConfig;
function eventURLOptions(btn, tag, focus_id) {
	var oldhtml = show_finding(btn, "Loading...");
	$.mobile.changePage($("#eventURLOptionPage"), { transition: device_transition, role: "dialog" });
	$("#eventURLTitle").text("Custom URL Calling on Event for " + tag.name);

	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadEventURLConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) eventURLConfig = retval.d;

			for (var x in eventURLConfig) {
				if (eventURLConfig[x] != null) {
					$('#eu_' + x + '_url').val(eventURLConfig[x].url);
					var enbtn = $('#eu_' + x + '_en');
					enbtn.change(function () { if (this.checked) { $(this).parent().next().show(); } else { $(this).parent().next().hide(); } });
					if (eventURLConfig[x].disabled) {
						enbtn.attr('checked', false).checkboxradio("refresh");
						$('#eu_' + x + '_group').hide();
					} else {
						enbtn.attr('checked', true).checkboxradio("refresh");
						$('#eu_' + x + '_group').show();
					}
					$("#eu_" + x + "_nat").attr('checked', eventURLConfig[x].nat);
				}
			}

			if (focus_id) {
				var enbtn = $('#eu_' + focus_id + '_en');
				enbtn.attr('checked', true).checkboxradio("refresh");
				var group = $('#eu_' + focus_id + '_group');
				group.show();
				scrollToView(group);
			}

			$("#eventURLViewLog").unbind("click").click(function () {

				var log_url = WSROOT + "webcams/" + tag.uuid + ".txt";
				if (isMobile()) location.href = (log_url);
				else window.open(log_url, "_blank");

			});
			$("#eventURLOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				var btn = $("#btnOptionSubmit_eu");
				var oldhtml = show_finding(btn, "Saving...");
				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				for (var x in eventURLConfig) {
					if (eventURLConfig[x] != null) {
						eventURLConfig[x].url = $('#eu_' + x + '_url').val();
						eventURLConfig[x].disabled = !($('#eu_' + x + '_en').is(":checked"));
						eventURLConfig[x].nat = $('#eu_' + x + '_nat').is(":checked");
					}
				}
				var applyAll = $("#applyAll_eu").is(":checked");

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveEventURLConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": eventURLConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						history.back();
						//$.mobile.changePage("#indexPage", { transition: device_transition }, true);
						//location.hash = "#indexPage";
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr);
		}
	});
}

function v2flagOptions(tag) {

	$.mobile.changePage($("#v2flagPage"), { transition: device_transition, role: "dialog" });
	$("#v2flagPageTitle").text("Special Options for " + tag.name);

	if (tag.version1 >= 2) {
		$("#lockFlash1").attr('checked', (tag.v2flag&1)!=0).checkboxradio("refresh");
		$("#lockFlashChoice1").show();
	} else {
		$("#lockFlashChoice1").hide();
	}
	if (tag.version1 >= 4 || (tag.rev > 0x90 && tag.tagType!=26) || tag.rev>0xB0 || (tag.tagType == 32 && tag.rev >= 0x21)) {
		$("#cachedPostback1").attr('checked', (tag.v2flag&8)!=0).checkboxradio("refresh");
		$("#cachedPostbackChoice1").show();
		$("#cachedPostback1").change(function () {
			if (this.checked) {
				if (localStorage["warned_cached_postback"] != "1") {
					alert("Please make sure you understand what this option does. With this option, if you set update every 10 minutes, temperature is recorded every 10 minutes, but is transmitted every 130 minutes including 13 data points in one transmission. You will NOT see very recent temperature on screen unless you manually update, but you will get longer battery life because it is more efficient to send more data in one transmission. In recorded temperature/RH/lux graphs, data points will be spaced every 10 minutes.");
					localStorage["warned_cached_postback"] = "1";
				}
			}
		});
	} else {
		$("#cachedPostbackChoice1").hide();
	}
	if (tag.rev >= 15) {
		$("#noLED1").attr('checked', (tag.v2flag & 2)!=0).checkboxradio("refresh");
		$("#noLEDChoice1").show();
	} else {
		$("#noLEDChoice1").hide();
	}
	$("#v2flagform").unbind("submit").submit(function (event) {
		event.preventDefault();
		var btn = $("#submitBtn_v2flag");
		var oldhtml = show_finding(btn, "Updating...");
		tag.v2flag = ($("#noLED1").is(":checked") ? 2 : 0) + ($("#lockFlash1").is(":checked") ? 1 : 0) + ($("#cachedPostback1").is(":checked") ? 8 : 0);
		$.ajax({
			url: WSROOT + "ethClient.asmx/SaveTagInfo",
			data: JSON.stringify({ "tag": tag }),
			headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
			complete: function () { restore_finding(btn, oldhtml); },
			success: function (retval, textStatus) {
				$.mobile.changePage("#indexPage", { transition: device_transition }, true);
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, null, null, exception.message);
			}
		});
	});
}

var messageConfig;
function messageOptions(btn, tag ){

	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadMessageTemplateConfig",
		data: "{id: '" + tag.slaveId + "'}",
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval, textStatus) {
			if (retval.d != null) messageConfig = retval.d;

			$.mobile.changePage($("#messageOptionPage"), { transition: device_transition, role: "dialog" });
			$("#msgTempTitle").text("Customize Notification Messages for " + tag.name);

			for (var x in messageConfig) {
				if (messageConfig[x].title != null) {
					$('#msg_' + x + '_t').val(messageConfig[x].title);
					$('#msg_' + x + '_d').val(messageConfig[x].detail);
				}
			}
			$("#messageOptionForm").unbind("submit").submit(function (event) {
				event.preventDefault();
				var btn = $("#btnOptionSubmit_msg");
				var oldhtml = show_finding(btn, "Saving...");
				var btn2 = $(this).parent().parent().find(".optionSubmit>.ui-btn-inner");
				var oldhtml2 = show_finding(btn2, "Saving...");

				for (var x in messageConfig) {
					if (messageConfig[x].title != null) {
						messageConfig[x].title = $('#msg_' + x + '_t').val();
						messageConfig[x].detail = $('#msg_' + x + '_d').val();
					}
				}
				var applyAll = $("#applyAll_message").is(":checked");

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveMessageTemplateConfig",
					data: JSON.stringify({ "id": tag.slaveId, "config": messageConfig, "applyAll": applyAll }),
					headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
					complete: function () { restore_finding(btn, oldhtml); restore_finding(btn2, oldhtml2); },
					success: function (retval, textStatus) {
						history.back();
						//$.mobile.changePage("#indexPage", { transition: device_transition }, true);
						//location.hash = "#indexPage";
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null, null, exception.message);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn, null, exception.message);
		}
	});
}
function undelete(btn) {
	$.ajax({
		url: WSROOT + "ethClient.asmx/UndeleteTag2",
		data: JSON.stringify({ uuid: btn.val() }),
		success: function (retval) {
			if (retval.d)
				updateTag(retval.d);
		}
	});
}
function doViewMultiStats(type) {
	var selected = [];
	for (var id in taglist_cache) savePref(taglist_cache[id].uuid + "selected_for_" + type, "0");
	$('#multi-stat-choices').find('input:checked').each(function () {
		if (allTagManager) {
			selected.push(taglist_cache[$(this).val()].uuid);
		} else {
			selected.push($(this).val());
		}
		savePref(taglist_cache[$(this).val()].uuid + "selected_for_" + type, "1");
	});
	if (selected.length > 0) {
		if (window.NC) {
			if (allTagManager) {
				window.NC.multiGraphUuids("\"" + selected.join("\",\"") + "\"", (type == "tvoc" && !window.NC.tempGraphZmod)?"light":type);
			} else {
				window.NC.multiGraph(selected.join(','), (type == "tvoc" && !window.NC.tempGraphZmod) ? "light" : type);
			}
		}
		else {
			var p = { slaveids: selected.join(':'), type: type };
			stat_url = WSROOT+"eth/tempStatsMulti.html?" + jQuery.param(p);

			if (isMobile()) location.href = (stat_url);
			else pcOpenStats(stat_url);
		}
	}
}

function checkAbandoned() {
	if(allTagManager) return;
	if(tmgrs_cache.length==0) return; // not yet loaded

	if(tmgrs_cache[tmgrs_index[selectedTagManager]].linkedToMac) return;
	for(var i in tmgrs_cache) {
		if(selectedTagManager==tmgrs_cache[i].linkedToMac) return;
	}
	var abandoned_tag=[];
	for(var id in taglist_cache) {
		var tag=taglist_cache[id];
		if(tag.slaveId>=0 && tag.OutOfRange) {
			var lastComm=new Date((tag.lastComm/10000)-11644473600000);
			var now=new Date();
			var diff=now.getTime()-lastComm.getTime()+serverTime2LocalTime;
			var daysDifference=Math.floor(diff/1000/60/60/24);
			if(daysDifference>90) abandoned_tag.push(tag);
		}
	}
	if(abandoned_tag.length>0) {
		$("#trendBtn").simpledialog({
			mode: 'bool',
			'useDialog': false,
			'useDialogForceFalse': true,
			prompt: "<div style='margin:20px'>There appears to be abandoned tags (<em>"+abandoned_tag.map(x => "'"+x.name+"'").join(",")+"</em> ) under your account. Keeping them paired can make connection to working tags unreliable. Do you want to unpair them? You can undo within 90 days (from settings > undelete). </div>",
			useModal: true,forceInput: false,cleanOnClose: true,
			'buttons': {
				'Unpair': {
					click: function() {
						abandoned_tag.forEach(function(tag) {							
							$.ajax({
								url: WSROOT+"ethClient.asmx/DeleteTag",
								data: "{id: "+tag.slaveId+"}",
								success: function(retval,textStatus) {
									$("#collapsible-"+tag.wid).remove();
									$("#taglist").resetRoundedEdges();
								}
							});
						});
					},icon: "check",theme: "b"
				},
				'Remind me later': {
					click: function() {
						localStorage["mytaglist.stats.abandoned"]="0";
					},icon: "back",theme: "a"
				},
				'No, don\'t ask again': {
					click: function() {
						localStorage["mytaglist.stats.abandoned"]="1";
					},theme: "c"
				}
			}
		});
	}
}

function pcOpenStats(stat_url) {
	window.open(stat_url, "_blank");
	if (WSROOT == "/") {
		window.setTimeout(function () {
			if (localStorage["mytaglist.stats.askforreview"] == "1" && localStorage["mytaglist.stats.askedforreview"] != "1") {

				$("#eventLogBtn").simpledialog({
					mode: 'bool',
					'useDialog': false,
					'useDialogForceFalse': true, 
					prompt: "<div style='margin:20px'>If you enjoy Wireless Tag, would you mind taking a moment to give it a 5 star rating? It will only take a minute. Thanks for your support!</div>",
					useModal: true, forceInput: true, cleanOnClose: true,
					'buttons': {
						'Rate Wireless Tag': {
							click: function () {
								localStorage["mytaglist.stats.askedforreview"] = "1";
								window.open("https://www.google.com/search?hl=en-US&gl=us&q=CAO+GADGETS+LLC,+4603,+50+Tesla,+Irvine,+CA+92618&ludocid=1632316189981625371#lrd=0x80dce7df4e54475f:0x16a726ed28f94c1b,3", "_blank");
							}, icon: "star", theme: "e"
						},
						'Remind me later': {
							click: function () {
								localStorage["mytaglist.stats.askforreview"] = "0";
							}, icon: "back", theme: "a"
						},
						'No, thanks': {
							click: function () {
								localStorage["mytaglist.stats.askedforreview"] = "1";
							}, icon: "delete", theme: "c"
						}
					}
				});
			}
		}, 2500);
	}
}
function multiStats(btn) {
	var html = "<div style='padding: 15px'><b>Check tags to view:</b><fieldset data-role='controlgroup' id='multi-stat-choices'>";
	for (var i = 0; i < taglist_sorted.length; i++) {
		var tag = taglist_sorted[i];
		tag.hasChipTemp = tag.isTcProbe && ((tag.rev & 0xF) == 0xF) && !tag.shorted;
		if (btn.val() == "cap" && tag.cap <= 0 && !tag.isFlat) continue;
		if (btn.val() == "dp" && (tag.cap <= 0 || tag.isMoistureTag || tag.isFlat || tag.isWMETag || tag.hasChipTemp)) continue;
		if (btn.val() == "motion" && !tag.hasEventLog) continue;
		if (btn.val() == "light" && !tag.hasALS) continue;
		if (btn.val() == "tvoc" && !tag.hasZmod) continue;
		html += "<input type='checkbox' name='view-tag' id='view-tag-{0}' {2} value='{0}'><label for='view-tag-{0}'>{1}</label>".format(tag.wid, tag.name,
			loadPref(tag.uuid+"selected_for_" + btn.val())=="1" ? "checked" : "");
	}
	html += "</fieldset><a onclick='doViewMultiStats(\"" + btn.val() + "\")' rel='close' data-role='button' data-theme='b' href='#' id='simpleclose'>View Statistics</a></div>";

	if (btn.data('simpledialog')) {
		btn.data('simpledialog').options.fullHTML = html;
		btn.simpledialog('refresh').simpledialog('open');
	} else {
		btn.simpledialog({
			'mode': 'blank',
			'prompt': false,
			'useDialog': false,
			'useDialogForceFalse': true, 
			'forceInput': false,
			'useModal': true,
			pickPageTheme: 'c',
			'fullHTML': html
		});
	}
}
function globalSettings(btn) {
	if (allTagManager) {
		if (btn.val() == "2" || btn.val() == "3" || btn.val() == "4") {
			popup("Please choose a specific tag manager from the menu on top of the page first", btn); return;
		}
	}

	switch (btn.val()) {
		case "1":
			accountOptions(btn);
			break;
		case "2":
			migrateConfig(btn); break;
		case "3":
			undeleteChoice(btn); break;
		case "4":
			rebootTm(btn); break;
		case "6":
			moveDataPage(btn); break;
		case "5":
			window.open('https://ifttt.com/wirelesstag', '_blank'); break;
	}
}
var oldConfig, newConfig;
var paramSets = {};

function recalc_wireless_perf_new() {
	var psd = { ID: 0, name: "", estRange: 0, xtalTol: 0, batteryLifeCoeff: 1, v1Compatible: false };
	psd = paramSets[$("#newparamset").val()];
	var resp = $("#newresp").val();
	recalc_wireless_perf(psd, resp, $("#newcrc32").is(":checked"), $("#newperformance"));
}
function recalc_wireless_perf(psd, resp, crc32, display) {
/*	var bat_mult = (crc32 ? 0.9 : 1)*2;
	display.html("Est. Range:  <b>{0}m (new) / {1}m (old)</b><br>Est. Battery Life:  <b>{2} months</b><br>{3}".format
		(psd.estRange, psd.estRangeV1, (psd.batteryLifeCoeff * resp * bat_mult).toFixed(1),
		psd.estRangeV1 > 0 ? "Compatible with all tags" : "For long range tag only"));   */
}
$("#newparamset").change(function () { recalc_wireless_perf_new(); });
$("#newresp").change(function () { recalc_wireless_perf_new(); });
$("#newcrc32").change(function () { recalc_wireless_perf_new(); });

function migrateConfig(btn) {
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadWirelessConfigs",
		success: function (retval) {
			$.mobile.changePage($("#migratePage"), { transition: device_transition, role: "dialog" });
			var choiceHtml;
			for (var i = 0; i < retval.d[2].length; i++) {
				var ps = retval.d[2][i];
				paramSets[ps.ID] = ps;
				choiceHtml += ('<option value="' + ps.ID + '">' + ps.name + '</option>');
			}
			$("#oldparamset").html(choiceHtml).selectmenu();
			$("#newparamset").html(choiceHtml).selectmenu();

			oldConfig = retval.d[0];
			newConfig = retval.d[1];

			$("#oldfreq").val(oldConfig.Freq).selectmenu("refresh");
			$("#oldparamset").val(oldConfig.psid).selectmenu("refresh");
			$("#oldresp").val(oldConfig.activeInterval).selectmenu("refresh");

			var showFEC = retval.d[3];
			if (showFEC) {
				$(".crc16-fec-options").show();
				$("#oldcrc32").attr('checked', oldConfig.useCRC32).checkboxradio("refresh");
				$("#newcrc32").attr('checked', newConfig.useCRC32).checkboxradio("refresh");
			} else {
				$(".crc16-fec-options").hide();
			}

			if (paramSets[oldConfig.psid] != null)
				recalc_wireless_perf(paramSets[oldConfig.psid], oldConfig.activeInterval, oldConfig.CRC32, $("#oldperformance"));

			$("#newfreq").val(newConfig.Freq).selectmenu("refresh");
			$("#newparamset").val(newConfig.psid).selectmenu("refresh");
			if (oldConfig.psid == 76 || newConfig.psid == 76) $("#newparamset").selectmenu("disable");
			$("#newresp").val(newConfig.activeInterval).selectmenu("refresh").trigger("change");
		}
	});
}
$("#migratePage").live("pagebeforecreate", function () {
	for (var i = 0; i < 105; i++) {
		var freqv = (13 + i) * 32 + 1;
		$('<option/>').val(freqv).text(Math.round((430 + 0.0025 * freqv) * 100) / 100 + "MHz").appendTo('#oldfreq').clone().appendTo('#newfreq');
	}
});
$("#migrateform").submit(function (event) {
	event.preventDefault();

	var btn = $("#submitBtn");
	var oldhtml = show_finding(btn, "Migrating...");
	newConfig.Freq = $("#newfreq").val();
	newConfig.activeInterval = $("#newresp").val();
	newConfig.psid = $("#newparamset").val();
	newConfig.dataRate = paramSets[newConfig.psid].DR;
	newConfig.useFEC = false; //$("#newfec").is(":checked");
	newConfig.useCRC16 = (paramSets[newConfig.psid].estRangeV1 == 0);  //automatically enable crc16 for non-v1-compatible and vice versa. //$("#newcrc16").is(":checked");
	newConfig.useCRC32 = $("#newcrc32").is(":checked");

	$.ajax({
		url: WSROOT + "ethClient.asmx/MigrateWirelessConfig",
		data: JSON.stringify({ "newConfig": newConfig }),
		success: function (retval, textStatus) {
			$.mobile.changePage("#indexPage", { transition: device_transition }, true);
			restore_finding(btn, oldhtml);
			for (var i = 0; i < retval.d.length; i++) {
				updateTag(retval.d[i]);
			}
			var ai = $("#updateInterval");
			if (ai.val() < 2147483647) ai.trigger("change");
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message); restore_finding(btn, oldhtml);
		}
	});
});
var move_from_tag_uuid = null, move_to_tag_sid = null;
$("#moveDataBtn").click(function () {
	var btn = $(this);
	var oldhtml = show_finding(btn, "Moving...");
	var tag = taglist_cache[move_to_tag_sid];
	$.ajax({
		url: WSROOT + "ethClient.asmx/MoveLoggedData2",
		data: JSON.stringify({ from_uuid: move_from_tag_uuid, to_id: tag.slaveId, includeMotion: true, noValidation: $("#movedata_no_validation").is(":checked") }),
		headers: allTagManager ? { 'X-Set-Mac': tag.mac } : null,
		success: function (retval) {
			restore_finding(btn, oldhtml); btn.button("disable");
			popup("Successfully moved " + retval.d + " entries.", btn);
			$("#" + move_from_tag_uuid).parent().fadeOut(400, function () {
				$(this).remove();
				$("#move_from_choices").children().first().find(".ui-btn").eq(0).addClass("ui-corner-tl ui-corner-tr");
				$("#move_from_choices").children().last().find(".ui-btn").eq(0).addClass("ui-corner-bl ui-corner-br");
			});
			$("#sid_" + move_to_tag_sid).parent().fadeOut(400, function () {
				$(this).remove();
				$("#move_to_choices").children().first().find(".ui-btn").eq(0).addClass("ui-corner-tl ui-corner-tr");
				$("#move_to_choices").children().last().find(".ui-btn").eq(0).addClass("ui-corner-bl ui-corner-br");
			});
			move_from_tag_uuid = null; move_to_tag_sid = null;
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message); restore_finding(btn, oldhtml);
		}
	});
});

function moveDataPage(btn) {
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/GetDeletedTagList2",
		data: "{count_logdata: true}",
		success: function (retval) {
			$("#move_from_choices, #move_to_choices").html(""); move_from_tag_uuid = null; move_to_tag_sid = null;
			$.mobile.changePage($("#moveDataPage"), { transition: device_transition, role: "dialog" });

			var html = "";
			for (var i = 0; i < retval.d.length; i++)
				html += ('<input type="radio" name="from_tag" id="{0}" value="{0}" /><label for="{0}">{1}: {2}, {3} points</label>').format(retval.d[i].uuid, retval.d[i].name, UserFriendlyTimeSpanString(retval.d[i].deleted), UserFriendlyCountString(retval.d[i].count));		
			$("#move_from_choices").html(html).parent().trigger("create");
			html = "";
			for (var id in taglist_cache) 
				html += ('<input type="radio" name="to_tag" id="sid_{0}" value="{0}" /><label for="sid_{0}">{1}</label>').format(id, taglist_cache[id].name);
			$("#move_to_choices").html(html).parent().trigger("create");
			$("#moveDataBtn").button("disable");

			$('input:radio[name=from_tag]').change(function () {
				move_from_tag_uuid = $(this).val();
				if (move_from_tag_uuid != null && move_to_tag_sid != null) $("#moveDataBtn").button("enable");
			});
			$('input:radio[name=to_tag]').change(function () {
				move_to_tag_sid = $(this).val();
				if (move_from_tag_uuid != null && move_to_tag_sid != null) $("#moveDataBtn").button("enable");
			});

		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null, null, exception.message); 
		}
	});
}