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 WSROOT;
if (!window.NC) {
	if (window["localStorage"] != null) {
		if (!localStorage["mytaglist.iosapp.nowarning"]) {
			if (navigator.userAgent.match(/(iPhone|iPad)/) && window.location.search.length == 0) {
				if (confirm("Install the iPhone/iPad app?")) {
					window.location.href = "http://itunes.apple.com/us/app/wireless-tag-list/id508973799";
				} else {
					localStorage["mytaglist.iosapp.nowarning"] = true;
				}
			}
		}
	}
	if (!$.mobile.gradeA()) window.location.href = "/eth/ie_not_supported.html";
	WSROOT = "/";
} else {
	WSROOT = "https://www.mytaglist.com/";
}

var VALID_EMAIL_REGEX = "^[^\\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"] };
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 = isMobile() ? "none" : "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, id) {
	var menu = $('<select id="_reviveOptionFor" data-native-menu="false"><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 holder = $("#updateIntervalFor-" + id); holder.empty();
	menu.appendTo(holder).selectmenu();
	menu.val(taglist_cache[id].reviveEvery).selectmenu("refresh").selectmenu("open");
	holder.empty();
	menu.change(function () {
		var oldhtml = show_finding(btn, "Configuring...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
			url: WSROOT + "ethClient.asmx/SetReviveEvery",
			data: "{id: " + id + ", multiple:" + $(this).val() + "}",
			success: function (retval, textStatus) {
				updateTag(retval.d);
			}
		});
		return false;
	});

}

function setRssiMode(id, enable, btn) {
	var oldhtml = show_finding(btn, "Configuring...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
		url: WSROOT + "ethClient.asmx/SetLowPowerWOR",
		data: "{id: " + id + ", enable:" + enable+ "}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		}
	});
}

function rssiModeOptions(btn, id) {
	var menu = $('<select id="_rssiMode" data-native-menu="false"><option value="false" {0}>High Sensivity</option><option value="true" {1}>Long Battery Life</option></select>'.format(
		taglist_cache[id].rssiMode ? '' : 'selected', taglist_cache[id].rssiMode ? 'selected' : ''));
	var holder = $("#updateIntervalFor-" + id); holder.empty();
	menu.appendTo(holder).selectmenu().selectmenu("open");
	holder.empty();
	menu.change(function () {
		if ($(this).val()=="true") {
			if (window["localStorage"] != null) {
				if (localStorage["mytaglist.rssimode.nowarning"]) {
					setRssiMode(id, 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 Receive Mode will dramatically increase tag's battery life, but the drawback is: ";
						html += "the radio channel needs to be quiet (no command to other tags) for at least 10 seconds before sending command to the tag with this mode enabled. "; 
						html += "If immediately following a command to another tag, a command is sent to the tag with this mode enabled, there will be longer than usual delay or 'tag did not respond' error.";
						html += "<fieldset data-role='controlgroup'><input type='checkbox' id='rssi-mode-goahead'><label for='rssi-mode-goahead'>I understand this limitation</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',
							'prompt': false,
							'forceInput': false,
							'useModal': true,
							pickPageTheme: 'c',
							'fullHTML': html,
							onClosed: function () {
								if ($("#rssi-mode-goahead").is(":checked")) {
									setRssiMode(id, true, btn);
									if ($("#rssi-mode-dont-warn").is(":checked"))
										localStorage["mytaglist.rssimode.nowarning"] = true;
								}
							}
						});
					}
				}
			} else {
				setRssiMode(id, true, btn);
			}
		} else {
			setRssiMode(id, false, btn);
		}
		return false;
	});
}
function autoUpdateOptions(btn, id) {
	var menu = $('<select id="_updateIntervalFor" data-native-menu="false"></select>');
	menu.html($("#updateInterval").html());
	var holder = $("#updateIntervalFor-" + id); holder.empty();
	menu.appendTo(holder).selectmenu();
	menu.val(taglist_cache[id].postBackInterval).selectmenu("refresh").selectmenu("open");
	holder.empty();
	menu.change(function () {
		var oldhtml = show_finding(btn, "Configuring...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
			url: WSROOT + "ethClient.asmx/SetPostbackIntervalFor",
			data: "{id: " + id + ", sec:" + $(this).val() + "}",
			success: function (retval, textStatus) {
				updateTag(retval.d);
			}
		});
		return false;
	});
}
function rebootTm(btn) {
	$.ajax({
		url: WSROOT + "ethClient.asmx/RebootTagManager",
		error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
		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"><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;
	if (getNextUpdate_xhr) {
		getNextUpdate_xhr.abort();
		getNextUpdate_xhr = null;
	}
}
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="?{0}" style="font-size:16pt; float: right; margin-right: 30px" onclick="$(\'#tagmanager_menu\').val(\'{0}\').selectmenu(\'refresh\').trigger(\'change\'); return false;">View...</a>').format(mac);
		$(html + "</div>")
						.appendTo($.mobile.pageContainer)
						.click(function () { $(this).fadeOut(400, function () { $(this).remove(); }) });
	} else {
		$(html + "</div>")
						.appendTo($.mobile.pageContainer)
						.click(function () { $(this).fadeOut(400, function () { $(this).remove(); }) })
						.delay((title.length + detail.length) * 60 + 700).fadeOut(400, function () { $(this).remove(); });
	}
}
function MN_onMessage(payload) {

	if (payload.mac == null || payload.mac == $("#tagmanager_menu").val()) {

		popupMN(payload.alert, payload.detail, null);
		if (!getNextUpdate_xhr) {
			var id = payload.slaveid;
			$.ajax({
				url: WSROOT + "ethClient.asmx/GetTagForSlaveId",
				data: "{slaveid: " + id + "}",
				success: function (retval, textStatus) {
					retval.d.notificationJS = null;
					updateTag(retval.d);
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn);
				}
			});
		}
	} else {
		popupMN(payload.alert, payload.detail, payload.mac);
	}
	//$("#indexPage").trigger("pagehide"); $("#indexPage").trigger("pageshow");
	//navigator.notification.vibrate(1200);
	//navigator.notification.beep(1);
}
var loginEmailAddress;
function MN_onRegistered(event)			   // oldToken, newToken, type, phoneName
{
	promptAsync("Please pick a name for this device: ", event.phoneName, function (phoneName) {
		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);
				//var err = eval("(" + xhr.responseText + ")");
				//alert(err.Message + " " + err.StackTrace);
			}
		});
	});
}
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 popup(msg, btn) {
	$(".ui-error").remove();
	if (btn !=null && btn.length==0) btn = null;
	if (btn != null)
		if (btn.offset().top < 0) btn = btn.parent();
	$("<div class='ui-error ui-overlay-shadow ui-body-e ui-corner-all'><h1>" + msg + "</h1></div>")
						.css(btn != null ? { "top": btn.offset().top - 20 } : { "top": "40%", "position": "fixed" })
						.appendTo($.mobile.pageContainer)
						//.click(function () { $(this).fadeOut(400, function () { $(this).remove(); }) });
						.delay(700 + msg.length * 50).fadeOut(400, function () { $(this).remove(); });

}

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>" + 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) {
	try {
		btn.button('disable');
		btn.blur();
	} catch (e) {
		try {
			btn.selectmenu('disable');
		} catch (e) {
			btn.addClass("ui-disabled");
			btn.attr('disabled', true);
		}
	}
	var btn_text = btn.parent().find(".ui-btn-text");
	var oldhtml = btn_text.text();
	btn_text[0].innerHTML = finding_label || "Finding...";
	var btn_icon = btn.parent().find(".ui-icon");
	btn_icon.data("old_class", btn_icon[0].className);
	//btn_icon[0].className = "ui-icon-gear";
	btn_icon.addClass("ui-icon-gear spin");
	return oldhtml;
}
function restore_finding(btn, oldhtml) {
	try {
		btn.button('enable');
		btn.focus();
	} catch (e) {
		try {
			btn.selectmenu('enable');
		} catch (e) {
			btn.removeClass("ui-disabled");
			btn.attr('disabled', false);
		}
	}
	if(oldhtml)
		btn.parent().find(".ui-btn-text")[0].innerHTML = oldhtml;
	//btn.parent().find(".ui-icon").removeClass("ui-icon-gear spin");
	var btn_icon = btn.parent().find(".ui-icon");
	btn_icon[0].className = btn_icon.data("old_class");
}

