
/*********************************************************************
 **
 **   server/appx-client-options.js - Client Option processing
 **
 **   This module contains code to process client options.
 **
 *********************************************************************/

// what_str =  "@(#)Appx $Header: /src/cvs/appxHtml5/server/appx-client-options.js,v 1.90 2016/05/09 12:48:18 jnelson Exp $";

// FIXME:  need a way to save to disk and reload if user deletes Browser cache
// thinking maybe allow to download and save a backup, and a way to upload and
// set options from a backup

var appxServerClientVersionStr = "5.4.4";
var appxServerClientVersionNum = 50404.010;

var appxSortedOptions = {};
var appxSortedOptionsArray = [];
var appxSortedOptionsArrayFinal;

var PROP_SECTION = 0;
var PROP_NAME = 1;
var PROP_HIDDEN = 2;
var PROP_EDIT_AT_RT = 3;
var PROP_AUTO_SAVE = 4;
var PROP_FORCE_SAVE = 5;
var PROP_EXPAND_STRING = 6;
var PROP_CREATE_PATH = 7;
var PROP_DATATYPE = 8;
var PROP_DATALIST = 9;
var PROP_VALUE = 10;
var PROP_DEFAULT = 11;
var PROP_OLD_NAME = 12;
var PROP_OLD_VALUE = 13;
var PROP_DESC = 14;

appx_session.getSysProp = function (prop) {

    switch (prop) {
        case "user.home":
            appx_session.userhome = "";
            return appx_session.userhome;
            break;
        default:
            return "";
    }
};

appx_session.parseOption = function (strIn) {
    try {
        if (typeof strIn != "string")
            return strIn;
	
    if (appx_session.globals["os"].indexOf("Win") < 0)
	var str = strIn;
    else
	var str = strIn.replace("/\//g","\\");

        var patt = /\$\([a-zA-Z0-9]+\)/;
        if (str) {

            while (str.match(patt)) {
                str = str.replace(patt, appx_session.getProp(str.match(patt)[0].replace("$", "").replace("(", "").replace(")", "")));
            }
        }
        else {
            return str;
        }
    }
    catch (e) {
	console.log("appx_session.parseOption: " + e);
	console.log(e.stack);
    }
    return str;
};

appx_session.getRawProp = function (prop) {
    try {
        if (appx_session.options && prop) {
            if (appx_session.options[prop]) {
                return appx_session.options[prop].prop[PROP_VALUE];
            }
        }
        else {
            return null;
        }
    }
    catch (e) {
	console.log("appx_session.getRawProp: " + e);
	console.log(e.stack);
    }
};

appx_session.getProp = function (prop) {
    switch( prop ) {
	case "host": prop = "lastHost"; break;
	case "port": prop = "lastPort"; break;
    }

    try {
        if (appx_session.options && prop) {
            if (appx_session.options[prop]) {
                return appx_session.options[prop].prop[PROP_VALUE] == null ? appx_session.parseOption(appx_session.options[prop].prop[PROP_DEFAULT]) : appx_session.parseOption(appx_session.options[prop].prop[PROP_VALUE]);
            }
            else {
                if (prop == "now") {
                    return Date.now();
                }
                if (prop == "rndByte") {
                    return Math.floor((Math.random() * 255) + 1).toString();
                }
                return prop;
            }
        }
        else {
            return "Options not set.";
        }
    }
    catch (e) {
	console.log("appx_session.getProp: " + e);
	console.log(e.stack);
    }
};

appx_session.setPropEx = function (prop, rawval, save) {
    if (appx_session.options) {
        if (appx_session.options[prop]) {
            var val = null;
            if (appx_session.options[prop].prop[PROP_DATATYPE] === "boolean") {
                if (rawval == null || rawval == "")
                    val = null;
                else if (rawval.toLowerCase() == "true")
                    val = true;
                else
                    val = false;
            }
            else {
                val = rawval;
            }
            if (val == appx_session.options[prop].prop[PROP_DEFAULT])
                appx_session.options[prop].prop[PROP_VALUE] = null;
            else
                appx_session.options[prop].prop[PROP_VALUE] = val;
	    if (save){
		localStorage["appx_options"] = JSON.stringify(appx_session.options);
	    }
	    if( prop === "windowTitle" ){
		$("title").html(appx_session.getProp("windowTitle"));
	    }
            return appx_session.options[prop].prop[PROP_VALUE];
        }
        else {
            return "Can't set prop:" + prop;
        }
    }
    else {
        return "Options not set.";
    }
};

appx_session.setProp = function (prop, rawval) {
    appx_session.setPropEx(prop, rawval, true);
};

appx_session.getDefaultInputFontName = function () {};


