$.ajaxSetup({
    crossDomain: true,
    error: function (event, jqxhr, settings, exception) {
        Dashboard.hideLoadingMsg();
        if (!Dashboard.suppressAjaxErrors) {
            setTimeout(function () {
                var msg = event.getResponseHeader("X-Application-Error-Code") || Dashboard.defaultErrorMessage;
                Dashboard.showError(msg);
            }, 500);
        }
    }
});
$.support.cors = true;
$(document).one('click', WebNotifications.requestPermission);
var Dashboard = {
    jQueryMobileInit: function () {
        //$.mobile.defaultPageTransition = 'slide';
        // Page
        //$.mobile.page.prototype.options.theme = "a";
        //$.mobile.page.prototype.options.headerTheme = "a";
        //$.mobile.page.prototype.options.contentTheme = "a";
        //$.mobile.page.prototype.options.footerTheme = "a";
        //$.mobile.button.prototype.options.theme = "c";
        $.mobile.listview.prototype.options.dividerTheme = "b";
        $.mobile.popup.prototype.options.theme = "c";
        //$.mobile.collapsible.prototype.options.contentTheme = "a";
    },
    getCurrentUser: function () {
        if (!Dashboard.getUserPromise) {
            Dashboard.getUserPromise = ApiClient.getUser(Dashboard.getCurrentUserId()).fail(Dashboard.logout);
        }
        return Dashboard.getUserPromise;
    },
    validateCurrentUser: function () {
        Dashboard.getUserPromise = null;
        if (Dashboard.getCurrentUserId()) {
            Dashboard.getCurrentUser();
        }
        var header = $('.header', $.mobile.activePage);
        
        if (header.length) {
            // Re-render the header
            header.remove();
            Dashboard.ensureHeader($.mobile.activePage);
        }
    },
    getCurrentUserId: function () {
        var userId = localStorage.getItem("userId");
        if (!userId) {
            var autoLoginUserId = getParameterByName('u');
            if (autoLoginUserId) {
                userId = autoLoginUserId;
                localStorage.setItem("userId", userId);
            }
        }
        return userId;
    },
    setCurrentUser: function (userId) {
        localStorage.setItem("userId", userId);
        ApiClient.currentUserId(userId);
        Dashboard.getUserPromise = null;
    },
    logout: function () {
        localStorage.removeItem("userId");
        Dashboard.getUserPromise = null;
        ApiClient.currentUserId(null);
        window.location = "login.html";
    },
    showError: function (message) {
        $.mobile.loading('show', {
            theme: "e",
            text: message,
            textonly: true,
            textVisible: true
        });
        setTimeout(function () {
            $.mobile.loading('hide');
        }, 2000);
    },
    alert: function (message) {
        $.mobile.loading('show', {
            theme: "e",
            text: message,
            textonly: true,
            textVisible: true
        });
        setTimeout(function () {
            $.mobile.loading('hide');
        }, 2000);
    },
    updateSystemInfo: function (info) {
        var isFirstLoad = !Dashboard.lastSystemInfo;
        Dashboard.lastSystemInfo = info;
        Dashboard.ensureWebSocket(info);
        if (!Dashboard.initialServerVersion) {
            Dashboard.initialServerVersion = info.Version;
        }
        if (info.HasPendingRestart) {
            Dashboard.hideDashboardVersionWarning();
            Dashboard.showServerRestartWarning();
        } else {
            Dashboard.hideServerRestartWarning();
            if (Dashboard.initialServerVersion != info.Version) {
                Dashboard.showDashboardVersionWarning();
            }
        }
        if (isFirstLoad) {
            Dashboard.showFailedAssemblies(info.FailedPluginAssemblies);
        }
        Dashboard.showInProgressInstallations(info.InProgressInstallations);
    },
    showFailedAssemblies: function (failedAssemblies) {
        for (var i = 0, length = failedAssemblies.length; i < length; i++) {
            var assembly = failedAssemblies[i];
            var html = '
';
            var index = assembly.lastIndexOf('\\');
            if (index != -1) {
                assembly = assembly.substring(index + 1);
            }
            html += '';
            html += assembly + " failed to load.";
            html += '';
            Dashboard.showFooterNotification({ html: html });
        }
    },
    showInProgressInstallations: function (installations) {
        installations = installations || [];
        for (var i = 0, length = installations.length; i < length; i++) {
            var installation = installations[i];
            var percent = installation.PercentComplete || 0;
            if (percent < 100) {
                Dashboard.showPackageInstallNotification(installation, "progress");
            }
        }
        if (installations.length) {
            Dashboard.ensureInstallRefreshInterval();
        } else {
            Dashboard.stopInstallRefreshInterval();
        }
    },
    ensureInstallRefreshInterval: function () {
        if (!Dashboard.installRefreshInterval) {
            if (Dashboard.isWebSocketOpen()) {
                Dashboard.sendWebSocketMessage("SystemInfoStart", "0,350");
            }
            Dashboard.installRefreshInterval = 1;
        }
    },
    stopInstallRefreshInterval: function () {
        if (Dashboard.installRefreshInterval) {
            if (Dashboard.isWebSocketOpen()) {
                Dashboard.sendWebSocketMessage("SystemInfoStop");
            }
            Dashboard.installRefreshInterval = null;
        }
    },
    cancelInstallation: function (id) {
        ApiClient.cancelPackageInstallation(id).always(Dashboard.refreshSystemInfoFromServer);
    },
    showServerRestartWarning: function () {
        var html = 'Please restart Media Browser Server to finish updating.';
        html += '';
        Dashboard.showFooterNotification({ id: "serverRestartWarning", html: html, forceShow: true, allowHide: false });
    },
    hideServerRestartWarning: function () {
        $('#serverRestartWarning').remove();
    },
    showDashboardVersionWarning: function () {
        var html = 'Please refresh this page to receive new updates from the server.';
        html += '';
        Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false });
    },
    reloadPage: function () {
        window.location.href = window.location.href;
    },
    hideDashboardVersionWarning: function () {
        $('#dashboardVersionWarning').remove();
    },
    showFooterNotification: function (options) {
        var removeOnHide = !options.id;
        options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random());
        var parentElem = $('#footerNotifications');
        var elem = $('#' + options.id, parentElem);
        if (!elem.length) {
            elem = $('
';
            var imageUrl = user.PrimaryImageTag ? ApiClient.getUserImageUrl(user.Id, {
                height: 400,
                tag: user.PrimaryImageTag,
                type: "Primary"
            }) : "css/images/userFlyoutDefault.png";
            html += '';
            html += '
';
        }
        else if (isLibraryPage) {
            headerHtml += '
';
        }
        headerHtml += '';
        var imageColor = isLibraryPage ? "White" : "Black";
        if (user && !page.hasClass('wizardPage')) {
            headerHtml += '
';
            }
            headerHtml += '';
            if (user.Configuration.IsAdministrator) {
                headerHtml += '
';
            }
            headerHtml += '
').insertBefore('.btnTools', page);
            }
        });
    },
    ensureToolsMenu: function (page) {
        if (!page.hasClass('type-interior')) {
            return;
        }
        var sidebar = $('.toolsSidebar', page);
        if (!sidebar.length) {
            var html = '';
            $(page).append(html);
        }
    },
    getToolsMenuLinks: function (page) {
        var pageElem = page[0];
        return [{
            name: "Dashboard",
            href: "dashboard.html",
            selected: pageElem.id == "dashboardPage"
        }, {
            name: "Media Library",
            href: "library.html",
            selected: pageElem.id == "mediaLibraryPage"
        }, {
            name: "Metadata",
            href: "metadata.html",
            selected: pageElem.id == "metadataConfigurationPage" || pageElem.id == "advancedMetadataConfigurationPage" || pageElem.id == "metadataImagesConfigurationPage"
        }, {
            name: "Plugins",
            href: "plugins.html",
            selected: page.hasClass("pluginConfigurationPage")
        }, {
            name: "User Profiles",
            href: "userProfiles.html",
            selected: page.hasClass("userProfilesConfigurationPage")
        }, {
            name: "Display Settings",
            href: "uiSettings.html",
            selected: pageElem.id == "displaySettingsPage"
        }, {
            name: "Advanced",
            href: "advanced.html",
            selected: pageElem.id == "advancedConfigurationPage"
        }, {
            name: "Scheduled Tasks",
            href: "scheduledTasks.html",
            selected: pageElem.id == "scheduledTasksPage" || pageElem.id == "scheduledTaskPage"
        }, {
            name: "Help",
            href: "support.html",
            selected: pageElem.id == "supportPage" || pageElem.id == "logPage" || pageElem.id == "supporterPage" || pageElem.id == "supporterKeyPage" || pageElem.id == "aboutPage"
        }];
    },
    ensureWebSocket: function (systemInfo) {
        if (!("WebSocket" in window)) {
            // Not supported by the browser
            return;
        }
        if (Dashboard.webSocket) {
            if (Dashboard.webSocket.readyState === WebSocket.OPEN || Dashboard.webSocket.readyState === WebSocket.CONNECTING) {
                return;
            }
        }
        systemInfo = systemInfo || Dashboard.lastSystemInfo;
        var url = "ws://" + ApiClient.serverHostName() + ":" + systemInfo.WebSocketPortNumber + "/mediabrowser";
        var ws = new WebSocket(url);
        ws.onmessage = Dashboard.onWebSocketMessage;
        ws.onopen = function () {
            setTimeout(function () {
                $(document).trigger("websocketopen");
            }, 500);
        };
        ws.onerror = function () {
            setTimeout(function () {
                $(document).trigger("websocketerror");
            }, 0);
        };
        ws.onclose = function () {
            setTimeout(function () {
                $(document).trigger("websocketclose");
            }, 0);
        };
        Dashboard.webSocket = ws;
    },
    resetWebSocketPingInterval: function () {
        if (Dashboard.pingWebSocketInterval) {
            clearInterval(Dashboard.pingWebSocketInterval);
            Dashboard.pingWebSocketInterval = null;
        }
        Dashboard.pingWebSocketInterval = setInterval(Dashboard.pingWebSocket, 30000);
    },
    pingWebSocket: function () {
        // Send a ping to the server every so often to try and keep the connection alive
        if (Dashboard.isWebSocketOpen()) {
            Dashboard.sendWebSocketMessage("ping");
        }
    },
    onWebSocketMessage: function (msg) {
        msg = JSON.parse(msg.data);
        if (msg.MessageType === "LibraryChanged") {
            Dashboard.processLibraryUpdateNotification(msg.Data);
        }
        else if (msg.MessageType === "UserDeleted") {
            Dashboard.validateCurrentUser();
        }
        else if (msg.MessageType === "SystemInfo") {
            Dashboard.updateSystemInfo(msg.Data);
        }
        else if (msg.MessageType === "HasPendingRestartChanged") {
            Dashboard.updateSystemInfo(msg.Data);
        }
        else if (msg.MessageType === "UserUpdated") {
            Dashboard.validateCurrentUser();
            var user = msg.Data;
            if (user.Id == Dashboard.getCurrentUserId()) {
                $('.currentUsername').html(user.Name);
            }
        }
        else if (msg.MessageType === "PackageInstallationCompleted") {
            Dashboard.showPackageInstallNotification(msg.Data, "completed");
            Dashboard.refreshSystemInfoFromServer();
        }
        else if (msg.MessageType === "PackageInstallationFailed") {
            Dashboard.showPackageInstallNotification(msg.Data, "failed");
            Dashboard.refreshSystemInfoFromServer();
        }
        else if (msg.MessageType === "PackageInstallationCancelled") {
            Dashboard.showPackageInstallNotification(msg.Data, "cancelled");
            Dashboard.refreshSystemInfoFromServer();
        }
        else if (msg.MessageType === "PackageInstalling") {
            Dashboard.showPackageInstallNotification(msg.Data, "progress");
            Dashboard.refreshSystemInfoFromServer();
        }
        else if (msg.MessageType === "ScheduledTaskEndExecute") {
            Dashboard.showTaskCompletionNotification(msg.Data);
        }
        $(document).trigger("websocketmessage", [msg]);
    },
    sendWebSocketMessage: function (name, data) {
        var msg = { MessageType: name };
        if (data) {
            msg.Data = data;
        }
        msg = JSON.stringify(msg);
        Dashboard.webSocket.send(msg);
    },
    isWebSocketOpen: function () {
        return Dashboard.webSocket && Dashboard.webSocket.readyState === WebSocket.OPEN;
    },
    showTaskCompletionNotification: function (result) {
        var html = '';
        if (result.Status == "Completed") {
            html += '
';
            return;
        }
        else if (result.Status == "Cancelled") {
            html += '
';
            return;
        }
        else {
            html += '
';
        }
        html += '';
        html += result.Name + " " + result.Status;
        html += '';
        var timeout = 0;
        if (result.Status == 'Cancelled') {
            timeout = 2000;
        }
        Dashboard.showFooterNotification({ html: html, id: result.Id, forceShow: true, timeout: timeout });
    },
    showPackageInstallNotification: function (installation, status) {
        var html = '';
        if (status == 'completed') {
            html += '
';
        }
        else if (status == 'cancelled') {
            html += '
';
        }
        else if (status == 'failed') {
            html += '
';
        }
        else if (status == 'progress') {
            html += '
';
        }
        html += '';
        if (status == 'completed') {
            html += installation.Name + ' ' + installation.Version + ' installation completed';
        }
        else if (status == 'cancelled') {
            html += installation.Name + ' ' + installation.Version + ' installation was cancelled';
        }
        else if (status == 'failed') {
            html += installation.Name + ' ' + installation.Version + ' installation failed';
        }
        else if (status == 'progress') {
            html += 'Installing ' + installation.Name + ' ' + installation.Version;
        }
        html += '';
        if (status == 'progress') {
            var percentComplete = Math.round(installation.PercentComplete || 0);
            html += '';
            if (percentComplete < 100) {
                var btnId = "btnCancel" + installation.Id;
                html += '';
            }
        }
        var timeout = 0;
        if (status == 'cancelled') {
            timeout = 2000;
        }
        var forceShow = status != "progress";
        var allowHide = status != "progress" && status != 'cancelled';
        Dashboard.showFooterNotification({ html: html, id: installation.Id, timeout: timeout, forceShow: forceShow, allowHide: allowHide });
    },
    processLibraryUpdateNotification: function (data) {
        var newItems = data.ItemsAdded.filter(function (a) {
            return !a.IsFolder;
        });
        if (!Dashboard.newItems) {
            Dashboard.newItems = [];
        }
        for (var i = 0, length = newItems.length ; i < length; i++) {
            Dashboard.newItems.push(newItems[i]);
        }
        if (Dashboard.newItemTimeout) {
            clearTimeout(Dashboard.newItemTimeout);
        }
        Dashboard.newItemTimeout = setTimeout(Dashboard.onNewItemTimerStopped, 60000);
    },
    onNewItemTimerStopped: function () {
        var newItems = Dashboard.newItems;
        newItems = newItems.sort(function (a, b) {
            if (a.PrimaryImageTag && b.PrimaryImageTag) {
                return 0;
            }
            if (a.PrimaryImageTag) {
                return -1;
            }
            return 1;
        });
        Dashboard.newItems = [];
        Dashboard.newItemTimeout = null;
        // Show at most 3 notifications
        for (var i = 0, length = Math.min(newItems.length, 3) ; i < length; i++) {
            var item = newItems[i];
            var data = {
                title: "New " + item.Type,
                body: item.Name,
                timeout: 6000
            };
            if (item.PrimaryImageTag) {
                data.icon = ApiClient.getImageUrl(item.Id, {
                    width: 100,
                    tag: item.PrimaryImageTag,
                    type: "Primary"
                });
                
                if (!item.Id || data.icon.indexOf("undefined") != -1) {
                    alert("bad image url: " + JSON.stringify(item));
                    console.log("bad image url: " + JSON.stringify(item));
                    continue;
                }
            }
            WebNotifications.show(data);
        }
    },
    ensurePageTitle: function (page) {
        if (!page.hasClass('type-interior')) {
            return;
        }
        var pageElem = page[0];
        if (pageElem.hasPageTitle) {
            return;
        }
        var parent = $('.content-primary', page);
        if (!parent.length) {
            parent = $('.ui-content', page)[0];
        }
        $(parent).prepend("