$.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) {
	try {
		if (xhr.responseText.length > 0) {
			var err = eval("(" + xhr.responseText + ")");
			popup(err.Message, btn);
		}
		else if (xhr.statusText == "error") {
			popup("Network connection issue.", btn);
		}
		else {
			popup(xhr.statusText, btn);
		}
	} catch (e) {
		popup("Unknown Error: " + xhr, btn);
	}
}
function armDisarm(btn, id) {
	switch (btn.val()) {
		case "1":
			armit(btn, id); break;
		case "2":
			disarmit(btn, id); break;
	}
}
function armit(btn, id) {
	var oldhtml = show_finding(btn, "Arming...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/Arm",
		data: "{id: '" + id + "', door_mode_set_closed: true}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		},
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function disarmit(btn, id) {
	var oldhtml = show_finding(btn, "Disarming...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/Disarm",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		},
		complete: function () {
			restore_finding(btn, oldhtml);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function armDisarmAll(btn) {
	switch (btn.val()) {
		case "1":
			all_tag_action(btn, "ArmAll", "Arming..."); break;
		case "2":
			all_tag_action(btn, "DisarmAll", "Disarming..."); break;
	}
}
function all_tag_action(btn, action, finding_text) {
	var oldhtml = show_finding(btn, finding_text);

	$.ajax({
		url: WSROOT + "ethClient.asmx/" + action,
		data: "{autoRetry: " + autoRetry + "}",
		complete: function () {
			restore_finding(btn, oldhtml);
		},
		success: function (retval, textStatus) {

			$.each(taglist_cache, function (id, tag) { tag._updated = false; });

			for (var i = 0; i < retval.d.length; i++) {
				updateTag(retval.d[i]);
			}

			if (action == "PingAllTags") {
				$.each(taglist_cache, function (id, tag) {
					if (tag) {
						if (!tag._updated) {
							$("#collapsible-" + tag.slaveId).remove();
							$("#taglist").resetRoundedEdges();
							delete taglist_cache[id];
						}
					}
				});
			}
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null);
		}
	});
}

function UserFriendlyTimeSpanString(filetime) {
	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 dBmToBars(dBm) {
	if (dBm <= -105) return 0;
	else if (dBm < -97) return 1;
	else if (dBm < -87) return 2;
	else if (dBm < -77) return 3;
	else if (dBm < -67) 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);
		}
	});
}
*/
function resetit(btn, id) {
	var oldhtml = show_finding(btn);
	$.ajax({
		url: WSROOT + "ethClient.asmx/ResetTag",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		},
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function reqPostback(btn, id) {
	var oldhtml = show_finding(btn);
	$.ajax({
		url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		},
		complete: function () { restore_finding(btn, oldhtml); },
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
			//popupDebug(xhr, btn);
		}
	});
}
function togglelight(btn, id) {
	var btn_text = btn.parent().find(".ui-btn-text");
	var oldhtml = btn_text.html();
	if (oldhtml == "Light On") {
		lightOn(btn, id);
	} else {
		lightOff(btn, id);
	}
}

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

		var holder = btnIconSpan(btn); holder.empty();
		menu.appendTo(holder).selectmenu();
		menu.val(tag.beepDurationDefault).selectmenu("refresh").selectmenu("open");
		holder.empty();

		menu.change(function () {
			oldhtml = show_finding(btn);
			$.ajax({
				url: WSROOT + "ethClient.asmx/Beep",
				data: "{id: '" + id + "', beepDuration: '" + $(this).val() + "'}",
				success: function (retval, textStatus) {
					restore_finding(btn, oldhtml);
					updateTag(retval.d);
				},
				error: function (xhr, textStatus, exception) {
					restore_finding(btn, oldhtml);
					popup_error(xhr, btn);
				}
			});
			return false;
		});

	} else if (oldhtml == "Stop Beep") {
		oldhtml = show_finding(btn);
		$.ajax({
			url: WSROOT + "ethClient.asmx/StopBeep",
			data: "{id: '" + id + "'}",
			success: function (retval, textStatus) {
				restore_finding(btn, "Beep");
				updateTag(retval.d);
			},
			error: function (xhr, textStatus, exception) {
				restore_finding(btn, oldhtml);
				popup_error(xhr, btn);
			}
		});
	}
	else if (oldhtml == "Update") {
		oldhtml = show_finding(btn);
		$.ajax({
			url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
			data: "{id: '" + id + "'}",
			success: function (retval, textStatus) {
				updateTag(retval.d);
			},
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn);
			}
		});
	}
	else if (oldhtml == "Calibrate") {
		calFreqOffset(btn, id);
	}
	else if (oldhtml == "Migrate") {
		oldhtml = show_finding(btn);
		var tag = taglist_cache[id];
		$.ajax({
			url: WSROOT + "ethClient.asmx/RetryMigrateWirelessConfig",
			data: "{id: '" + id + "'}",
			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);
			}
		});
	}
}
function calFreqOffset(btn, id) {
	oldhtml = show_finding(btn);
	var tag = taglist_cache[id];
	$.ajax({
		url: WSROOT + "ethClient.asmx/CalibrateFrequencyOffset",
		data: "{id: '" + id + "', readFlash: false}",
		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);
		}
	});
}
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, $(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, $(event.target));
					}
				});
			} else
				mark.removeClass().addClass("ok");

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

$("#indexPage").live("pageinit", function () {

	$("#tagmanager_menu").change(function () {
		var btn = $(this);
		var oldhtml = show_finding(btn, "Loading...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
			url: WSROOT + "ethAccount.asmx/SelectTagManager",
			data: JSON.stringify({ "mac": $(this).val() }),
			success: function (retval, textStatus) {
				refreshNewMac();		// forces update the tag list.
			}
		});
	});


	$("#rxFilterChoice").change(function () {
		var btn = $(this);
		var oldhtml = show_finding(btn, "Configuring...");
		var rxFilter = $(this).val();
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
			url: WSROOT + "ethClient.asmx/SetRXFilter",
			data: "{filter:" + rxFilter + "}",
			success: function () {
				updateMaxFreqOffset(rxFilter);
				$.each(taglist_cache, function (id, tag) { updateTag(tag) });
			}
		});
	});
	$("#updateInterval").change(function () {
		var btn = $(this);
		var oldhtml = show_finding(btn, "Configuring...");
		$.ajax({
			complete: function () { restore_finding(btn, oldhtml); },
			error: function (xhr, textStatus, exception) { popup_error(xhr, btn); },
			url: WSROOT + "ethClient.asmx/SetPostbackInterval",
			data: "{sec:" + $(this).val() + ",autoRetry: true}",
			success: function (retval, textStatus) {
				for (var i = 0; i < retval.d.length; i++) {
					updateTag(retval.d[i]);
				}
			}
		});
	});
});

var serverTime2LocalTime = 0;

var updateSecIntervalID = 0;

/*
$("#indexPage").live("pagebeforecreate", function () {
	var ua = navigator.userAgent.toLowerCase();
	if (ua.indexOf("iphone") != -1 || ua.indexOf("ipod") != -1 || ua.indexOf("ipad") != -1) {
		$("#indexPage").attr("data-title", "My Tag List");
	}
});
$("#optionPage").live("pagebeforecreate", function () {
	var ua = navigator.userAgent.toLowerCase();
	if (ua.indexOf("iphone") != -1 || ua.indexOf("ipod") != -1) {
		$.each([$("#send_email_to_group"), $("#send_email_oor_group")], function (i, o) {
			var lb = o.children("label").eq(0);
			lb.hide(); o.attr("placeholder", lb.text().replace(":", ""));
		});

	}
});
*/

$("#indexPage").live("pagecreate", function () {

	//onDeviceReady();
	//document.addEventListener("deviceready", onDeviceReady, false);
	//$.mobile.defaultPageTransition = 'none';
	//$.mobile.defaultDialogTransition = 'none';
	//$.mobile.loadingMessage = false;

	try{
		document.body.addEventListener("online", function () {
			NC_onResume();
		}, false);
	}catch(e){}

	updateSecIntervalID = setInterval(function () {

		$.each(taglist_cache, function (id, tag) { updateAgoString(tag); });
		/*		if (navigator.network != null) {
		var ns = navigator.network.connection.type;
		$("#networkStatus").text(ns);
		if (ns == Connection.UNKNOWN || ns == Connection.NONE) {
		if (!lastOffline) {
		lastOffline = true;
		$("#indexPage").trigger("pagehide");
		alert("gone offline");
		}
		} else {
		if (lastOffline) {
		lastOffline = false;
		$("#indexPage").trigger("pageshow");
		alert("gone online");
		}
		}
		}
		*/
	}, 2000);

	//	clearInterval(updateSecIntervalID);

});

$("#indexPage").live('pagehide', function () {
	should_run_comet = false;
	if (getNextUpdate_xhr) {
		getNextUpdate_xhr.abort();
		getNextUpdate_xhr = null;
	}
});