appx_session.loadOptions = function () {
    var iconSizeList, iconStyleList, encodingList, displayList, fontList, SSLModeList, tileModeList, GUILookList;
    appx_session.severityText = "Some kinda text needed here";
    appx_session.DEFAULT_LOG_LEVEL = 0;
    appx_session.DEFAULT_NOTIFY_LEVEL = 1;
    appx_session.SCALING_QUALITY_HIGH = 10;
    if (appx_session.globals["os"].indexOf("Win") < 0)
        appx_session.fileseparatorchar = "/";
    else
        appx_session.fileseparatorchar = "\\";
    appx_session.options = {};
        var options = [
            //           Section, Tag, Hidden?, Edit@RT, AutoSave, ForceSave, ExpandString, CreatePath, Datatype, DataList, Value, Default, OldTag, OldValue, Description
            {
                "prop": ["HTML5", "[HTML5]", true, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["HTML5", "host", true, true, false, false, false, false, "string", null, null, appx_session.host, null, null, "Current Host, set after user logs in."]
            }, {
                "prop": ["HTML5", "port", true, true, false, false, false, false, "string", null, null, appx_session.port, null, null, "Current Port, set after user logs in."]
            }, {
                "prop": ["HTML5", "lastPid", true, true, false, false, false, false, "string", null, null, appx_session.pid, null, null, "Last Process ID, set after user logs in."]
            }, {
                "prop": ["Experimental", "[Experimental]", true, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Experimental", "inputByteLengthCheck", true, true, false, false, false, false, "boolean", null, null, true, null, null, "Test raw byte lengths for data entry fields"]
            }, {
                "prop": ["Experimental", "cacheHtmlImages", true, true, false, false, false, false, "boolean", null, null, true, null, null, "Implement HTML image cache"]
            }, {
                "prop": ["Experimental", "cacheImagesToMemory", true, false, false, false, false, false, "boolean", null, null, true, null, null, "Cache resource images to memory?"]
            }, {
                "prop": ["Experimental", "newTypeaheadCode", true, true, false, false, false, false, "boolean", null, null, true, null, null, "Enable new typeahead test code"]
            }, {
                "prop": ["Experimental", "forceAntiAliasing", true, false, false, false, false, false, "boolean", null, null, false, null, null, "Force AntiAliasing"]
            }, {
                "prop": ["Experimental", "forceWidgetMovable", true, false, false, false, false, false, "boolean", null, null, false, null, null, "Force all widgets to be movable"]
            }, {
                "prop": ["Experimental", "convertMultiLine", true, false, false, false, false, false, "boolean", null, null, false, null, null, "convert Multi-line labels to HTML?"]
            }, {
                "prop": ["Experimental", "showTypeaheadLog", true, true, false, false, false, false, "boolean", null, null, false, null, null, "Log typeahead messages?"]
            }, {
                "prop": ["Experimental", "showExperimental", true, true, false, false, false, false, "boolean", null, null, false, null, null, "Show hidden experimental options?"]
            }, {
                "prop": ["Experimental", "cacheImagesInMemory", true, false, false, false, false, false, "boolean", null, null, true, null, null, "Cache all resource images in memory?"]
            }, {
                "prop": ["Experimental", "autoFillMainWindow", true, true, false, false, false, false, "boolean", null, null, false, null, null, "If using a scrollpane, fill extra space with main window BG color"]
            }, {
                "prop": ["Experimental", "autoGuiWindowMargins", true, true, false, false, false, false, "boolean", null, null, true, null, null, "turn on auto-gui window margins"]
            }, {
                "prop": ["Experimental", "hideMenuBorder", true, false, false, false, false, false, "boolean", null, null, false, null, null, "hide the border line between the menubar and the toolbar"]
            }, {
                "prop": ["Experimental", "addToolbarBorder", true, false, false, false, false, false, "boolean", null, null, false, null, null, "Add a border to the toolbar window"]
            }, {
                "prop": ["Experimental", "toolbarBorderRaised", true, false, false, false, false, false, "boolean", null, null, false, null, null, "draw the toolbar border as a raised border"]
            }, {
                "prop": ["Experimental", "timeoutMultiplier", true, true, false, false, false, false, "float", null, null, 1, null, null, "Timout multiplier applied to server timeout value"]
            }, {
                "prop": ["Experimental", "clearCache", true, true, false, false, false, false, "boolean", null, null, false, null, null, "clear .appx cache directory"]
            }, {
                "prop": ["Experimental", "newPulldownMenus", true, true, false, false, false, false, "boolean", null, null, true, null, null, "New pulldown menu code allows same name in more than one place."]
            }, {
                "prop": ["Experimental", "loadHyperlinksInPlace", true, true, false, false, false, false, "boolean", null, null, false, null, null, "Launch hyperlinks into the html viewer widget."]
            }, {
                "prop": ["Experimental", "newWidgetParser", true, true, false, false, false, false, "boolean", null, null, true, null, null, "Activate new code for parsing widgets"]
            }, {
                "prop": ["Experimental", "autoGuiParser", true, true, false, false, false, false, "boolean", null, null, true, null, null, "Activate client autoGui parser"]
            }, {
                "prop": ["Experimental", "newImageEditorTools", true, true, false, false, false, false, "boolean", null, null, true, null, null, "New Image Editor Tools"]
            }, {
                "prop": ["Experimental", "autoFontScaling", true, true, false, false, false, false, "boolean", null, null, false, null, null, "Can font size auto adjust as window resizes"]
            }, {
                "prop": ["Options", "[Options]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
            //           Section, Tag, Hidden?, Edit@RT, AutoSave, ForceSave, ExpandString, CreatePath, Datatype, DataList, Value, Default, OldTag, OldValue, Description
                "prop": ["Options", "gridVirtualScroll", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Grids use virtual scrolling versus paging"]
	    }, {
                "prop": ["Options", "gridFilterToolbar", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Show grid filter toolbar"]
	    },{
                "prop": ["Options", "gridShowRowNumbers", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Show row numbers on left side of grid"]
            }, {
                "prop": ["Options", "gridShowFooterBar", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Show footer bar on grid"]
            }, {
                "prop": ["Options", "guiInterface", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Turn the GUI Interface On or Off"]
            }, {
                "prop": ["Options", "showOptionNumbers", false, true, true, true, false, false, "boolean", null, null, false, null, null, "Show numeric option numbers of buttons"]
            }, {
                "prop": ["Options", "autoTabOut", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Tab to next field after current field is filled"]
            }, {
                "prop": ["Options", "autoSelect", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Select text as a field gains focus"]
            }, {
                "prop": ["Options", "dockingScrollbar", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Hide scrollbar unless the mouse is near the scrollbar location"]
            }, {
                "prop": ["Options", "showScrollbar", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Should the scrollbar be visible at all?"]
            }, {
                "prop": ["Options", "showGridlines", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Show gridlines in the Image Editor"]
            }, {
                "prop": ["Options", "toolbarIconSize", false, true, true, false, false, false, "string", iconSizeList, null, "Medium", null, null, "Toolbar Icon Size"]
            }, {
                "prop": ["Options", "toolbarStyle", false, true, true, false, false, false, "string", iconStyleList, null, "Icons", null, null, "Toolbar Button Style"]
            }, {
                "prop": ["Options", "editorForceSize", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Force design widgets to not truncate content"]
            }, {
                "prop": ["Options", "hideStaticClientMenus", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Hide the client autoGui static pulldown menus"]
            }, {
                "prop": ["Options", "characterEncoding", false, true, false, false, false, false, "string", encodingList, null, "windows-1252", null, null, "Character Set Encoding "]
            }, {
                "prop": ["Options", "showButtonFocus", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Show focus border when button has focus"]
            }, {
                "prop": ["Options", "textReverseEnterKey", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Pressing ENTER in a Text Field performs a Newline only, Ctrl-Enter triggers button"]
            }, {
                "prop": ["Options", "arrowScrollEditor", false, true, true, false, false, false, "boolean", null, null, true, null, null, "arrow keys will scroll ilf code if at top or bottom of region"]
            }, {
                "prop": ["Options", "endMappedToCtrlE", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Should the Ctrl-E sequence map to an Appx END key action?"]
            }, {
                "prop": ["Options", "hidePrefsMenuItem", false, false, true, false, false, false, "boolean", null, null, false, null, null, "Hide the menu option to edit the preferences.ini file"]
            }, {
                "prop": ["Options", "appxDoubleClick", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Enable Appx DoubleClick = EnterKey logic"]
            }, {
                "prop": ["Options", "allowAquaButtons", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Allow native Aqua buttons on OSX?"]
            }, {
                "prop": ["Options", "arrowScrollRegion", false, true, true, false, false, false, "boolean", null, null, false, null, null, "arrow keys will scroll and scrolling area if at top or bottom of region"]
            }, {
                "prop": ["Options", "alwaysOnTop", false, false, false, false, false, false, "boolean", null, null, false, null, null, "Window always on top?"]
            }, {
                "prop": ["Options", "windowOpacity", false, false, false, false, false, false, "integer", null, null, 100, null, null, "Window opacity (0=transparent, 100=fully opaque)"]
            }, {
                "prop": ["Options", "borderlessMode", false, false, false, false, false, false, "boolean", null, null, false, null, null, "Remove main window border decorations"]
            }, {
                "prop": ["Options", "useMainTitlebar", false, false, false, false, false, false, "boolean", null, null, false, null, null, "Use the main window titlebar instead of a MDI type titlebar"]
            }, {
                "prop": ["Options", "useScrollNavBar", false, false, false, false, false, false, "boolean", null, null, false, null, null, "Use a NavBar for scrollers instead of a ScrollBar"]
            }, {
                "prop": ["Options", "newScanButton", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Activate new code for smaller scan button"]
            }, {
                "prop": ["Options", "displayNumber", false, false, false, false, false, false, "string", displayList, null, "1", null, null, "Which workstation display to use for a multi-head PC"]
            }, {
                "prop": ["Options", "drawBlockCursor", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Draw the block cursor"]
            }, {
                "prop": ["Options", "drawScrollActive", false, true, true, false, false, false, "boolean", null, null, true, null, null, "Draw the scrolling region record selected"]
            }, {
                "prop": ["Options", "swipeScrollMode", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Swipe to Scroll Mode"]
            }, {
                "prop": ["Options", "oldLayerNumbers", false, true, true, false, false, false, "boolean", null, null, false, null, null, "Use pre-5.1 layer numbers (1,2,3) instead of new (10,20,30)"]
            }, {
                "prop": ["Options", "valueChangedTimer", false, true, true, false, false, false, "integer", null, null, 500, null, null, "Milliseconds to wait after typing for value changed events to fire"]
            }, {
                "prop": ["Options", "messageComboRows", false, true, true, false, false, false, "integer", null, null, 8, null, null, "How many rows to display in status message list before adding a scrollbar"]
            }, {
                "prop": ["Options", "resizeMainWindowPane", false, false, true, false, false, false, "boolean", null, null, false, null, null, "Dynamically resize the main display scrollpane?"]
            }, {
                "prop": ["Options", "mainWindowScrollPane", false, false, true, false, false, false, "boolean", null, null, false, null, null, "Use a scrollpane for the main display and stop auto-zooming"]
            }, {
                "prop": ["Options", "randomizeWindowLocation", false, false, true, false, false, false, "boolean", null, null, false, null, null, "Add small random offset so new windows don't start exactly over existing windows"]
            }, {
                "prop": ["Options", "doubleBufferScreen", false, false, true, false, false, false, "boolean", null, null, true, null, null, "Wait for images to load before showing screens"]
            }, {
                "prop": ["ReportViewers", "[ReportViewers]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["ReportViewers", "pdfReportViewer", false, true, true, true, false, false, "string", null, null, null, null, null, "Viewer for PDF files"]
            }, {
                "prop": ["ReportViewers", "txtReportViewer", false, true, true, true, false, false, "string", null, null, null, null, null, "Viewer for TXT files"]
            }, {
                "prop": ["ReportViewers", "autoDeleteTimer", false, true, true, true, false, false, "integer", null, null, 30, null, null, "How many seconds to wait before auto-deleting print files"]
            }, {
                "prop": ["SSL", "[SSL]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["SSL", "SSLMode", false, false, false, false, false, false, "string", SSLModeList, null, "optional", null, null, "Use SSL for connections?"]
            }, {
                "prop": ["SSL", "SSLAnonAllowed", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Allow SSL connections to a server that does not have an SSL certificate"]
            }, {
                "prop": ["SSL", "SSLMismatchAllowed", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Allow SSL Mismatched options with user acknowledgement"]
            }, {
                "prop": ["SSL", "SSLSelfSignedAllowed", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Allow SSL certificates that are not signed by a trusted signing authority"]
            }, {
                "prop": ["SSL", "SSLHandshakeTimeout", false, false, false, false, false, false, "integer", null, null, 3, null, null, "Login older server fallback timeout in seconds"]
            }, {
                "prop": ["OutputEdit", "[OutputEdit]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["OutputEdit", "printRowsPerInch", false, true, false, false, false, false, "float", null, null, 6.0, null, null, "printable rows per inch for PDf design"]
            }, {
                "prop": ["OutputEdit", "printColsPerInch", false, true, false, false, false, false, "float", null, null, 10.0, null, null, "printable columns per inch for PDF design"]
            }, {
                "prop": ["UIDefaults", "[UIDefaults]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["UIDefaults", "allowXpTheme", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Allow XP theme to be used"]
            }, {
                "prop": ["UIDefaults", "editInsetTop", false, true, false, false, false, false, "integer", null, null, 0, null, null, "Top insets for data entry widgets"]
            }, {
                "prop": ["UIDefaults", "editInsetLeft", false, true, false, false, false, false, "integer", null, null, 1, null, null, "Left insets for data entry widgets"]
            }, {
                "prop": ["UIDefaults", "editInsetBottom", false, true, false, false, false, false, "integer", null, null, 0, null, null, "Bottom insets for data entry widgets"]
            }, {
                "prop": ["UIDefaults", "editInsetRight", false, true, false, false, false, false, "integer", null, null, 0, null, null, "Right insets for data entry widgets"]
            }, {
                "prop": ["UIDefaults", "showMessageDialogs", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Show MESSAGE text in a popup dialog"]
            }, {
                "prop": ["UIDefaults", "showWarningDialogs", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Show WARNING text in a popup dialog"]
            }, {
                "prop": ["UIDefaults", "showErrorDialogs", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Show ERROR text in a popup dialog"]
            }, {
                "prop": ["UIDefaults", "scanTooltip", false, true, false, false, false, false, "string", null, null, "Click to scan for a value from a lookup file", null, null, "Scan button tooltip"]
            }, {
                "prop": ["Performance", "[Performance]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Performance", "repaintLevel", false, true, false, false, false, false, "integer", null, null, 1, null, null, "Screen repaint optimization level"]
            }, {
                "prop": ["Performance", "scalingQuality", false, true, false, false, false, false, "string", null, null, appx_session.SCALING_QUALITY_HIGH, "scaling", null, "Determine how images are scaled"]
            }, {
                "prop": ["Performance", "tcpNoDelay", false, true, false, false, false, false, "boolean", null, null, true, null, null, "TCP_NODELAY setting"]
            }, {
                "prop": ["Performance", "busyRepaintTimer", false, true, false, false, false, false, "integer", null, null, 600, null, null, "Milliseconds between repaints when waiting on server (600=1 Second)"]
            }, {
                "prop": ["LocalPaths", "[LocalPaths]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["LocalPaths", "userHome", false, false, false, false, true, true, "string", null, null, appx_session.getSysProp("user.home"), null, null, "Local user home directory"]
            }, {
                "prop": ["LocalPaths", "clientHome", false, false, false, false, true, true, "string", null, null, appx_session.getSysProp("user.dir"), null, null, "Appx Client home directory"]
            }, {
                "prop": ["LocalPaths", "userClientRoot", false, false, false, false, true, true, "string", null, null, "$(userHome)" + appx_session.fileseparatorchar + ".appx", null, null, "Appx Client root directory for all local files or a user"]
            }, {
                "prop": ["LocalPaths", "cacheRoot", false, false, false, false, true, true, "string", null, null, "$(userClientRoot)" + appx_session.fileseparatorchar + "cache", null, null, "Cache path root directory for all client cache files"]
            }, {
                "prop": ["LocalPaths", "cachePath", false, false, false, false, true, true, "string", null, null, "$(cacheRoot)" + appx_session.fileseparatorchar + "$(host)" + appx_session.fileseparatorchar + "$(port)", null, null, "Cache path directory for the current session"]
            }, {
                "prop": ["LocalPaths", "tokenCachePath", false, false, false, false, true, true, "string", null, null, "$(cachePath)" + appx_session.fileseparatorchar + "Token", null, null, "Token cache path directory for the current session"]
            }, {
                "prop": ["LocalPaths", "resourceCachePath", false, false, false, false, true, true, "string", null, null, "$(cachePath)" + appx_session.fileseparatorchar + "Resource", null, null, "Resource cache path directory for the current session"]
            }, {
                "prop": ["LocalPaths", "printCachePath", false, false, false, false, true, true, "string", null, null, "$(cachePath)" + appx_session.fileseparatorchar + "Print", null, null, "Print cache path directory for the current session"]
            }, {
                "prop": ["LocalPaths", "dataCachePath", false, false, false, false, true, true, "string", null, null, "$(cachePath)" + appx_session.fileseparatorchar + "Data", null, null, "Data cache path directory for the current session"]
            }, {
                "prop": ["LocalPaths", "dropCachePath", false, false, false, false, true, true, "string", null, null, "$(cachePath)" + appx_session.fileseparatorchar + "Drop", null, null, "Drag and drop cache path directory for the current session"]
            }, {
                "prop": ["LocalPaths", "themeHome", false, false, false, false, true, false, "string", null, null, "$(clientHome)" + appx_session.fileseparatorchar + "themes", null, null, "Root theme directory to use in locating all themes"]
            }, {
                "prop": ["LocalPaths", "themeDir", false, false, false, false, true, false, "string", null, null, "$(clientHome)" + appx_session.fileseparatorchar + "themes" + appx_session.fileseparatorchar + "$(themeName)", null, null, "Theme directory currently in use"]
            }, {
                "prop": ["Startup", "[Startup]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Startup", "loginPositionX", false, false, false, false, false, false, "integer", null, null, 300, null, null, "Login Dialog screen position X"]
            }, {
                "prop": ["Startup", "loginPositionY", false, false, false, false, false, false, "integer", null, null, 300, null, null, "Login Dialog screen position Y"]
            }, {
                "prop": ["Startup", "startX", false, false, false, false, false, false, "integer", null, null, -1, null, null, "Startup screen position X"]
            }, {
                "prop": ["Startup", "startY", false, false, false, false, false, false, "integer", null, null, -1, null, null, "Startup screen position Y"]
            }, {
                "prop": ["Startup", "netcardLockupFix", false, false, false, false, false, false, "boolean", null, null, false, null, null, "Workaround for bad notebook netcard, limit constants exchanged"]
            }, {
                "prop": ["Startup", "baseFontName", false, false, false, false, false, false, "string", fontList, null, appx_session.getDefaultInputFontName(), "font", null, "Base font to use on screens"]
            }, {
                "prop": ["Startup", "initialFontSize", false, false, false, false, false, false, "integer", null, null, 14, null, null, "Base font size to use on startup"]
            }, {
                "prop": ["Startup", "widgetFontAdjust", false, false, false, false, false, false, "integer", null, null, 0, null, null, "Font scaling adjustment for widgets"]
            }, {
                "prop": ["Startup", "baseTilingMode", false, false, false, false, false, false, "string", tileModeList, null, null, "bmode", null, "Base wallpaper tiling mode"]
            }, {
                "prop": ["Startup", "baseWallpaper1", false, false, false, false, true, false, "string", null, null, null, "tile1", null, "Base wallpaper for level 1 windows"]
            }, {
                "prop": ["Startup", "baseWallpaper2", false, false, false, false, true, false, "string", null, null, null, "tile2", null, "Base wallpaper for level 2 windows"]
            }, {
                "prop": ["Startup", "baseWallpaper3", false, false, false, false, true, false, "string", null, null, null, "tile3", null, "Base wallpaper for level 3 windows"]
            }, {
                "prop": ["Startup", "baseWallpaper4", false, false, false, false, true, false, "string", null, null, null, "tile4", null, "Base wallpaper for level 4 windows"]
            }, {
                "prop": ["Startup", "baseWallpaper5", false, false, false, false, true, false, "string", null, null, null, "tile5", null, "Base wallpaper for level 5 windows"]
            }, {
                "prop": ["Startup", "guiLook", false, false, true, false, false, false, "string", null, null, "appx", "look", null, "LookAndFeel Java theme to use"]
            }, {
                "prop": ["Startup", "showOptionsTab", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Show the Login Options tab?"]
            }, {
                "prop": ["Startup", "commandShell", false, false, false, false, true, false, "string", null, null, null, "shell", null, "OS Command Shell for launching files"]
            }, {
                "prop": ["Startup", "connectMode", false, false, false, false, false, false, "string", null, null, appx_session.CONNECT_MODE_BOTH, "mode", null, "Preset the connection type"]
            }, {
                "prop": ["Startup", "embedApplet", false, false, false, false, false, false, "boolean", null, null, false, "embed", true, "Should the applet run embedded"]
            }, {
                "prop": ["Startup", "enginePath", false, false, false, false, true, false, "string", null, null, null, "pathname", null, "Engine pathname for Local execution"]
            }, {
                "prop": ["Startup", "mapOptionKey", false, false, false, false, false, false, "string", null, null, null, "optkey", null, "Key to use for the Option key"]
            }, {
                "prop": ["Startup", "mapTabKey", false, false, false, false, false, false, "string", null, null, null, "tabkey", null, "Key to use for the Tab key"]
            }, {
                "prop": ["Startup", "mapEndKey", false, false, false, false, false, false, "string", null, null, null, "endkey", null, "Key to use for the End key"]
            }, {
                "prop": ["Startup", "profileName", false, false, false, false, true, false, "string", null, null, null, null, null, "Name of profile to use from INI file"]
            }, {
                "prop": ["Startup", "reconnectId", false, false, false, false, false, false, "integer", null, null, 0, null, null, "Reconnect ID"]
            }, {
                "prop": ["Startup", "remoteHost", false, false, false, false, false, false, "string", null, null, null, "host", null, "Remote login hostname"]
            }, {
                "prop": ["Startup", "remotePassword", false, false, false, false, false, false, "string", null, null, null, "password", null, "Remote login password"]
            }, {
                "prop": ["Startup", "remotePort", false, false, false, false, false, false, "integer", null, null, 0, "port", null, "Remote connection Appx server port"]
            }, {
                "prop": ["Startup", "remoteUser", false, false, false, false, false, false, "string", null, null, null, "user", null, "Remote login user id"]
            }, {
                "prop": ["Startup", "useSSO", false, false, false, false, false, false, "boolean", null, null, false, "sso", null, "SSO Authentication?"]
            }, {
                "prop": ["Startup", "runApplication", false, false, false, false, false, false, "string", null, null, null, "application", null, "Application to run on startup"]
            }, {
                "prop": ["Startup", "runDatabase", false, false, false, false, false, false, "string", null, null, null, "database", null, "Database to run on startup"]
            }, {
                "prop": ["Startup", "runProcess", false, false, false, false, false, false, "string", null, null, null, "process", null, "Process to run on startup"]
            }, {
                "prop": ["Startup", "runProcessType", false, false, false, false, false, false, "string", null, null, null, "ptype", null, "Process Type to run on startup"]
            }, {
                "prop": ["Startup", "screenRows", false, false, true, false, false, false, "integer", null, null, 21, "rows", null, "Screen grid cell rows"]
            }, {
                "prop": ["Startup", "screenColumns", false, false, true, false, false, false, "integer", null, null, 80, "cols", null, "Screen grid cell columns"]
            }, {
                "prop": ["Startup", "screenAspect", false, false, false, false, false, false, "float", null, null, 2.625, null, null, "Screen cell width multiplier to get height"]
            }, {
                "prop": ["Startup", "showDateScans", false, false, false, false, false, false, "boolean", null, null, false, "datescan", true, "Show scan buttons on date fields"]
            }, {
                "prop": ["Startup", "showMenubar", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Show Menubar on client window"]
            }, {
                "prop": ["Startup", "showStatusbar", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Show Statusbar on client window"]
            }, {
                "prop": ["Startup", "showToolbar", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Show Toolbar on client window"]
            }, {
                "prop": ["Startup", "showScanButtons", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Show Scan Buttons on client window"]
            }, {
                "prop": ["Startup", "startupWallMode", false, false, false, false, false, false, "string", null, null, null, "smode", null, "Wallpaper tiling mode for startup wallpaper"]
            }, {
                "prop": ["Startup", "startupWallpaper", false, false, false, false, true, false, "string", null, null, null, "splash", null, "Wallpaper to load into the window in start"]
            }, {
                "prop": ["Startup", "themeName", false, false, false, false, false, false, "string", null, null, "default", "theme", null, "Name of theme directory to use"]
            }, {
                "prop": ["Startup", "windowTitle", false, false, false, false, true, false, "string", null, null, "APPX - $(host):$(port):$(lastPid)", "title", null, "Text to show in the window title"]
            }, {
                "prop": ["Startup", "mergeBoxes", true, true, false, false, false, false, "boolean", null, null, false, null, null, "Merge boxes that touch top and two sides of screen"]
            }, {
                "prop": ["Startup", "readServerStack", false, false, false, false, false, false, "boolean", null, null, true, null, null, "Read server pcb stack for client widget persistence"]
            }, {
                "prop": ["Debug", "[Debug]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Debug", "loggingEnabled", false, false, false, false, false, false, "boolean", null, null, false, null, null, "Turn on debug logging"]
            }, {
                "prop": ["Debug", "debugNotifyLevel", false, true, false, false, false, false, "integer", appx_session.severityText, null, appx_session.DEFAULT_NOTIFY_LEVEL, null, null, "Set debug level for popup dialogs"]
            }, {
                "prop": ["Debug", "debugLogLevel", false, true, false, false, false, false, "integer", appx_session.severityText, null, appx_session.DEFAULT_LOG_LEVEL, null, null, "Set debug level for logging to the logfile"]
            }, {
                "prop": ["Debug", "memoryCheckTimer", false, false, false, false, false, false, "integer", null, null, 15, null, null, "Seconds between About Dialog memory checks"]
            }, {
                "prop": ["LogOptions", "[LogOptions]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["LogOptions", "logClassCreation", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log the creation of Java classes"]
            }, {
                "prop": ["LogOptions", "logServerRequests", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log server request messages"]
            }, {
                "prop": ["LogOptions", "logObjectEvents", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log object events"]
            }, {
                "prop": ["LogOptions", "logTokenScanList", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log Token Scanlist information"]
            }, {
                "prop": ["LogOptions", "logGetFileList", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log get file list information"]
            }, {
                "prop": ["LogOptions", "logGetFieldList", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log get field list information"]
            }, {
                "prop": ["LogOptions", "logBitsSent", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log bits sent"]
            }, {
                "prop": ["LogOptions", "logBitsRecv", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log bits received"]
            }, {
                "prop": ["LogOptions", "logKeyboardEvents", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log keyboard events"]
            }, {
                "prop": ["LogOptions", "logKeyboardEventStack", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log keyboard event stack info"]
            }, {
                "prop": ["LogOptions", "logTopBoxTitle", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log topmost window titles"]
            }, {
                "prop": ["LogOptions", "logConsoleToFile", false, true, false, false, false, false, "boolean", null, null, true, null, null, "Log console debug info to logfile"]
            }, {
                "prop": ["LogOptions", "logRawWidgetData", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log raw widget data"]
            }, {
                "prop": ["LogOptions", "logRawEventData", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log raw event data"]
            }, {
                "prop": ["LogOptions", "logFileTransfers", false, true, false, false, false, false, "boolean", null, null, false, null, null, "Log file transfer statistics"]
            }, {
                "prop": ["Constants", "[Constants]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "serverConnectorVersionStr", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "serverConnectorVersionNum", false, false, false, false, false, false, "integer", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "clientServerVersionStr", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "clientServerVersionNum", false, false, false, false, false, false, "integer", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "clientPublicVersionStr", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "clientPublicVersionNum", false, false, false, false, false, false, "integer", null, null, null, null, null, ""]
            },{
                "prop": ["Constants", "localConnectorVersionStr", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "localConnectorVersionNum", false, false, false, false, false, false, "integer", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "rawEncoding", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "nationalEncoding", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "ucode32Encoding", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["Constants", "networkEncoding", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["LastLogin", "[LastLogin]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {
                "prop": ["LastLogin", "lastHost", false, false, true, false, false, false, "string", null, null, null, null, null, "Remote login hostname"]
            }, {
                "prop": ["LastLogin", "lastPort", false, false, true, false, false, false, "integer", null, null, 8060, null, null, "Remote connection Appx server port"]
            }, {
                "prop": ["LastLogin", "lastUser", false, false, true, false, false, false, "string", null, null, null, null, null, "Remote login user id"]
            }, {
                "prop": ["LastLogin", "userData", false, false, false, false, false, false, "string", null, null, null, null, null, "User Data to pass to server"]
            }, {
                "prop": ["LastLogin", "lastPassword", true, false, false, false, true, false, "string", null, null, null, null, null, "Remote login password"]
            }, {
                "prop": ["LastLogin", "lastPath", false, false, true, false, true, false, "string", null, null, null, null, null, "Engine pathname for Local execution"]
            }, {
                "prop": ["LastLogin", "lastTab", false, false, true, false, false, false, "string", null, null, null, null, null, "Engine pathname for Local execution"]
            }, {
                "prop": ["LastLogin", "lastIniFile", false, false, true, false, false, false, "string", null, null, null, null, null, "Last profile"]
            }, {
                "prop": ["LastLogin", "lastUseSSO", false, false, true, false, false, false, "boolean", null, null, null, null, null, "Last Use SSO"]
            }, {
                "prop": ["LastLogin", "lastPid", false, false, true, false, false, false, "string", null, null, null, null, null, "Last server side process id"],
		"prop": ["Obsolete", "[Obsolete]", false, false, false, false, false, false, "string", null, null, null, null, null, ""]
            }, {       //"Options" 
                "prop": ["Obsolete", "presentationMode", false, false, false, false, false, false, "boolean", null, null, false, null, null, "(Obsolete) - Hide frame, stretch to fill screen, and center"]
            }, {
                "prop": ["Obsolete", "presentationFg", false, false, false, false, false, false, "string", null, null, "#FFFFFF", null, null, "(Obsolete) - Background color to fill around client window"]
            }, {
                "prop": ["Obsolete", "presentationBg", false, false, false, false, false, false, "string", null, null, "#000000", null, null, "(Obsolete) - Background color to fill around client window"]
            }, {
                "prop": ["Obsolete", "presentationFooterSize", false, false, false, false, false, false, "integer", null, null, 14, null, null, "(Obsolete) - Font size of footer message in Presentation Mode"]
            }, {
                "prop": ["Obsolete", "presentationRemote", false, true, true, false, false, false, "boolean", null, null, false, null, null, "(Obsolete) - Presentation Remote Mode"]
            }, {       //"OutuputEdit"
                "prop": ["Obsolete", "editorCellGridColor", false, true, false, false, false, false, "string", null, null, "#CCCCFF", null, null, "(Obsolete) - Grid line color for the character cell grid"]
            }, {
                "prop": ["Obsolete", "editorInchGridColor", false, true, false, false, false, false, "string", null, null, "#FFCCCC", null, null, "(Obsolete) - Grid line color for the form inches grid"]
            }, {       //"UIDefaults"
                "prop": ["Obsolete", "caretColor", false, true, false, false, false, false, "string", null, null, "#000000", null, null, "(Obsolete) - Caret color for data entry widgets"]
            }, {       //"Startup"
                "prop": ["Obsolete", "colorAppletBg", false, false, false, false, false, false, "string", null, null, null, "appletBg", null, "(Obsolete) - Applet Background Color"]
            }, {
                "prop": ["Obsolete", "colorBoldFg", false, false, false, false, false, false, "string", null, null, null, "boldFg", null, "(Obsolete) - Bold Foreground Color"]
            }, {
                "prop": ["Obsolete", "colorButtonBg", false, false, false, false, false, false, "string", null, null, null, "buttonBg", null, "(Obsolete) - Button Background Color"]
            }, {
                "prop": ["Obsolete", "colorButtonFg", false, false, false, false, false, false, "string", null, null, null, "buttonFg", null, "(Obsolete) - Button Foreground Color"]
            }, {
                "prop": ["Obsolete", "colorEditBg", false, false, false, false, false, false, "string", null, null, null, "editBg", null, "(Obsolete) - Edit Background Color"]
            }, {
                "prop": ["Obsolete", "colorFrameBg", false, false, false, false, false, false, "string", null, null, null, "frameBg", null, "(Obsolete) - Frame Background Color"]
            }, {
                "prop": ["Obsolete", "colorFrameFg", false, false, false, false, false, false, "string", null, null, null, "frameFg", null, "(Obsolete) - Frame Foreground Color"]
            }, {
                "prop": ["Obsolete", "colorStdBg", false, false, false, false, false, false, "string", null, null, null, "bg", null, "(Obsolete) - Standard Background Color"]
            }, {
                "prop": ["Obsolete", "colorStdFg", false, false, false, false, false, false, "string", null, null, null, "fg", null, "(Obsolete) - Standard Foreground Color"]
            }, {
                "prop": ["Obsolete", "colorScrollSelectActive", false, false, false, false, false, false, "string", null, null, "#0000FF", null, null, "(Obsolete) - Color of scrolling selector border on active record"]
            }, {
                "prop": ["Obsolete", "colorScrollSelectOther", false, false, false, false, false, false, "string", null, null, "#FF0000", null, null, "(Obsolete) - Color of scrolling selector border on other records"]
            }, {
                "prop": ["Obsolete", "colorWindowBg", false, false, false, false, false, false, "string", GUILookList, null, null, "windowBg", null, "(Obsolete) - Window Background Color"]
            }
        ];
    for (var opn = 0; opn < options.length; opn++) {
	appx_session.options[options[opn].prop[PROP_NAME]] = options[opn];
    }
    if (localStorage["appx_options"]){
	var storedOptions = JSON.parse(localStorage["appx_options"]);
	for (var key in storedOptions){
	    if (storedOptions[key].prop[PROP_SECTION] == "Constants"){
		storedOptions[key].prop[PROP_VALUE] = null;
	    }
	    for (var key1 in appx_session.options){
		if (appx_session.options[key1].prop[PROP_NAME] == storedOptions[key].prop[PROP_NAME]){
		    appx_session.options[key1].prop[PROP_VALUE] = storedOptions[key].prop[PROP_VALUE];
		}
	    }
	}
    }
    localStorage["appx_options"] = JSON.stringify(appx_session.options);
};

appx_session.clearCache = function () {
    localStorage.clear();
    localStorage["appx_ls_version"] = "1";
    window.location.reload()
}

appx_session.showPreferences = function (atlogin) {
    var d = $("<div id='appx_prefs'>").css({
            "background": "rgba(50, 50, 50, 0.7)",
            "width": "100%",
            "height": "100%",
            "min-height": "400px",
            "z-index": 10000000,
            "display": "none",
            "position": "absolute",
            "top": "0px",
            "left": "0px",
            "font-family": "verdana",
            "font-size": "11px"
        })
        .appendTo("body");

    var prefwrap = $("<div style='border: 10px solid #333;'>").css({
            "width": "950px",
            "height": "430px",
            "background": "#fff"
        }).appendTo("#appx_prefs")
        .position({
            my: "center",
            at: "center",
            of: window
        }).draggable();

    var prefsdiv = $("<div>").css({
        "width": "950px",
        "height": "400px",
        "overflow": "scroll"
    });

    var closer = $("<button type='button' style='float:right;border:none;;background: #333;text-align:right;padding: 5px;color: #F5F539; font-weight:bold;padding-bottom: 10px;'>")
    .append($("<span>close(X)</span>"))
		.click(function () {
                $("#appx_prefs").hide();
                $("#appx_prefs").remove();
		    });

    var prefs = sortAppxOptions(atlogin);
    $(prefwrap).prepend($("<div>").append(closer));
    $(prefsdiv).append($("<div>").append(prefs));
    $(prefsdiv).appendTo(prefwrap);
    $("#appx_prefs").show();
    $(prefs).find("input").change(function () {
        appx_session.setProp($(this).attr("id"), $(this).val());
        if (appx_session.getRawProp($(this).attr("id")) != null)
            $(this).css({
                "background": "#ff0"
            });
        else
            $(this).css({
                "background": "#fff"
            });
    });
}

function sortAppxOptions(atlogin) {
    appxSortedOptions = {};
    appxSortedOptionsArray = [];
    $.each(appx_session.options, function (k, v) {
        if (v.prop[PROP_HIDDEN].toString().trim() == "false") {
            if (v.prop[PROP_NAME].toString().indexOf("[") > -1) {
                appxSortedOptions[v.prop[PROP_SECTION]] = {};
                appxSortedOptions[v.prop[PROP_SECTION]].items = [];
                appxSortedOptions[v.prop[PROP_SECTION]].header = v;
            }
            else {
                if (appxSortedOptions[v.prop[PROP_SECTION]]) {
                    appxSortedOptions[v.prop[PROP_SECTION]].items.push(v);
                }
            }
        }
    });

    $.each(appxSortedOptions, function (k, v) {
        appxSortedOptions[k].items.sort(function (a, b) {
            if (a.prop[PROP_NAME] < b.prop[PROP_NAME]) return -1;
            if (a.prop[PROP_NAME] > b.prop[PROP_NAME]) return 1;
            return 0;
        });
        appxSortedOptionsArray.push(k);
    });
    appxSortedOptionsArray.sort();

    var prefs = $("<table border='1' cellspacing='0' cellpadding='10'>");
    $(prefs).append("<tr style='padding: 3px;color: #fff;font-weight: bold;background: #678'>" + "<td>Option</td>" + "<td>Value</td>" + "<td>Default Value</td>" + "<td>Description</td>" + "</tr>");
    for (var i = 0; i < appxSortedOptionsArray.length; i++) {
        var v = appxSortedOptions[appxSortedOptionsArray[i]];
        $(prefs).append("<tr style='padding: 3px; background: #5C90DD; color: #fff; font-weight: bold; font-size: 1.2em'>" + "<td>" + v.header.prop[PROP_NAME] + "</td>" +
            " <td></td>" + "<td></td>" + "<td></td>" + "</tr>");
        for (var j = 0; j < v.items.length; j++) {
            var prop10;
            var hasChanged = false;
            if (v.items[j].prop[PROP_SECTION] != "Constants" && v.items[j].prop[PROP_VALUE] != null && v.items[j].prop[PROP_VALUE] != v.items[j].prop[PROP_DEFAULT]) {
                hasChanged = true;
            }
            if (v.items[j].prop[PROP_SECTION] != "Constants" && (v.items[j].prop[PROP_EDIT_AT_RT] || atlogin == true)) {
                prop10 = "<input style='background:" + (hasChanged ? "#ff0" : "#fff") + "' id='" + v.items[j].prop[PROP_NAME] + "' type='text' value='" + (v.items[j].prop[PROP_VALUE] == null ? v.items[j].prop[PROP_DEFAULT] : v.items[j].prop[PROP_VALUE]) + "' />";
            }
            else {
                prop10 = "<span style='background:" + (hasChanged ? "#ff0" : "#fff") + "'>" + (v.items[j].prop[PROP_VALUE] == null ? (v.items[j].prop[PROP_DEFAULT] == null ? "" : v.items[j].prop[PROP_DEFAULT]) : v.items[j].prop[PROP_VALUE]) + "</span>";
            }
            $(prefs).append("<tr style='padding: 3px;'>" + "<td>" + v.items[j].prop[PROP_NAME] + "</td>" + "<td class='editable-prop'>" + prop10 + "</td>" + "<td>" + (v.items[j].prop[PROP_DEFAULT] == null ? "" : v.items[j].prop[PROP_DEFAULT]) + "</td>" + "<td>" + (v.items[j].prop[PROP_DESC] == null ? "" : v.items[j].prop[PROP_DESC]) + "</td>" + "</tr>");
        }
    }
    return $(prefs);
}

appx_session.loadOptions();

appx_session.setProp("clientServerVersionStr", appxServerClientVersionStr);
appx_session.setProp("clientServerVersionNum", appxServerClientVersionNum);
appx_session.setProp("serverConnectorVersionStr", appx_session.serverConnectorVersionStr);
appx_session.setProp("serverConnectorVersionNum", appx_session.serverConnectorVersionNum);

$("#client_version").text(appxServerClientVersionStr);
$("#appx_access").prop('title', "Client Version: " + appxServerClientVersionStr); // <-- does not support HTML tags in tooltip

//try local first to keep IE happy
// creates a global LOCAL OS Session object
// NOTE: this object is destroyed on refresh, may need a work-around to prevent user to accidentally restarting a session
try {
    localos_session = new LOCALOS();
}
catch (ex) {
    console.log("LOCALOS: " + ex.message);
    console.log(ex.stack);
}

if (appxLoginAutoConnect)
    start_session();