var needRefreshTagManagers = true;
function refreshTagManagerDropDown(tmgrs) {
	var html = "";
	for (var i = 0; i < tmgrs.length; i++) {
		html += ('<option {0} value="{1}">{2}{3}</option>').format(tmgrs[i].selected ? "selected" : "", tmgrs[i].mac, tmgrs[i].name, tmgrs[i].online ? "" : " (Offline)");
	}
	$('#tagmanager_menu').html(html).selectmenu('refresh');

	if (tmgrs.length > 1) {
		$("#tagmanager_choice").show();
	} else {
		$("#tagmanager_choice").hide();
	}
}
$("#indexPage").bind('pageshow', function () {
	should_run_comet = true;
	$.ajax({
		url: WSROOT + "ethAccount.asmx/IsSignedInEx",
		error: function () {
			/*$.mobile.changePage("signin.html", { transition: "slidedown" });*/
			location.replace("signin.html");
		},
		success: function (retval, textStatus) {
			if (serverTime2LocalTime == 0) {
				$.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 (loginEmailAddress == null) {

				if (window.location.search == "?add_nest") {
					$.mobile.changePage($("#addnewPage"), { transition: device_transition, role: "dialog" });
					$("#addNestBtn").trigger('click');
				}

				if (window["localStorage"] != null) {
					loginEmailAddress = localStorage["mytaglist.signin.email"];
					if (window.NC) {
						window.NC.registerMN(loginEmailAddress);
					}
				} else {
					$.ajax({
						url: WSROOT + "ethAccount.asmx/GetLoginEmail",
						success: function (retval, textStatus) {
							loginEmailAddress = retval.d;
							if (window.NC) {
								window.NC.registerMN(loginEmailAddress);
							}
						}
					});
				}
			}

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

						needRefreshTagManagers = false;
						refreshTagManagerDropDown(retval.d);
					}
				});
			}
			createTagList();
			/*$.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;
	$("#updateInterval").val(d.postbackInterval).selectmenu("refresh");

	if (tmSetting.limited) {
		$(".hide-for-limited").hide();
	} 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();
	}
}
// clears the tag list, and recreate using the active selected tag manager. also updates the update interval choice. 
function refreshNewMac() {
	if (clearNotificationJSTimer) clearTimeout(clearNotificationJSTimer);
	notificationQueue = new Array();
	taglist_cache = {};
	$("#taglist").html("");
	createTagList();
	$.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"];
	$.ajax({
		url: WSROOT + "ethClient.asmx/SaveTagInfo",
		data: JSON.stringify({ "tag": tag }),
		complete: function () {
			restore_finding(btn, oldhtml);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
	tag.ampData = ampData_backup;
}
function pingTag(btn, tag) {
	var oldhtml = show_finding(btn, "Pinging...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/PingTag",
		data: "{id: '" + tag.slaveId + "'}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function optionsChoice(btn, id) {
	switch (btn.val()) {
		case "1":
			mnOptions(btn, id); break;
		case "2":
			oorOptions(btn, id); break;
		case "3":
			tempOptions(btn, id); break;
		case "4":
			msOptions(btn, id); break;
		case "22":
			lbOptions(btn, id); break;
		case "5":
			capOptions(btn, id); break;
		case "6":
			currentOptions(btn, id); break;
		case "7":
			kumostatOptions(btn, id); break;
		case "10":
			messageOptions(btn, id); break;
		case "11":
			eventURLOptions(btn, id); break;
		case "20":
			autoUpdateOptions(btn, id); break;
		case "21":
			reviveOptions(btn, id); break;
	}
}
function lightOn(btn, id) {
	var oldhtml = show_finding(btn, "Finding...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/LightOn",
		data: "{id: '" + id + "', flash: false}",
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
			restore_finding(btn, oldhtml);
		}
	});
}
function lightOff(btn, id) {
	var oldhtml = show_finding(btn, "Finding...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/LightOff",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			restore_finding(btn, oldhtml);
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
			restore_finding(btn, oldhtml);
		}
	});
}

function selectedURL(tb, isMotion) {
	tb.setSelectionRange(0, tb.value.length); $(isMotion ? "#shareMotion" : "#shareTemp").attr("checked", true).checkboxradio("refresh"); return false;
}
function previewEmbedHTML(slaveId) {
	$.ajax({
		url: WSROOT + "ethLogs.asmx/EditSharePermissions",
		data: JSON.stringify({ "ids": [slaveId], "shareTemperature": [$("#shareTemp").is(":checked")], "shareMotion": [$("#shareMotion").is(":checked")] }),
		success: function () {
			$("#embdedHTMLPreview").html($("#embedHTML").val());
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null);
		}
	});
}
function shareTag(btn, id) {
	var isMotion = (btn.val()=="2");
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		url: WSROOT + "ethLogs.asmx/GetSharePermissions",
		data: JSON.stringify({ "ids": [id], "type": isMotion?"motion":"temperature" }),
		complete: function () { restore_finding(btn, oldhtml); },
		success: function (retval, textStatus) {
			shareInfo = retval.d;
			var html = "<div style='padding: 15px; width: " + (window.innerWidth - 140) + "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'></div>"+
			"<div data-role='fieldcontain'><label for='downloadURL'>CSV download link:</label><input type='text' id='downloadURL'></div>"+
			"<div data-role='fieldcontain'><label for='iosURL'>Link to open graph in iOS app:</label><input type='text' id='iosURL'></div>"+
			"<div data-role='fieldcontain'><label for='embedHTML'>HTML to embed latest readings:</label><input type='text' id='embedHTML'><button onclick='previewEmbedHTML("+id+")' data-theme='d'>Preview HTML</button></div><div id='embdedHTMLPreview'></div>"+
			"<fieldset data-role='controlgroup'><input type='checkbox' id='shareTemp'><label for='shareTemp'>Anyone with link can access temperature 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></fieldset>"+
			"<a rel='close' data-role='button' data-theme='b' href='#'>Apply Permissions</a></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,
					'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": [id], "shareTemperature": [$("#shareTemp").is(":checked")], "shareMotion": [$("#shareMotion").is(":checked")] }),
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null);
						}
					});
				}
			};

			$("#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);
		}
	});
}

function advanced(btn, id) {
	var stat_url;
	//alert(btn.val());
	var tag = taglist_cache[id];
	var newname = null;
	switch (btn.val()) {
		case "0":
			//pingTag(btn, tag);
			reqPostback(btn, tag.slaveId);
			break;
		case "1":
			promptAsync("New tag name:", tag.name, function (newname) {
				if (newname) {
					tag.name = newname;
					updateTag(tag);
					SaveTagInfo(tag, btn);
				}
			});
			break;
		case "2":
			promptAsync("Tag comment:", tag.comment, function (newname) {
				if (newname) {
					tag.comment = newname;
					updateTag(tag);
					SaveTagInfo(tag, btn);
				}
			});
			break;
		case "3":
			var oldhtml = show_finding(btn, "Unassociating...");
			$.ajax({
				complete: function () { restore_finding(btn, oldhtml); },
				url: WSROOT + "ethClient.asmx/UnassociateTag",
				data: "{id: '" + id + "'}",
				success: function (retval, textStatus) {
					var tag = retval.d;
					if (tag.alive) {
						$("#collapsible-" + tag.slaveId).remove();
						$("#taglist").resetRoundedEdges();
					} else {


						btn.simpledialog({
							mode: 'bool',
							prompt: "Tag failed to respond to unassociation request. Did the tag start flashing?", useModal: true, forceInput: true, cleanOnClose: true,
							'buttons': {
								'Yes (remove from list)': {
									click: function () {

										if (getNextUpdate_xhr) {
											getNextUpdate_xhr.abort();
											getNextUpdate_xhr = null;
										}

										$.ajax({
											url: WSROOT + "ethClient.asmx/DeleteTag",
											data: "{id: " + tag.slaveId + "}",
											complete: function () {
												getNextUpdate();
											}
										});
										$("#collapsible-" + tag.slaveId).remove();
										$("#taglist").resetRoundedEdges();
									}, icon: "forward"
								},
								'No (do not remove)': {
									click: function () {
										//$.mobile.changePage("#indexPage", {transition: "slidedown"}, true);
									}, icon: "back"
								}
							}
						});

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

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

		case "5":
			if (window["localStorage"] != null) {
				localStorage["mytaglist.stats.slaveid"] = tag.slaveId;
				localStorage["mytaglist.stats.name"] = tag.name;
				stat_url = "stats.html";
			} else
				stat_url = "stats.html?" + tag.slaveId;

			if (isMobile()) location.replace(stat_url);
			else window.open(stat_url, "_blank");
			break;

		case "51":
			if (window["localStorage"] != null) {
				localStorage["mytaglist.stats.slaveid"] = tag.slaveId;
				localStorage["mytaglist.stats.name"] = tag.name;
				stat_url = "tempStats.html";
			} else
				stat_url = "tempStats.html?" + tag.slaveId;

			if (isMobile()) location.replace(stat_url);
			else window.open(stat_url, "_blank");
			break;

		case "11":
			rssiModeOptions(btn, id);
			break;
		case "12":
			calFreqOffset(btn, id);
			break;

		case "6":
			genericSingleTagAction(btn, id, "SoftwareResetTag", "Resetting...");
			break;
		case "7":
			lightOn(btn, id);
			break;
		case "8":
			lightOff(btn, id);
			break;
		case "9":
			genericSingleTagAction(btn, id, "SecondaryArm", "Recording...");
			break;
		case "10":
			genericSingleTagAction(btn, id, "SecondaryDisarm", "Erasing...");
			break;
	}
	return true;
}
function genericSingleTagAction(btn, id, method, progress) {
	var oldhtml = show_finding(btn, progress);
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/" + method,
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			updateTag(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function updateAgoString(tag) {
	try {
		var agostring = UserFriendlyTimeSpanString(tag.lastComm);
		$("#lasttalk-" + tag.slaveId).text(agostring);
	} catch (e) { }
}

function play_tagname(uuid, suffix) {
	if (window.NC) {
		window.NC.playTwoMediaUrl(WSROOT + "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, silence;
var amp_normal, amp_toohigh, amp_toolow;
var detected_movement, timed_out;
var is_disconnected;
//var is_online, is_offline;
var audioElement;

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';
	silence = document.createElement('audio'); silence.src = WSROOT + 'eth/styles/silence.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';
	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 }),
			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 tempDisp(tag) {
	if (tag.rev >= 11 && tag.temperature) {
		if (degCmode)
			return tag.temperature.toFixed(tag.isHTU ? 1 : 0) + "°C";
		else
			return (tag.temperature * 9 / 5 + 32).toFixed(tag.isHTU ? 1 : 0) + "°F";
	} else if (tag.isNest) {
		if (degCmode)
			return tag.temperature.toFixed(1) + "°C";
		else
			return (tag.temperature * 9 / 5 + 32).toFixed(0) + "°F";
	}else
		return "";
}
function ds18state(tag){
	if(tag.isReed){
		if(tag.ds18) return " (External)";
		else return " (Internal)";
	}
	else return "";
}
function tagVer(tag) {
	if (tag.version1 == 2) {
		if (tag.rev == 14) return " (v2.1)";
		else return " (v2.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 calculateTagStatus(tag, isMsTag, isMoistureTag, isCurrentTag, isHTU) {
	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)";

	if (isMoistureTag)
	{
		if (tag.shorted) tag_status += " (Water Detected)";

		if (tag.capEventState == 3) tag_status += " (Too Dry)";
		else if (tag.capEventState == 4) tag_status += " (Too Wet)";
		else if (tag.capEventState == 2) tag_status += " (Normal)";
		else if (tag.capEventState == 1) tag_status += " (Disarmed)";
	}
	else if (isHTU)
	{
		if (tag.capEventState == 3) tag_status += " (Too Dry)";
		else if (tag.capEventState == 4) tag_status += " (Too Humid)";
		else if (tag.capEventState == 2) tag_status += " (Normal RH)";
	}
	else if (isCurrentTag) {
		if (tag.capEventState == 3) tag_status += " (Detached)";
		if (tag.ampData != null) {
			if (tag.ampData.eventState == 2) tag_status += " (Normal)";
			else if (tag.ampData.eventState == 3) tag_status += " (Too High)";
			else if (tag.ampData.eventState == 4) tag_status += " (Too Low)";
		}
	}
	if (tag.tempEventState == 2) tag_status += " (Too Hot)";
	else if (tag.tempEventState == 3) tag_status += " (Too Cold)";
	return tag_status;
}
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.capEventState == 4) return "f";
	if (tag.capEventState == 3) return "r";
	if (tag.isNest) {
		if (tag.eventState == 5) return "t";
		else return "a";
	}
	return tagEventStates[tag.eventState][1];
}

function updateTag(tag) {

	tag.isMsTag = (tag.tagType == 12 || tag.tagType == 13); // || tag.tagType == 22);
	tag.isMoistureTag = (tag.tagType == 32 || tag.tagType == 33);
	tag.hasBeeper = (tag.tagType == 13 || tag.tagType == 12);
	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.isHTU = (tag.tagType == 52 || tag.tagType == 62 || tag.tagType == 72 || tag.tagType == 13) && !tag.isNest;
	tag.isCurrentTag = (tag.tagType == 42);

	var oldTag = taglist_cache[tag.slaveId] || {};
	taglist_cache[tag.slaveId] = tag;
	uuid2tag[tag.uuid] = tag;
	tag._updated = true;

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

	var tag_status = calculateTagStatus(tag, tag.isMsTag||tag.isPIR||tag.isReed, tag.isMoistureTag, tag.isCurrentTag, tag.isHTU);
	var ageText = UserFriendlyTimeSpanString(tag.lastComm);
	var tag_theme = calculateTagTheme(tag);

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

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

		if (tag.hasBeeper) {
			var btn1 = $("#beepbtn-" + tag.slaveId).parent();
			var btn2 = $("#alt-beepbtn-" + tag.slaveId).parent();
			var btn3 = $("#main-beepbtn-" + tag.slaveId).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 (Math.abs(tag.freqOffset) > maxFreqOffset) {
				btn1.find(".ui-btn-text").text("Calibrate"); 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.slaveId).parent();
			var btn3 = $("#main-updatebtn-" + tag.slaveId).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 (Math.abs(tag.freqOffset) > maxFreqOffset) {
				btn1.find(".ui-btn-text").text("Calibrate"); 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");
			}
		}
		if (!tag.hasBeeper) {
			if (tag.lit) {
				$("#lightbtn-" + tag.slaveId).parent().find(".ui-btn-text").text( "Light Off");
				$("#alt-lightbtn-" + tag.slaveId).parent().find(".ui-btn-text").text("Light On");
				setTheme($("#lightbtn-" + tag.slaveId).parent(), "b");
			} else {
				$("#lightbtn-" + tag.slaveId).parent().find(".ui-btn-text").text("Light On");
				$("#alt-lightbtn-" + tag.slaveId).parent().find(".ui-btn-text").text("Light Off");
				setTheme($("#lightbtn-" + tag.slaveId).parent(), "c");
			}
		}
		$("#tagname-" + tag.slaveId).text(tag.name + " " + tag_status); // + " "  + tag.solarVolt+"Ga ");
		$("#signal-icon-" + tag.slaveId).removeClass().addClass("ui-icon-signal-" + dBmToBars(tag.signaldBm));
		$("#temp-display-" + tag.slaveId).html(tempDisp(tag));

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


		if (!tag.image_md5) {
			$("#tag-pic-" + tag.slaveId).hide();
		}
		else if (tag.image_md5 != oldTag.image_md5) {
			$("#tag-pic-" + tag.slaveId).css("background", "url('/eth/tags/" + tag.uuid + ".jpg?" + (new Date()).getTime() + "')").show();
			//$("#tag-pic-" + tag.slaveId).css("background", "url('/eth/tags/"+tag.uuid+".jpg')").show();  
		}
		if (tag.eventState == 2 || tag.eventState==5) {			// moved
			$("#resetbtn-" + tag.slaveId).parent().show();
		} else {
			$("#resetbtn-" + tag.slaveId).parent().hide();
		}
		if (tag.isKumostat && tag.thermostat != null) {
			var element = $("#kumostat-range-" + tag.slaveId);
			if (element) {
				var rs = $.data(element.get(0), "rangeslider");
				rs._inputFirst.val(toNativeTemp(tag.thermostat.th_low)).slider("refresh");
				rs._inputLast.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.slaveId).flipswitch("option", "onText", "Home").flipswitch("option", "offText", "Away");
				else
					$("#ac_onoff_" + tag.slaveId).flipswitch("option", "onText", "AC/Heat On").flipswitch("option", "offText", "AC/Heat Off");

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

		var batVoltDisplay = Math.round(100.0 * tag.batteryVolt) / 100;
		var batDisplay = $("#tagbat-" + tag.slaveId);
		if (tag.batteryVolt < tag.LBTh)
			batDisplay.addClass("lbWarn");
		else
			batDisplay.removeClass("lbWarn");
		batDisplay.text(batVoltDisplay + " volts");

		$("#tagcomment-" + tag.slaveId).text(tag.comment);
		$("#signal-text-" + tag.slaveId).text(tag.signaldBm > -105 ? Math.round(tag.signaldBm) + "dBm" : "No Signal");

		if (tag.isHTU) {
			$("#tag-temp-" + tag.slaveId).html(tag.temperature ? tag.temperature.toFixed(1)+ "°C/" + Math.round(10*tag.temperature * 9 / 5 + 320)/10 + "°F" + ds18state(tag) : "N/A");
		} else {
			$("#tag-temp-" + tag.slaveId).html(tag.temperature ? Math.round(tag.temperature) + "°C/" + Math.round(tag.temperature * 9 / 5 + 32) + "°F" + tagVer(tag) : "N/A" + tagVer(tag));
		}
		if (tag.isMoistureTag || tag.isHTU)
			$("#tag-moisture-" + tag.slaveId).html(tag.cap.toFixed(0));

		/*if (tag.tagType==22) {
			$("#tag-temp-" + tag.slaveId).html(tag.temperature ? Math.round(tag.temperature) + "" : "N/A");
			$("#tag-solarstat-" + tag.slaveId).text(tag.solarVolt ? (tag.solarVolt >= tag.batteryVolt ? ", Charging" : ", On battery") : "");
		}*/

		var advchoice = $("#advanced-choice-" + tag.slaveId);
		var needUpdateAdvanced = false;
		if (tag.isMsTag) {
			if (oldTag.eventState == 0 && tag.eventState != 0) {
				advchoice.find("option[value='4']").after('<option value="9">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 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);

		if (tag.isCurrentTag) {
			currentRemoveDC(tag.ampData);
			$("#tag-arms-" + tag.slaveId).html(Math.round(currentGetRms(tag) * 100) / 100);

			if (smoothie_loaded)
				smoothie_redraw(tag.slaveId, $("#chart-" + tag.slaveId));
			else
				loadSmoothie();
		}
	}
	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)*5/9;
}
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 createTagDetail(tag) {
	var ageText = UserFriendlyTimeSpanString(tag.lastComm);

	var html = ('<div class="column pic ui-shadow" id="tag-pic-{0}" style="{1} background-image: url({3}eth/tags/{2}.jpg)"></div>').format(tag.slaveId, tag.image_md5 == null ? 'display:none;' : '', tag.uuid, WSROOT);

	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.slaveId);
		} 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.slaveId);
		}
	} 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.slaveId);
		} 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.slaveId);
		}
	}

	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.slaveId);
		} 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.slaveId, tag.beeping ? "Beep" : "Stop Beep", tag.beeping ? "search" : "delete");
		}
	}
	else if (!tag.isKumostat) {
		html += ('<button data-inline=1 id="lightbtn-{0}" data-theme="{2}" onclick="togglelight($(this), {0}); return false;"  data-icon=search>{1}</button>')
							.format(tag.slaveId, tag.lit ? "Light Off" : "Light On", tag.lit ? "b" : "c");
		html += ('<button data-inline=1 id="alt-lightbtn-{0}" data-theme="c" onclick="togglelight($(this), {0}); return false;"  data-icon=delete>{1}</button>').format(tag.slaveId, tag.lit ? "Light On" : "Light Off");
		//html += ('<button data-inline=1 id="read-stat-btn-{0}" data-theme="c" onclick="reqPostback($(this), {0}); return false;"  data-icon=refresh>Refresh Stats</button>').format(tag.slaveId);
	}

	if (tag.isMsTag || tag.isPIR) {
		if (tag.eventState == 2 || tag.eventState==5)  // moved or detected
		{
			html += ('<button data-inline=1 id="resetbtn-{0}" data-icon=delete data-theme="c" onclick="resetit($(this), {0}); return false;" >Reset</button>').format(tag.slaveId);
		}
		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.slaveId);
		}
	}
	if(tag.isMsTag){
		html += ('<select data-inline=1 id="armbtn-{0}" data-toptext="Motion sensor" data-icon=grid data-theme="a" onchange="armDisarm($(this), {0}); return false;" data-native-menu="false" ><option value="1">Arm</option><option value="2">Disarm</option></select>')
						.format(tag.slaveId);

		if (tag.isHTU)
			html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="4">Motion Sensor...</option><option value="3">Temperature...</option><option value="5">Humidity...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
		else
			html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="4">Motion Sensor...</option><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
	}
	else if (tag.isMoistureTag) {
		html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="5">Moisture...</option><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
	}
	else if (tag.isPIR) {
		html += ('<select data-inline=1 id="armbtn-{0}" data-toptext="PIR sensor" data-icon=grid data-theme="a" onchange="armDisarm($(this), {0}); return false;" data-native-menu="false" ><option value="1">Arm</option><option value="2">Disarm</option></select>')
						.format(tag.slaveId);
		html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="4">PIR Sensor...</option><option value="5">Humidity...</option><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>')
						.format(tag.slaveId);
	}
	else if (tag.isReed) {
		html += ('<select data-inline=1 id="armbtn-{0}" data-toptext="Reed sensor" data-icon=grid data-theme="a" onchange="armDisarm($(this), {0}); return false;" data-native-menu="false" ><option value="1">Arm</option><option value="2">Disarm</option></select>')
						.format(tag.slaveId);
		if (tag.isHTU) {
			html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="4">Reed Sensor...</option><option value="5">Humidity...</option><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
		} else
			html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="4">Reed Sensor...</option><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
	}
	else if (tag.isKumostat) {
		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.slaveId, degCmode ? 0 : 32, degCmode ? 43 : 110,
									toNativeTemp(tag.thermostat.th_low), toNativeTemp(tag.thermostat.th_high), degCmode ? "C" : "F", tag.image_md5 != null ? "data-indent=100" : "", degCmode?0.5:1);
		html += ('<label for="target-choice-{0}" class="ui-select">Set at:</label> <select data-inline=1 id="target-choice-{0}" data-native-menu="false">').format(tag.slaveId);

		$.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><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.slaveId, 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");
		if (tag.isNest)
			html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="3">Temperature...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option></select>').format(tag.slaveId);
		else
			html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="5">Humidity...</option><option value="3">Temperature...</option><option value="7">Wiring...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="2">Out of Range...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);

		setTimeout(function () {
			var element = $("#kumostat-range-" + tag.slaveId);
			var rs = $.data(element.get(0), "rangeslider");
			var targetChoice = $("#target-choice-" + tag.slaveId);
			var hvac_onoff = $("#ac_onoff_" + tag.slaveId);
			var fan_onoff = $("#fan_onoff_" + tag.slaveId);
			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 }),
					complete: function () {
						tstat_control("enable");
					},
					success: function (retval, textStatus) {
						updateTag(tag=retval.d);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null);
					}
				});

			});
			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 }),
					complete: function () {
						tstat_control("enable");
					},
					success: function (retval, textStatus) {
						updateTag(tag=retval.d);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null);
					}
				});
				
			});

			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 }),
						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);

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

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

						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, null);
							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 }),
					success: function (retval, textStatus) {
						updateTag(tag = retval.d);
						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 + "'}",
							success: function (retval, textStatus) {
								tstat_control("enable");
								updateTag(retval.d);
								if (tag.thermostat.targetUuid != tag.uuid)
									popup("Temperature monitoring successfully configured", rs.solidBg);
							},
							error: function (xhr, textStatus, exception) {
								popup_error(xhr, rs.solidBg);
							}
						});

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

			});
			animateTstat(rs, tag);
		}, 300);
	}
	else if (tag.isCurrentTag) {
		html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="6">Current...</option><option value="5">Proximity...</option><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
	}
	else {
		html += ('<select data-inline=1 data-toptext="Options..." onchange="optionsChoice($(this), {0}); return false;" id="options-choice-{0}" data-native-menu="false" data-icon="gear"><option value="3">Temperature...</option><option value="2">Out of Range...</option><option value="10">Customize Message...</option><option value="1">Phones...</option><option value="11">URL Calling...</option><option value="20">Auto Update...</option><option value="21">If Out-of-Range ...</option><option value="22">Low Battery Warning ...</option></select>').format(tag.slaveId);
	}
	html += ('<span id="updateIntervalFor-{0}"></span>ߵ).format(tag.slaveId);

	if (tag.hasBeeper)
		html += ('<button data-inline=1 id="pingBtn-{0}" data-icon=refresh data-theme="c" onclick="reqPostback($(this), {0}); return false;" >Ping Tag</button>').format(tag.slaveId);

	html += ('<select data-inline=1 data-toptext="Share..." onchange="shareTag($(this), {0}); return false;" data-native-menu="false" data-icon="arrow-u"><option value="1">Temperature/Humidity</option><option value="2">Motion events</option></select>').format(tag.slaveId);

	html += ('<select data-inline=1 data-right=1 data-toptext="More..." onchange="advanced($(this), {0}); return false;" id="advanced-choice-{0}" data-native-menu="false" data-icon="arrow-r">').format(tag.slaveId);
	if (tag.isNest)
		html += '<option value="1">Change Tag name</option><option value="2">Edit Tag comment</option><option value="3">Unassociate</option><option value="51">Temperature Graph</option></select>';
	else
		html += '<option value="1">Change Tag name</option><option value="2">Edit Tag comment</option><option value="3">Unassociate</option><option value="4">'
		 + (tag.migrationPending ? "Use new wireless setting" : "Use old wireless setting") + '</option>'
		 + (tag.version1 == 2 ? '<option value="11">Receiver Mode...</option><option value="12">Calibrate Frequency Offset</option>' : '')
		 + (tag.isMsTag ? (tag.eventState > 0 ? '<option value="9">Define 2nd Closed Angle</option>' : '') + (tag.az2 != 0 ? '<option value="10">Erase 2nd Closed Angle</option>' : '') : '')
		 + (tag.hasEventLog ? '<option value="5">Event Graph</option>' : '')
		 + '<option value="51">Temperature' + (tag.isMoistureTag ? '/Moisture' : '') + (tag.isHTU ? '/Humidity' : '') + ' Graph</option><option value="6">Reset States</option><option value="7">Light On<option><option value="8">Light Off</option></select>';

	if (tag.isCurrentTag) {
		html += ('<canvas id="chart-{0}" class="currentChart" data-slaveid="{0}" style="	float: right; padding-bottom: 10px; padding-right: 4px;" width="250" height="100" onclick="currentChart_click($(this)); return false;"></canvas>').format(tag.slaveId);
	}
	//html += ('<button data-inline=1 id="advancedbtn-{0}" data-icon=arrow-r data-iconpos="right" data-theme="c" onclick="advanced($(this), {0}); return false;" >Advanced</button>')
	//							.format(tag.slaveId);

	html += ('<table class="table-detail"><tr><td style="width:{5}%; word-wrap: break-word"><span id=tagcomment-{0}>{1}</span></td><td>Battery: <b><span id=tagbat-{0} {6}>{2} volts</span></b>,  Signal: <b><span id=signal-text-{0}>{3}</span></b>, Updated <b><span id=lasttalk-{0}>{4}</span></b>')
							.format(tag.slaveId, tag.comment, Math.round(100.0 * tag.batteryVolt) / 100/*Math.round(100.0 * ((tag.batteryVolt - 2.3) / 0.85))*/, tag.signaldBm > -105 ? Math.round(tag.signaldBm) + "dBm" : "No Signal", ageText, (tag.comment == null ? 1 : Math.min(tag.comment.length, 40)),
							tag.batteryVolt < tag.LBTh ? 'class="lbWarn"' : "");
	if(tag.isHTU){
		html += (',Temperature: <b><span id=tag-temp-{0}>{1}</span></b></span>')
								.format(tag.slaveId, tag.temperature ? Math.round(tag.temperature*10)/10 + "°C/" + Math.round(tag.temperature * 90 / 5 + 320)/10 + "°F" + ds18state(tag) : "N/A");
	}else{
		html += (',Temperature: <b><span id=tag-temp-{0}>{1}</span></b></span>')
								.format(tag.slaveId, tag.temperature ? Math.round(tag.temperature) + "°C/" + Math.round(tag.temperature * 9 / 5 + 32) + "°F" + tagVer(tag) : "N/A" + tagVer(tag));
	}
	if (tag.isMoistureTag) {
		html += (',Moisture: <b><span id=tag-moisture-{0}>{1}</span>%</b></span>').format(tag.slaveId, tag.cap);
	}
	else if (tag.isHTU) {
		html += (',Humidity: <b><span id=tag-moisture-{0}>{1}</span>%</b></span>').format(tag.slaveId, tag.cap.toFixed(0));
	}
	else if (tag.isCurrentTag) {
		currentRemoveDC(tag.ampData);
		html += (',Current: <b><span id=tag-arms-{0}>{1}</span>Arms</b></span>').format(tag.slaveId, Math.round(currentGetRms(tag) * 100) / 100);
		html += (',Proximity: <b><span id=tag-moisture-{0}>{1}</span>%</b></span>').format(tag.slaveId, tag.cap);
	}
	/*if (tag.tagType==22) {
		html += (',Temperature: <b><span id=tag-temp-{0}>{1}</span><span id=tag-solarstat-{0}>{2}</span></b></span>')
							.format(tag.slaveId, tag.temperature?Math.round(tag.temperature)+"":"N/A", tag.solarVolt?(tag.solarVolt >= tag.batteryVolt ? ", Charging" : ", On battery"):"");
	}*/
	html += '.</td></tr></table>';
	return html;
}
$("#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");
	}
});

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

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

	var html = ('<div data-slaveid="{3}" id="collapsible-{3}" data-role="collapsible" data-theme="{0}"><h3 id=tagtitle-{3} {6}><span id=tagname-{3}>{1} {2}</span></h3><h3><div class=ui-temp-display id=temp-display-{3}>{5}</div><span id=signal-icon-{3} class=ui-icon-signal-{4}></span></h3>')
							.format(tag_theme, tag.name, tag_status, tag.slaveId, dBmToBars(tag.signaldBm), tempDisp(tag), tag.OutOfRange?"class=oor":"");

	tag.needFreqCal = (Math.abs(tag.freqOffset) > maxFreqOffset);
	if (tag.hasBeeper) {
		html += ('<button 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.slaveId, tag.migrationPending ? "Migrate" : (tag.needFreqCal ? "Calibrate" : (tag.beeping ? "Stop Beep" : "Beep")),
							(tag.migrationPending || tag.needFreqCal) ? "e" : (tag.beeping ? "b" : "c"), tag.migrationPending ? "refresh" : (tag.beeping ? "delete" : "search"));
	} else {
		html += ('<button 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.slaveId, tag.migrationPending ? "Migrate" : (tag.needFreqCal ? "Calibrate" : "Update"), (tag.needFreqCal || tag.migrationPending) ? "e" : "c");

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

	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);
}
function createTagList() {
	$.ajax({
		url: WSROOT + "ethClient.asmx/GetTagList",
		success: function (retval, textStatus) {
			/*$.each(nest_watcher, function (auth, watcher) {
				if(watcher._fb)
					watcher._fb.off();
			});
			nest_watcher = {};*/
			$.each(taglist_cache, function (id, tag) { tag._updated = false; });

			for (var i = 0; i < retval.d.length; i++) {
				updateTag(retval.d[i]);
			}
			//$("#taglist").trigger('create');
			var hasCurrentTag = false;

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

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

						if (tag.tagType == 42) hasCurrentTag = true;
					}
				}
			});
			
			if (hasCurrentTag) {
				if (!smoothie_loaded) {

					loadSmoothie();
				} else {

					smoothie_redrawAll();
				}
			}

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

var getNextUpdate_xhr = null;
function getNextUpdate() {
	if (getNextUpdate_xhr) return;

	getNextUpdate_xhr = $.ajax({
		url: WSROOT + "ethComet.asmx?op=GetNextUpdate",
		dataType: "xml",
		contentType: "text/xml; charset=\"utf-8\"",
		beforeSend: function (xhr) { xhr.setRequestHeader("SOAPAction", '"http://mytaglist.com/ethComet/GetNextUpdate"'); },
		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><GetNextUpdate xmlns="http://mytaglist.com/ethComet" /></soap:Body></soap:Envelope>',
		error: function (xhr, textStatus, exception) {
			getNextUpdate_xhr = null;
			//popupDebug(xhr, $.mobile.pageContainer);
			if (textStatus != "abort" && xhr.responseText)
				popup_error(xhr, $.mobile.pageContainer);
			else if (should_run_comet) {
				getNextUpdate();
			}
		},
		success: function (retval, textStatus, xhr) {
			var result = $(xhr.responseXML).find('GetNextUpdateResult');
			if (result.length && result.attr("xsi:nil") != "true") {
				var tags = eval("(" + result.text() + ")");
				if (tags != null) {
					for (var i = 0; i < tags.length; i++)
						updateTag(tags[i]);
				}
			}
			getNextUpdate_xhr = null;
			getNextUpdate();
		}
	});

}
/*
$("#startconttx").click(function (event) {
	var btn = $(event.target);
	var oldhtml = show_finding(btn, "Starting PWM...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/StartListen",
		//		url: WSROOT + "ethClient.asmx/StartContTX",
		complete: function () { restore_finding(btn, oldhtml); }
	});
});
$("#stopconttx").click(function (event) {
	var btn = $(event.target);
	var oldhtml = show_finding(btn, "Stopping...");
	$.ajax({
		url: WSROOT + "ethClient.asmx/StopListen",
		//		url: WSROOT + "ethClient.asmx/StopContTX",
		complete: function () { restore_finding(btn, oldhtml); }
	});
});
*/
$("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");
		},
		error: function (xhr, textStatus, exception) {
			restore_finding(btn, oldhtml);
			popup_error(xhr, btn);
		}
	});
});


$("#addnewPage").live('pagebeforeshow', function () {
	$("#compat_notice").hide();
	$("#namingform").hide();
	$("#nestLinkForm").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: 6000, searchV1Tag: " + $("#searchV1").is(":checked")+ "}",
		success: function (retval, textStatus) {
			if (retval.d != null) {

				newTagInfo = retval.d;

				$("#foundInfo_name")[0].innerHTML = (newTagInfo.description + " (ver. " + newTagInfo.version1 + ")");
				$("#foundInfo_signal")[0].innerHTML = (newTagInfo.signaldBm > -105 ? newTagInfo.signaldBm + "dBm" : "No Signal");
				$("#foundInfo_bat")[0].innerHTML = (Math.round(100.0 * retval.d.batteryVolt) / 100) + "V";  //(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 unassociate 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 {
					$("#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();
					}
				}
				$("#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);
					}
				});*/

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

$("#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/AssociateNewTag2",
			data: JSON.stringify({ "name": name, "comment": comment, "taginfo": newTagInfo, "timeout": 6000, "lockFlash": $("#lockFlash").is(":checked") }),
			success: function (retval, textStatus) {
				newTag = retval.d;
				if (!newTag.alive) {
					btn.simpledialog({
						mode: 'bool', prompt: "Tag failed to respond to association request. Is the tag still flashing?", useModal: true, forceInput: true, cleanOnClose: true,
						'buttons': {
							'Yes (roll back)': {
								click: function () {
									$.ajax({
										url: WSROOT + "ethClient.asmx/DeleteTag",
										data: "{id: " + newTag.slaveId + "}"
									});
								}, icon: "back"
							},
							'No (treat as done)': {
								click: function () {
									$.mobile.changePage("#indexPage", { transition: device_transition }, true);

									updateTag(newTag);

									setTimeout(function () {

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

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


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

					updateTag(newTag);
					setTimeout(function () {

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

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

$("#loginEmail").blur({ regex: VALID_EMAIL_REGEX, message: "Valid email address required to recover password." }, 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();
		$("#thAngleGroup").show(); $("#non_door_mode_label").hide(); $("#door_mode_delay").parent().show();
		$(".motion_detect_mode_only").hide();
	} else {
		$("#hmc_timeout_mode").parent().show();
		$("#thAngleGroup").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_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(); } });

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(); } else { $("#tempEventGroup").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_temp").change(function () { if (this.checked) { $("#beep_at_pc_vibrate_temp_group").show(); } else { $("#beep_at_pc_vibrate_temp_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();
	} else {
		$("#auto_reset_delay").parent().show(); $("#auto_reset_delay_timeout").parent().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 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
};

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

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

			$("#mobileNotifications").children().remove();
			if (msConfig.mobile_notifications.length > 0) {
				var html = '<fieldset data-role="controlgroup"><legend>Enable notifications on:</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();
			}

			$("#mnOptionForm").unbind("submit");
			$("#mnOptionForm").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;
				}

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveMobileNotificationConfig",
					data: JSON.stringify({ "id": id, "config": msConfig, "applyAll": applyAll }),
					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);
					}
				});
				//}
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}


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

	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadLowBatteryConfig",
		data: "{id: '" + id + "'}",
		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 " + taglist_cache[id].name);

			$("#enLB").attr("checked", msConfig.enabled).checkboxradio("refresh").trigger("change");
			$("#lbTh").val(msConfig.threshold).slider("refresh");
			$("#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");
			$("#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");
			$("#lbOptionForm").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.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": id, "config": msConfig, "applyAll": applyAll }),
					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);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
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, id) {
	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), id);
	});

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

			$.mobile.changePage($("#msOptionPage"), { transition: device_transition, role: "dialog" });
			//$("#optionPage").dialog("open");
			var tag = taglist_cache[id];
			if (tag.isMsTag && tag.rev >= 0xE) {
				$("#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.isPIR) {
				$("#msOptionTitle").text("Infra-Red Sensor Options for " + taglist_cache[id].name);
				populateResetTimeout(msConfig);

				$("#doormode").val(0).trigger("change");
				$("#auto_reset_delay_timeout").parent().show();
				$("#auto_reset_delay").parent().hide();
				$(".hmcOnly").hide();
			}
			else if (tag.isReed) {
				$("#msOptionTitle").text("Reed Sensor Options for " + taglist_cache[id].name);
				$("#doormode").val(1).trigger("change");
				$("#auto_reset_delay_timeout").parent().hide();
				$("#auto_reset_delay").parent().hide();
				$(".hmcOnly").hide();
			}
			else {
				$("#msOptionTitle").text("Motion Sensor Options for " + taglist_cache[id].name);
				$("#sensitivity").val(msConfig.sensitivity).slider("refresh");
				$("#responsiveness").val(msConfig.interval).selectmenu("refresh");
				$("#thAngle").val(msConfig.door_mode_angle).selectmenu("refresh");
				$("#auto_reset_delay").val(msConfig.auto_reset_delay).selectmenu("refresh");
				$("#silent_arming").attr("checked", msConfig.silent_arming).checkboxradio("refresh");
				$(".hmcOnly").show();
				$("#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");
			$("#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");
			$("#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");
			*/
			//populateBtOptions(msConfig);

			$("#optionForm").unbind("submit");
			$("#optionForm").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();
				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.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();

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

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


$("#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;

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);
	var min1 = $('#slider_min'); var min1_val = min1.val();
	min1.attr("min", degC_min).attr("max", degC_max).val((min1_val - 32) * 5.0 / 9.0);
	var max1 = $('#slider_max'); var max1_val = max1.val();
	max1.attr("min", degC_min).attr("max", degC_max).val((max1_val - 32) * 5.0 / 9.0);
	$("#tempcal,#slider_min,#slider_max").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);
	var min1 = $('#slider_min'); var min1_val = min1.val();
	min1.attr("min", degF_min).attr("max", degF_max).val(min1_val * 9.0 / 5.0 + 32);
	var max1 = $('#slider_max'); var max1_val = max1.val();
	max1.attr("min", degF_min).attr("max", degF_max).val(max1_val * 9.0 / 5.0 + 32);
	$("#tempcal,#slider_min,#slider_max").data("unit", "°F");
}
$('#radio-degF').change(function () {
	if (degCmode) {
		convertDegCToF();
		degCmode = false;
	}
});

$(".http-verb-options").click(function (event) {
	event.preventDefault();
	var x = $(this).data("entry");

	var html = "<div style='padding: 15px'><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);
	}
	html += "</fieldset><b>Upload Content:</b><textarea id='http-content'></textarea></div>";

	var currentEuConfig = eventURLConfig[x];

	$("#http-detail-parent").simpledialog({
		'mode': 'blank',
		'prompt': false,
		'forceInput': false,
		'useModal': true,
		pickPageTheme: 'c',
		'fullHTML': html,
		onClosed: function () {
			currentEuConfig.content = $("#http-content").val();
			currentEuConfig.verb = $('input:radio[name=http-verb]:checked').val();
		}
	});
	var selectedVerb = currentEuConfig.verb || "GET";
	$("#verb-" + selectedVerb).attr("checked", true).checkboxradio("refresh");// .parent().find("label").addClass("ui-btn-active");	
	$("#http-content").val(currentEuConfig.content);
});
$(".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, id) {
	var kConfig = {};
	var tag = taglist_cache[id];
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadKumostatConfig",
		data: "{id: '" + id + "'}",
		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");
			$("#kumostatOptionForm").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": id, "config": kConfig, "applyAll": applyAll }),
					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);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}

function capOptions(btn, id) {
	if (!capOptionSetup) setupCapOption();

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

	var tag = taglist_cache[id];
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadCapSensorConfig",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#capOptionPage"), { transition: device_transition, role: "dialog" });
			if (tag.isHTU) {
				$(".htuExclude").hide();
				$("#capOptionTitle").text("Humidity Sensor Options for " + tag.name);
			} else {
				$("#capOptionTitle").text("Moisture Sensor Options for " + tag.name);
				$(".htuExclude").show();
			}

			$("#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");

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

			$("#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");
			$("#beep_at_pc_vibrate_cap").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

			$("#btnCapCal").unbind("click");
			$("#btnCapCal").click(function (event) {
				event.preventDefault();
				var cap = $("#capCal").val();
				var btn2 = $("#btnCapCal");
				var oldhtml = show_finding(btn2, "Saving...");
				$.ajax({
					url: WSROOT + "ethClient.asmx/CalibrateCapSensor",
					data: "{id: '" + id + "', capRaw: '" + tag.capRaw + "', to: '" + cap + "'}",
					complete: function () {
						$("#cap_range").rangeslider("setSolidBgAt", cap, "gray");
						restore_finding(btn2, oldhtml);
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn2);
					},
					success: function (retval, textStatus) {
						updateTag(retval.d);
					}
				});
			});

			$("#capOptionForm").unbind("submit");
			$("#capOptionForm").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;
				msConfig.th_low = $("#cap_min").val();
				msConfig.th_high = $("#cap_max").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.beep_pc_vibrate = $("#beep_at_pc_vibrate_cap").is(":checked");

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveCapSensorConfig",
					data: JSON.stringify({ "id": id, "config": msConfig, "applyAll": applyAll }),
					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 || Math.abs(org_th_high - msConfig.th_high) > 1 || Math.abs(org_th_low - msConfig.th_low) > 1)) {
							if (applyAll)
								all_tag_action(btn, "ArmCapSensorAll", "Configuring...");
							else {
								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/ArmCapSensor",
									data: "{id: '" + id + "'}",
									success: function (retval, textStatus) {
										updateTag(retval.d);
									},
									complete: function () { restore_finding(btn, oldhtml); },
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null);
									}
								});
							}
						}
						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: '" + id + "'}",
									success: function (retval, textStatus) {
										updateTag(retval.d);
									},
									complete: function () { restore_finding(btn, oldhtml); },
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null);
									}
								});
							}
						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
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);
}
var SAMPLING_PERIOD_FOR_60Hz = 48;
var SAMPLING_PERIOD_FOR_50Hz = 58;
function currentOptions(btn, id) {
	if (!currentOptionSetup) setupCurrentOption();

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

	var tag = taglist_cache[id];
	var tag_rms_raw = currentGetRmsRaw(tag);
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadCurrentSensorConfig",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#currentOptionPage"), { transition: device_transition, role: "dialog" });
			$("#currentOptionTitle").text("Current Sensor Options for " + tag.name);

			$("#enableCurrentEvent").attr("checked", tag.ampData.eventState > 1).checkboxradio("refresh").trigger("change");

			$("#currentCal").val(tag_rms_raw * tag.ampData.gain_cal * 1000).slider("refresh");
			$("#current_min").val(msConfig.th_low * 1000).slider("refresh");
			$("#current_max").val(msConfig.th_high * 1000).slider("refresh");
			$("#currentresponsiveness").val(msConfig.interval).selectmenu("refresh");

			if (msConfig.sampling_period == SAMPLING_PERIOD_FOR_60Hz) {
				$('#sampling_period_60hz').attr("checked", true).checkboxradio("refresh");
				$('#sampling_period_50hz').attr("checked", false).checkboxradio("refresh");
			} else {
				$('#sampling_period_60hz').attr("checked", false).checkboxradio("refresh");
				$('#sampling_period_50hz').attr("checked", true).checkboxradio("refresh");
			}

			$("#send_email_current").attr("checked", msConfig.send_email).checkboxradio("refresh").trigger("change");
			$("#send_tweet_current").attr("checked", msConfig.send_tweet).checkboxradio("refresh").trigger("change");
			$("#send_email_to_current").val(msConfig.email || loginEmailAddress);
			$("#beep_at_pc_current").attr("checked", msConfig.beep_pc).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_tts_current").attr("checked", msConfig.beep_pc_tts).checkboxradio("refresh").trigger("change");
			$("#beep_at_pc_vibrate_current").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

			$("#btnCurrentCal").unbind("click");
			$("#btnCurrentCal").click(function (event) {
				event.preventDefault();
				var current = $("#currentCal").val() / 1000;
				var btn2 = $("#btnCurrentCal");
				var oldhtml = show_finding(btn2, "Saving...");
				$.ajax({
					url: WSROOT + "ethClient.asmx/CalibrateCurrentSensor",
					data: "{id: '" + id + "', rmsRaw: '" + tag_rms_raw + "', to: '" + current + "'}",
					complete: function () { restore_finding(btn2, oldhtml); },
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn2);
					},
					success: function (retval, textStatus) {
						updateTag(retval.d);
					}
				});
			});

			$("#currentOptionForm").unbind("submit");
			$("#currentOptionForm").submit(function (event) {
				event.preventDefault();
				$("#currentOptionForm input:visible").trigger('blur');
				//if ($("label.error").length == 0) {
				var btn1 = $("#btnOptionSubmit_current");
				var oldhtml = show_finding(btn1, "Saving...");
				var applyAll = $("#applyAll_current").is(":checked");

				var org_th_low = msConfig.th_low, org_th_high = msConfig.th_high;
				msConfig.th_low = $("#current_min").val() / 1000;
				msConfig.th_high = $("#current_max").val() / 1000;

				var new_sampling_period = $('#sampling_period_60hz').is(":checked") ? SAMPLING_PERIOD_FOR_60Hz : SAMPLING_PERIOD_FOR_50Hz;
				var sampling_period_changed = (msConfig.sampling_period != new_sampling_period);
				msConfig.sampling_period = new_sampling_period;

				msConfig.interval = $("#currentresponsiveness").val();
				msConfig.send_email = $("#send_email_current").is(":checked");
				msConfig.send_tweet = $("#send_tweet_current").is(":checked");
				msConfig.email = $("#send_email_to_current").val();
				msConfig.beep_pc = $("#beep_at_pc_current").is(":checked");
				msConfig.beep_pc_tts = $("#beep_at_pc_tts_current").is(":checked");
				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_current").is(":checked");

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveCurrentSensorConfig",
					data: JSON.stringify({ "id": id, "config": msConfig, "applyAll": applyAll }),
					complete: function () { restore_finding(btn1, oldhtml); },
					success: function (retval, textStatus) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);

						if ($("#enableCurrentEvent").is(":checked") && (sampling_period_changed || tag.ampData.eventState < 2 || Math.abs(org_th_high - msConfig.th_high) > 0.05 || Math.abs(org_th_low - msConfig.th_low) > 0.05)) {
							if (applyAll)
								all_tag_action(btn, "ArmCurrentSensorAll", "Configuring...");
							else {
								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/ArmCurrentSensor",
									data: "{id: '" + id + "'}",
									success: function (retval, textStatus) {
										updateTag(retval.d);
									},
									complete: function () { restore_finding(btn, oldhtml); },
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null);
									}
								});
							}
						}
						else if (!$("#enableCurrentEvent").is(":checked") && tag.ampData.eventState != 1) {
							if (applyAll) {
								all_tag_action(btn, "DisarmCurrentSensorAll", "Configuring...");
							}
							else {
								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/DisarmCurrentSensor",
									data: "{id: '" + id + "'}",
									success: function (retval, textStatus) {
										updateTag(retval.d);
									},
									complete: function () { restore_finding(btn, oldhtml); },
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null);
									}
								});
							}
						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function applyDs18(tag, on) {
	$("#ds18-off").checkboxradio("disable");
	$("#ds18-on").checkboxradio("disable");
	var btn2 = on ? $("#ds18-on") : $("#ds18-off");

	var btn_text = btn2.parent().find(".ui-btn-text");
	var oldhtml = btn_text.text();
	btn_text[0].innerHTML = "Switching...";

	$.ajax({
		url: WSROOT + "ethClient.asmx/DetectExtTempSensor",
		data: "{id: '" + tag.slaveId + "', detect: " + on + "}",
		complete: function () {
			$("#ds18-off").checkboxradio("enable");
			$("#ds18-on").checkboxradio("enable");

			btn_text[0].innerHTML = oldhtml;
		},
		error: function (xhr, textStatus, exception) {
			$("#ds18-off").attr("checked", !tag.ds18).checkboxradio("refresh")
			$("#ds18-off").attr("checked", tag.ds18).checkboxradio("refresh")
			popup_error(xhr, btn2);
		},
		success: function (retval, textStatus) {
			if (on) {
				var rom = retval.d;
				if (rom != null) {
					popup("Detected external 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 external probe, taking initial readings...", btn2);
				}
			}else{
				popup("Changed to internal sensor, taking temperature readings...", btn2);
			}
			$.ajax({
				url: WSROOT + "ethClient.asmx/RequestImmediatePostback",
				data: "{id: '" + tag.slaveId + "'}",
				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 + "'}",
							success: function (retval, textStatus) {
								popup("Reconfigured temperature monitoring");
							},
							error: function (xhr, textStatus, exception) {
								popup_error(xhr, btn2);
							}
						});
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn2);
				}
			});
		}
	});
}
function tempOptions(btn, id) {

	$(".msg_template").unbind("click");
	$(".msg_template").click(function (event) {
		event.preventDefault();
		messageOptions($(this), id);
	});
	var tag = taglist_cache[id];
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadTempSensorConfig",
		data: "{id: '" + id + "'}",
		success: function (retval, textStatus) {
			if (retval.d != null) msConfig = retval.d;

			$.mobile.changePage($("#tempOptionPage"), { transition: device_transition, role: "dialog" });
			$("#tempOptionTitle").text("Temperature Sensor Options for " + tag.name);

			if (tag.isHTU) {
				$(".htuExclude").hide();
			} else {
				$(".htuExclude").show();
			}
			if (tag.isReed) {
				$('#ds18-on').attr("checked", tag.ds18).checkboxradio("refresh");
				$('#ds18-off').attr("checked", !tag.ds18).checkboxradio("refresh");

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

			degCmode = (msConfig.temp_unit == 0);

			if (!degCmode) {
				$('#radio-degF').attr("checked", true).checkboxradio("refresh");
				$('#radio-degC').attr("checked", false).checkboxradio("refresh");
				
				$("#slider_min").attr("min", degF_min).attr("max", degF_max).val(msConfig.th_low * 9.0 / 5.0 + 32).slider("refresh");
				$("#slider_max").attr("min", degF_min).attr("max", degF_max).val(msConfig.th_high * 9.0 / 5.0 + 32).slider("refresh");
				//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").data("unit", "°F");
			}
			else {
				$('#radio-degC').attr("checked", true).checkboxradio("refresh");
				$('#radio-degF').attr("checked", false).checkboxradio("refresh");

				$("#slider_min").attr("min", degC_min).attr("max", degC_max).val(msConfig.th_low).slider("refresh");
				$("#slider_max").attr("min", degC_min).attr("max", degC_max).val(msConfig.th_high).slider("refresh");
				//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").data("unit", "°C");
			}
			$("#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);
			$("#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");
			$("#beep_at_pc_vibrate_temp").attr("checked", msConfig.beep_pc_vibrate).checkboxradio("refresh");

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

				$("#ds18-off").change(function () {			// when it is clicked. 
					applyDs18(tag, false);
					ds18Changed = true;
				})
				$("#ds18-on").change(function () {			// when it is clicked. 
					applyDs18(tag, true);
					ds18Changed = true;
				})
			}
			//if (!tag.isHTU){
				$("#btnTempCal").unbind("click");
				$("#btnTempCal").click(function (event) {
					event.preventDefault();

					var cap = $("#tempcal").val();
					var btn2 = $("#btnTempCal");
					var oldhtml = show_finding(btn2, "Saving...");
					var tempCalDegC = degCmode ? $("#tempcal").val() : ($("#tempcal").val() - 32) * 5 / 9;
					$.ajax({
						url: WSROOT + "ethClient.asmx/CalibrateTempSensor",
						data: "{id: '" + id + "', degCRaw: '" + (tag.temperature - tag.tempCalOffset) + "', to: '" + tempCalDegC + "'}",
						complete: function () {
							$("#temp_range").rangeslider("setSolidBgAt", $("#tempcal").val(), "gray");
							restore_finding(btn2, oldhtml);
						},
						error: function (xhr, textStatus, exception) {
							popup_error(xhr, btn2);
						},
						success: function (retval, textStatus) {
							updateTag(retval.d);
						}
					});
				});
			//}
			$("#tempOptionForm").unbind("submit");
			$("#tempOptionForm").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;
				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.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.beep_pc_tts = $("#beep_at_pc_tts_temp").is(":checked");
				msConfig.beep_pc_vibrate = $("#beep_at_pc_vibrate_temp").is(":checked");
				msConfig.temp_unit = degCmode ? 0 : 1;

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveTempSensorConfig",
					data: JSON.stringify({ "id": id, "config": msConfig, "applyAll": applyAll }),
					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 || Math.abs(org_th_high - msConfig.th_high) > 1 || Math.abs(org_th_low - msConfig.th_low) > 1)) {

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

								var oldhtml = show_finding(btn, "Configuring...");
								$.ajax({
									url: WSROOT + "ethClient.asmx/ArmTempSensor",
									data: "{id: '" + id + "'}",
									success: function (retval, textStatus) {
										updateTag(retval.d);
									},
									complete: function () { restore_finding(btn, oldhtml); },
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null);
									}
								});
							}
						}
						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: '" + id + "'}",
									success: function (retval, textStatus) {
										updateTag(retval.d);
									},
									complete: function () { restore_finding(btn, oldhtml); },
									error: function (xhr, textStatus, exception) {
										popup_error(xhr, null);
									}
								});
							}
						}
					},
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, null);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}


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

	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadOutOfRangeConfig",
		data: "{id: '" + id + "'}",
		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 " + taglist_cache[id].name);

			$("#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_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");
			$("#beep_at_pc_vibrate_oor").attr("checked", msConfig.beep_pc_vibrate_oor).checkboxradio("refresh");

			$("#oorOptionForm").unbind("submit");
			$("#oorOptionForm").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.beep_pc_tts_oor = $("#beep_at_pc_tts_oor").is(":checked");
				msConfig.beep_pc_vibrate_oor = $("#beep_at_pc_vibrate_oor").is(":checked");

				$.ajax({
					url: WSROOT + "ethClient.asmx/SaveOutOfRangeConfig",
					data: JSON.stringify({ "id": id, "config": msConfig, "applyAll": applyAll }),
					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);
					}
				});
				//}
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
// { 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);
				}
			});
		} 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();
					$("#taglist").resetRoundedEdges();
					if (--npending == 0) {
						$.mobile.changePage("#indexPage", { transition: device_transition }, true);
					}
				},
				error: function (xhr, textStatus, exception) {
					popup_error(xhr, btn);
				}
			});
		}
	});
	if (npending == 0) 
		$.mobile.changePage("#indexPage", { transition: device_transition }, true);

});

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.replace(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
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.replace(retval.d);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}

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.replace(retval.d); //$.mobile.changePage(retval.d, { transition: device_transition, role: "dialog" });
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
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);
		}
	});
}
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].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;
	}
}
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 group with any tag manager").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");
	$("#addtagmanagerform").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. 

					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);
				}
			});
		}
	});
});
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);
		},
		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 editUser(userid, btn) {
	var isLimited = user_cache[userid].isLimited;
	if (btn.val() == 1) {
		//var oldhtml = show_finding(btn, "Loading...");
		$.ajax({
			url: WSROOT + "ethClient.asmx/QueryLimitedUserPermissions",
			data: "{userId:'" + userid + "'}",
			error: function (xhr, textStatus, exception) {
				popup_error(xhr, btn);
			},
			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,
						'forceInput': false,
						'useModal': true,
						pickPageTheme: 'c',
						'fullHTML': html
					});
				}
			}
		});
	}
	else{		// delete
		confirmAsync("Do you really want to delete " + user_cache[userid].name, function (ret) {
			if (ret) {
				var oldhtml = show_finding(btn, "Deleting...");
				$.ajax({
					complete: function () { restore_finding(btn, oldhtml); },
					url: WSROOT + "ethClient.asmx/RemoveLimitedUser",
					data: "{userId:'" + userid + "'}",
					error: function (xhr, textStatus, exception) {
						popup_error(xhr, btn);
					},
					complete: function () { restore_finding(btn, oldhtml); },
					success: function (retval, textStatus) {
						btn.parent().remove();
					}
				});
			}
		} );
	}
}
function doAddLimitedUser(mac) {
	var 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/CreateLimitedUser",
		data: JSON.stringify({ email: username, password: $("#limited-user-pwd").val(), granted: granted }),
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, null);
		},
		success: function (retval, textStatus) {
			$("#add-user-dialog").simpledialog('close');
			var userid = retval.d;
			user_cache[userid] = { name: username, id: userid, isLimited: true };
			$(('<select data-inine="1"  data-icon="gear" id="edituser-{0}" data-toptext="{1} (Limited)" onchange="editUser(\'{0}\', $(this)); return false;" data-native-menu="false"><option value="1">Edit Permissions...</option><option value="2">Delete</option></select>')
						   .format(userid, username)).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);
		},
		complete: function () { restore_finding(btn, oldhtml); },
		success: function (retval, textStatus) {
			var perms = retval.d;
			var html = "<div style='padding: 20px'><fieldset  data-role='controlgroup'><label for='limited-user-email'>Email: </label><input type='text' id='limited-user-email'></input><label for='limited-user-pwd'>Password: </label><input type='text' id='limited-user-pwd'></input></fieldset><b>This user can access:</b><fieldset data-role='controlgroup' id='add-grant-tag-choices'>";
			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,
					'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);*/

		}
	});
}
var user_cache = {};
var accountConfig = { loginEmail: null, loginPwd: null, twitterID: null, twitterPwd: null, allowMore: true, managers: [] };
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);

			tmgrs_changed = {}; tmgrs = {};
			for (var i = 0; i < accountConfig.managers.length; i++) {
				var mgr = accountConfig.managers[i];
				tmgrs[mgr.mac] = mgr;
			}

			var html = "";
			for (var mac in tmgrs) {
				var mgr = tmgrs[mac];
				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>';
				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 += "Grouped with <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>, 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);
				//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" id="edituser-{0}" data-toptext="{1} {2}" onchange="editUser(\'{0}\', $(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)" : "");
				});
				html += ('<button data-inline="1" id="adduser-{0}" onclick="addUser(\'{0}\', $(this))" data-theme="a" data-icon="plus" >Add a Limited User</button>').format(mac);
				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>';
			}
			$("#tagmanagerlist").html(html).trigger('create');
			$("#tagmanagerlist").resetRoundedEdges();

			$("#accountOptionForm").unbind("submit");
			$("#accountOptionForm").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) {
							popup_error(xhr, null);
						}
					});
				}
			});

			refreshTagManagerDropDown(accountConfig.managers);
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}

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

			$.mobile.changePage($("#eventURLOptionPage"), { transition: device_transition, role: "dialog" });
			$("#eventURLTitle").text("Custom URL Calling on Event for " + taglist_cache[id].name);

			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);
				}
			}
			$("#eventURLOptionForm").unbind("submit");
			$("#eventURLOptionForm").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": id, "config": eventURLConfig, "applyAll": applyAll }),
					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);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr);
		}
	});
}
var messageConfig;
function messageOptions(btn, id) {
	var oldhtml = show_finding(btn, "Loading...");
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		url: WSROOT + "ethClient.asmx/LoadMessageTemplateConfig",
		data: "{id: '" + id + "'}",
		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 " + taglist_cache[id].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");
			$("#messageOptionForm").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": id, "config": messageConfig, "applyAll": applyAll }),
					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);
					}
				});
			});
		},
		error: function (xhr, textStatus, exception) {
			popup_error(xhr, btn);
		}
	});
}
function undelete(btn) {
	$.ajax({
		complete: function () { restore_finding(btn, oldhtml); },
		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 = [];
	$('#multi-stat-choices').find('input:checked').each(function () {
		selected.push($(this).val());
	});
	if (selected.length > 0) {
		if (window["localStorage"] != null) {
			localStorage["mytaglist.stats.slaveids"] = selected.join(':');
			localStorage["mytaglist.stats.type"] = type;
			stat_url = "tempStatsMulti.html";
		} else
			stat_url = "tempStatsMulti.html?" + selected.join(':') + "&" + type;

		if (isMobile()) location.replace(stat_url);
		else window.open(stat_url, "_blank");
	}
}
function multiStats(btn) {
	var remaining = 5;
	var html = "<div style='padding: 15px'><b>Check list of tags to view:</b><fieldset data-role='controlgroup' id='multi-stat-choices'>";
	for (var id in taglist_cache) {
		if (btn.val() == "cap" && taglist_cache[id].cap == 0) continue;
		if (btn.val() == "motion" && !taglist_cache[id].hasEventLog) continue;
		html += "<input type='checkbox' name='view-tag' id='view-tag-{0}' {2} value='{0}'><label for='view-tag-{0}'>{1}</label>".format(id, taglist_cache[id].name, remaining > 0 ? "checked" : "");
		remaining--;
	}
	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,
			'forceInput': false,
			'useModal': true,
			pickPageTheme: 'c',
			'fullHTML': html
		});
	}
}
function globalSettings(btn) {
	switch (btn.val()) {
		case "1":
			accountOptions(btn);
			break;
		case "2":
			migrateConfig(btn); break;
		case "3":
			undeleteChoice(btn); break;
		case "4":
			rebootTm(btn); break;
	}
}
var oldConfig, newConfig;
var paramSets = {};

var org_fec_state = false;
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();
	var crc = true; //$("#newcrc16").is(":checked");
	org_fec_state = false; //$("#newfec").is(":checked");
	recalc_wireless_perf(psd, resp, crc, org_fec_state, $("#newperformance"));

	/*if (psd.allowFEC)
		$("#newfec").attr('checked', org_fec_state).checkboxradio('enable').checkboxradio('refresh');
	else
		$("#newfec").attr('checked', false).checkboxradio('disable').checkboxradio('refresh');*/
}
function recalc_wireless_perf(psd, resp, crc, fec, display) {
	var range_mult = fec ? 2 : 1;
	var bat_mult = (fec ? 0.5 : 1) * (crc ? 0.9 : 1);
	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 * range_mult, 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(); });
//$("#newcrc16").change(function () { recalc_wireless_perf_new(); });
//$("#newfec").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();
				$("#oldcrc16").attr('checked', oldConfig.useCRC16).checkboxradio("refresh");
				$("#oldfec").attr('checked', oldConfig.useFEC).checkboxradio("refresh");
				$("#newcrc16").attr('checked', newConfig.useCRC16).checkboxradio("refresh");
				$("#newfec").attr('checked', newConfig.useFEC).checkboxradio("refresh");
			} else {
				$(".crc16-fec-options").hide();
			}*/
			if (paramSets[oldConfig.psid] != null)
				recalc_wireless_perf(paramSets[oldConfig.psid], oldConfig.activeInterval, oldConfig.CRC16, oldConfig.useFEC, $("#oldperformance"));

			$("#newfreq").val(newConfig.Freq).selectmenu("refresh");
			$("#newparamset").val(newConfig.psid).selectmenu("refresh");
			$("#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");

	$.ajax({
		url: WSROOT + "ethClient.asmx/MigrateWirelessConfig",
		data: JSON.stringify({ "newConfig": newConfig }),
		complete: function () { restore_finding(btn, oldhtml); },
		success: function (retval, textStatus) {
			$.mobile.changePage("#indexPage", { transition: device_transition }, true);
			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);
		}
	});
});