{#
/**
 * Copyright (C) 2023 Xibo Signage Ltd
 *
 * Xibo - Digital Signage - http://www.xibo.org.uk
 *
 * This file is part of Xibo.
 *
 * Xibo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * Xibo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Xibo.  If not, see <http://www.gnu.org/licenses/>.
 */
#}
{% extends "authed.twig" %}
{% import "inline.twig" as inline %}

{% block title %}{{ "Displays"|trans }} | {% endblock %}

{% block actionMenu %}
    <div class="widget-action-menu pull-right">
        {% if currentUser.featureEnabled("displays.add") %}
        <button class="btn btn-success XiboFormButton" title="{% trans "Add a Display via user_code displayed on the Player screen" %}" href="{{ url_for("display.addViaCode.form") }}"> <i class="fa fa-plus-circle" aria-hidden="true"></i> {% trans "Add Display (Code)" %}</button>
        {% endif %}
        <button class="btn btn-primary" id="refreshGrid" title="{% trans "Refresh the Table" %}" href="#"><i class="fa fa-refresh" aria-hidden="true"></i> {% trans "Refresh" %}</button>
    </div>
{% endblock %}

{% block pageContent %}
    <div class="widget">
        <div class="widget-title">{% trans "Displays" %}</div>
        <div class="widget-body">
            <div class="XiboGrid" id="{{ random() }}" data-grid-name="displayView">
                <div class="XiboFilter card mb-3 bg-light">
                    <div class="FilterDiv card-body" id="Filter">
                        <ul class="nav nav-tabs" role="tablist">
                            <li class="nav-item"><a class="nav-link active" href="#filter-general" role="tab" data-toggle="tab">{% trans "General" %}</a></li>
                            <li class="nav-item"><a class="nav-link" href="#filter-advanced" role="tab" data-toggle="tab">{% trans "Advanced" %}</a></li>
                        </ul>
                        <form class="form-inline">
                            <div class="tab-content">
                                <div class="tab-pane active" id="filter-general">
                                    {% set title %}{% trans "ID" %}{% endset %}
                                    {{ inline.number("displayId", title) }}

                                    {% set title %}{% trans "Name" %}{% endset %}
                                    {{ inline.inputNameGrid('display', title) }}

                                    {% set title %}{% trans "Status" %}{% endset %}
                                    {% set check %}{% trans "Up to date" %}{% endset %}
                                    {% set cross %}{% trans "Downloading" %}{% endset %}
                                    {% set cloud %}{% trans "Out of date" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: "1", option: check},
                                        { optionid: "2", option: cross},
                                        { optionid: "3", option: cloud}
                                    ] %}
                                    {{ inline.dropdown("mediaInventoryStatus", "single", title, "", options, "optionid", "option") }}

                                    {% set title %}{% trans "Logged In?" %}{% endset %}
                                    {% set yesOption %}{% trans "Yes" %}{% endset %}
                                    {% set noOption %}{% trans "No" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: "1", option: yesOption},
                                        { optionid: "0", option: noOption}
                                    ] %}
                                    {{ inline.dropdown("loggedIn", "single", title, "", options, "optionid", "option") }}

                                    {% set title %}{% trans "Authorised?" %}{% endset %}
                                    {% set yesOption %}{% trans "Yes" %}{% endset %}
                                    {% set noOption %}{% trans "No" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: "1", option: yesOption },
                                        { optionid: "0", option: noOption},
                                    ] %}
                                    {{ inline.dropdown("authorised", "single", title, "", options, "optionid", "option") }}

                                    {% set title %}{% trans "XMR Registered?" %}{% endset %}
                                    {% set yesOption %}{% trans "Yes" %}{% endset %}
                                    {% set noOption %}{% trans "No" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: 1, option: yesOption},
                                        { optionid: 0, option: noOption},
                                    ] %}
                                    {{ inline.dropdown("xmrRegistered", "single", title, "", options, "optionid", "option") }}

                                    {% if currentUser.featureEnabled("tag.tagging") %}
                                        {% set title %}{% trans "Tags" %}{% endset %}
                                        {% set exactTagTitle %}{% trans "Exact match?" %}{% endset %}
                                        {% set logicalOperatorTitle %}{% trans "When filtering by multiple Tags, which logical operator should be used?" %}{% endset %}
                                        {% set helpText %}{% trans "A comma separated list of tags to filter by. Enter a tag|tag value to filter tags with values. Enter --no-tag to filter all items without tags. Enter - before a tag or tag value to exclude from results." %}{% endset %}
                                        {{ inline.inputWithTags("tags", title, null, helpText, null, null, null, "exactTags", exactTagTitle, logicalOperatorTitle) }}
                                    {% endif %}

                                    {% if currentUser.featureEnabled("displaygroup.view") %}
                                        {% set title %}{% trans "Display Group" %}{% endset %}
                                        {% set attributes = [
                                            { name: "data-width", value: "200px" },
                                            { name: "data-allow-clear", value: "true" },
                                            { name: "data-placeholder--id", value: null },
                                            { name: "data-placeholder--value", value: "" },
                                            { name: "data-search-url", value:  url_for("displayGroup.search") },
                                            { name: "data-filter-options", value: '{"isDisplaySpecific":0}' },
                                            { name: "data-search-term", value: "displayGroup" },
                                            { name: "data-id-property", value: "displayGroupId" },
                                            { name: "data-text-property", value: "displayGroup" },
                                            { name: "data-initial-key", value: "displayGroupId" },
                                        ] %}
                                        {{ inline.dropdown("displayGroupId", "single", title, "", null, "displayGroupId", "displayGroup", helpText, "pagedSelect", "", "", "", attributes) }}
                                    {% endif %}

                                    {% if currentUser.featureEnabled("displayprofile.view") %}
                                        {% set title %}{% trans "Display Profile" %}{% endset %}
                                        {{ inline.dropdown("displayProfileId", "single", title, "", [{displayProfileId:null, name:""}]|merge(displayProfiles), "displayProfileId", "name") }}
                                    {% endif %}

                                    {{ inline.hidden("folderId") }}
                                </div>

                                <div class="tab-pane" id="filter-advanced">
                                    {% set title %}{% trans "Last Accessed" %}{% endset %}
                                    {{ inline.date("lastAccessed", title) }}

                                    {% set title %}{% trans "Player Type" %}{% endset %}
                                    {% set android %}{% trans "Android" %}{% endset %}
                                    {% set windows %}{% trans "Windows" %}{% endset %}
                                    {% set webos %}{% trans "webOS" %}{% endset %}
                                    {% set sssp %}{% trans "Tizen" %}{% endset %}
                                    {% set linux %}{% trans "Linux" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: "android", option: android},
                                        { optionid: "windows", option: windows},
                                        { optionid: "lg", option: webos},
                                        { optionid: "sssp", option: sssp},
                                        { optionid: "linux", option: linux},
                                    ] %}
                                    {{ inline.dropdown("clientType", "single", title, "", options, "optionid", "option") }}

                                    {% set title %}{% trans "Player Code" %}{% endset %}
                                    {{ inline.input("clientCode", title) }}

                                    {% set title %}{% trans "Custom ID" %}{% endset %}
                                    {{ inline.input("customId", title) }}

                                    {% set title %}{% trans "Mac Address" %}{% endset %}
                                    {{ inline.input("macAddress", title) }}

                                    {% set title %}{% trans "IP Address" %}{% endset %}
                                    {{ inline.input("clientAddress", title) }}

                                    {% set title %}{% trans "Orientation" %}{% endset %}
                                    {% set landscape %}{% trans "Landscape" %}{% endset %}
                                    {% set portrait %}{% trans "Portrait" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: "landscape", option: landscape},
                                        { optionid: "portrait", option: portrait}
                                    ] %}
                                    {{ inline.dropdown("orientation", "single", title, "", options, "optionid", "option") }}

                                    {% set title %}{% trans "Commercial Licence" %}{% endset %}
                                    {% set licensed %}{% trans "Licensed fully" %}{% endset %}
                                    {% set trial %}{% trans "Trial" %}{% endset %}
                                    {% set notLinceced %}{% trans "Not licenced" %}{% endset %}
                                    {% set notApplicable %}{% trans "Not applicable" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: "1", option: licensed},
                                        { optionid: "2", option: trial},
                                        { optionid: "0", option: notLinceced},
                                        { optionid: "3", option: notApplicable}
                                    ] %}
                                    {{ inline.dropdown("commercialLicence", "single", title, "", options, "optionid", "option") }}

                                    {% set title %}{% trans "Player supported?" %}{% endset %}
                                    {% set yesOption %}{% trans "Yes" %}{% endset %}
                                    {% set noOption %}{% trans "No" %}{% endset %}
                                    {% set options = [
                                        { optionid: "", option: "" },
                                        { optionid: 1, option: yesOption},
                                        { optionid: 0, option: noOption},
                                    ] %}
                                    {{ inline.dropdown("isPlayerSupported", "single", title, "", options, "optionid", "option") }}
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
                <div class="row">
                    <div class="col-sm-2 grid-folder-tree-container" id="grid-folder-filter">
                        <div class="p-3 mr-2">
                            <input id="jstree-search" class="form-control" type="text" placeholder="{% trans "Search" %}">
                            <div class="form-check">
                                <input type="checkbox" class="form-check-input" id="folder-tree-clear-selection-button">
                                <label class="form-check-label" for="folder-tree-clear-selection-button" title="{% trans "Search in all folders" %}">{% trans "All Folders" %}</label>
                            </div>
                            <div class="folder-search-no-results d-none">
                                <p>{% trans 'No Folders matching the search term' %}</p>
                            </div>
                            <div id="container-folder-tree"></div>
                        </div>
                    </div>
                    <div class="folder-controller d-none">
                        <button type="button" id="folder-tree-select-folder-button" class="btn btn-outline-secondary" title="{{ "Open / Close Folder Search options"|trans }}"><i class="fas fa-folder fa-1x"></i></button>
                        <div id="breadcrumbs" class="mt-2 pl-2"></div>
                    </div>
                    <div class="map-controller d-none pl-1">
                        <button type="button" id="map_button" class="btn btn-primary" title="{{ "Map"|trans }}"><i class="fa fa-map"></i></button>
                    </div>
                    <div class="list-controller d-none pl-1">
                        <button type="button" id="list_button" class="btn btn-primary" title="{{ "List"|trans }}"><i class="fa fa-list"></i></button>
                    </div>

                    <div id="datatable-container" class="col-sm-10 pr-0">
                        <div class="XiboData card pt-4 px-2">
                            <table id="displays" class="table table-striped" data-content-type="display" data-content-id-name="displayId" data-state-preference-name="displayGrid" style="width: 100%;">
                                <thead>
                                    <tr>
                                        <th>{% trans "ID" %}</th>
                                        <th>{% trans "Display" %}</th>
                                        <th>{% trans "Display Type" %}</th>
                                        <th>{% trans "Address" %}</th>
                                        <th>{% trans "Status" %}</th>
                                        <th>{% trans "Authorised?" %}</th>
                                        <th>{% trans "Current Layout" %}</th>
                                        <th>{% trans "Storage Available" %}</th>
                                        <th>{% trans "Storage Total" %}</th>
                                        <th>{% trans "Storage Free %" %}</th>
                                        <th>{% trans "Description" %}</th>
                                        <th>{% trans "Orientation" %}</th>
                                        <th>{% trans "Resolution" %}</th>
                                        {% if currentUser.featureEnabled("tag.tagging") %}<th>{% trans "Tags" %}</th>{% endif %}
                                        <th>{% trans "Default Layout" %}</th>
                                        <th>{% trans "Interleave Default" %}</th>
                                        <th>{% trans "Email Alert" %}</th>
                                        <th>{% trans "Logged In" %}</th>
                                        <th>{% trans "Last Accessed" %}</th>
                                        <th>{% trans "Display Profile" %}</th>
                                        <th>{% trans "Version" %}</th>
                                        <th>{% trans "Supported?" %}</th>
                                        <th>{% trans "Device Name" %}</th>
                                        <th>{% trans "IP Address" %}</th>
                                        <th>{% trans "Mac Address" %}</th>
                                        <th>{% trans "Timezone" %}</th>
                                        <th>{% trans "Languages" %}</th>
                                        <th>{% trans "Latitude" %}</th>
                                        <th>{% trans "Longitude" %}</th>
                                        <th>{% trans "Screen shot?" %}</th>
                                        <th>{% trans "Thumbnail" %}</th>
                                        <th>{% trans "CMS Transfer?" %}</th>
                                        <th>{% trans "Bandwidth Limit" %}</th>
                                        <th>{% trans "Last Command" %}</th>
                                        <th>{% trans "XMR Registered" %}</th>
                                        <th>{% trans "Commercial Licence" %}</th>
                                        <th>{% trans "Remote" %}</th>
                                        <th>{% trans "Sharing" %}</th>
                                        <th>{% trans "Screen Size" %}</th>
                                        <th>{% trans "Is Mobile?" %}</th>
                                        <th>{% trans "Outdoor?" %}</th>
                                        <th>{% trans "Reference 1" %}</th>
                                        <th>{% trans "Reference 2" %}</th>
                                        <th>{% trans "Reference 3" %}</th>
                                        <th>{% trans "Reference 4" %}</th>
                                        <th>{% trans "Reference 5" %}</th>
                                        <th>{% trans "Custom ID" %}</th>
                                        <th>{% trans "Cost Per Play" %}</th>
                                        <th>{% trans "Impressions Per Play" %}</th>
                                        <th>{% trans "Created Date" %}</th>
                                        <th>{% trans "Modified Date" %}</th>
                                        <th>{% trans "Faults?" %}</th>
                                        <th class="rowMenu"></th>
                                    </tr>
                                </thead>
                                <tbody>

                                </tbody>
                            </table>

                            <!-- Map -->
                            <div class="row">
                                <div class="col-sm-12">
                                    <div class="map-legend" style="display:none; position: absolute; z-index: 500; right: 20px; top: 10px;">
                                        <div class="display-map-legend" style="font-size: 12px;">
                                            <div>Logged in</div>
                                            <div><img style="width: 15%" src='{{ theme.rootUri() }}dist/assets/map-marker-green-check.png'/> - Up to date</div>
                                            <div><img style="width: 15%" src='{{ theme.rootUri() }}dist/assets/map-marker-yellow-check.png'/> - Out of date</div>
                                            <div><img style="width: 15%" src='{{ theme.rootUri() }}dist/assets/map-marker-red-check.png'/> - Downloading/Unknown</div>
                                            </br>
                                            <div>Logged out</div>
                                            <div><img style="width: 15%" src='{{ theme.rootUri() }}dist/assets/map-marker-green-cross.png'/> - Up to date</div>
                                            <div><img style="width: 15%" src='{{ theme.rootUri() }}dist/assets/map-marker-yellow-cross.png'/> - Out of date</div>
                                            <div><img style="width: 15%" src='{{ theme.rootUri() }}dist/assets/map-marker-red-cross.png'/> - Downloading/Unknown</div>
                                        </div>
                                    </div>
                                    <div id="display-map" data-displays-url="{{ url_for("display.map") }}">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block javaScript %}
    <script type="text/javascript">
        var mapConfig = {{ mapConfig|json_encode|raw }};

        {% if not currentUser.featureEnabled("folder.view") %}
        disableFolders();
        {% endif %}

        $(document).ready(function() {

            //<editor-fold desc="Display Grid>

            const table = $("#displays").DataTable({
                language: dataTablesLanguage,
                dom: dataTablesTemplate,
                serverSide: true,
                stateSave: true,
                stateDuration: 0,
                responsive: true,
                stateLoadCallback: dataTableStateLoadCallback,
                stateSaveCallback: dataTableStateSaveCallback,
                filter: false,
                searchDelay: 3000,
                order: [[1, 'asc']],
                ajax: {
                    url: '{{ url_for("display.search") }}',
                    data: function (dataToSend) {
                        //make a new object so as not to destroy the input.
                        var data = {};
                        data.draw = dataToSend.draw;
                        data.length = dataToSend.length;
                        data.start = dataToSend.start;
                        data.order = dataToSend.order;
                        data.columns = [];

                        $.each(dataToSend.columns, function (index, e) {
                            var col = {};
                            col.data = e.data;
                            if (e.name != null && e.name != '')
                                col.name = e.name;
                            data.columns.push(col);
                        });

                        $.extend(data, $("#displays").closest(".XiboGrid").find(".FilterDiv form").serializeObject());

                        return data;
                    }
                },
                createdRow: function (row, data, index) {
                    if (data.mediaInventoryStatus === 1) {
                        $(row).addClass('table-success');
                    } else if (data.mediaInventoryStatus === 2) {
                        $(row).addClass('table-danger');
                    } else {
                        $(row).addClass('table-warning');
                    }
                },
                "columns": [
                    {"data": "displayId", responsivePriority: 2},
                    {"data": "display", responsivePriority: 2},
                    {"data": "displayType", responsivePriority: 2},
                    {"data": "address", "visible": false, responsivePriority: 5},
                    {
                        "data": "mediaInventoryStatus",
                        responsivePriority: 2,
                        "render": function (data, type, row) {
                            if (type != "display")
                                return data;

                            var icon = "";
                            if (data == 1)
                                icon = "fa-check";
                            else if (data == 2)
                                icon = "fa-times";
                            else
                                icon = "fa-cloud-download";

                            return '<span class="fa ' + icon + '" title="' + (row.statusDescription) + '"></span>';
                        }
                    },
                    {"data": "licensed", "render": dataTableTickCrossColumn, responsivePriority: 3},
                    {"data": "currentLayout", "visible": false, "sortable": false, responsivePriority: 5},
                    {
                        "data": "storageAvailableSpace",
                        responsivePriority: 5,
                        "visible": false,
                        "render": function (data, type, row) {
                            if (type != "display" && type != "export") {
                                return data;
                            }

                            return row.storageAvailableSpaceFormatted;
                        }
                    },
                    {
                        "data": "storageTotalSpace",
                        responsivePriority: 5,
                        "visible": false,
                        "render": function (data, type, row) {
                            if (type != "display" && type != "export") {
                                return data;
                            }

                            return row.storageTotalSpaceFormatted;
                        }
                    },
                    {"data": "storagePercentage", "visible": false, "sortable": false, responsivePriority: 5},
                    {"data": "description", "visible": false, responsivePriority: 4},
                    {"data": "orientation", "visible": false, responsivePriority: 6},
                    {"data": "resolution", "visible": false, responsivePriority: 6},
                    {% if currentUser.featureEnabled("tag.tagging") %}
                    {
                        "name": "tags",
                        responsivePriority: 3,
                        "sortable": false,
                        "visible": false,
                        "data": dataTableCreateTags
                    },
                    {% endif %}
                    {"data": "defaultLayout", "visible": false, responsivePriority: 4},
                    {"data": "incSchedule", "render": dataTableTickCrossColumn, "visible": false, responsivePriority: 5},
                    {"data": "emailAlert", "render": dataTableTickCrossColumn, "visible": false, responsivePriority: 5},
                    {"data": "loggedIn", "render": dataTableTickCrossColumn, responsivePriority: 3},
                    {"data": "lastAccessed", "render": dataTableDateFromUnix, responsivePriority: 4},
                    {
                        "name": "displayProfileId",
                        responsivePriority: 5,
                        "data": function (data, type) {
                            return data.displayProfile;
                        },
                        "visible": false
                    },
                    {
                        "name": "clientSort",
                        responsivePriority: 4,
                        "data": function (data) {
                            if (data.clientType === 'lg') {
                                data.clientType = 'webOS'
                            }

                            return data.clientType + ' ' + data.clientVersion + '-' + data.clientCode;
                        },
                        "visible": false
                    },
                    {
                      data: 'clientCode',
                      responsivePriority: 3,
                      render: function (data, type) {
                        const playerVersionSupport = {{ playerVersion }};
                        if (type !== 'display') {
                          return data < playerVersionSupport ? '{{ "No"|trans }}' : '{{ "Yes"|trans }}';
                        }
                        return "<span class='fa " + (data < playerVersionSupport ? 'fa-times' : 'fa-check') + "'></span>";
                      },
                      visible: false
                    },
                    {"data": "deviceName", "visible": false, responsivePriority: 5},
                    {"data": "clientAddress", "visible": false, responsivePriority: 6},
                    {"data": "macAddress", responsivePriority: 5},
                    {"data": "timeZone", "visible": false, responsivePriority: 5},
                    {
                        "data": "languages",
                        "visible": false,
                        "responsivePriority": 5,
                        "render": function(data, type) {
                            if (type !== "display")
                                return data;

                            let returnData = '';
                            if (typeof data !== undefined && data != null) {
                                let arrayOfTags = data.split(',');
                                returnData += '<div class="permissionsDiv">';
                                for (let i = 0; i < arrayOfTags.length; i++) {
                                    let name = arrayOfTags[i];
                                    if (name !== '') {
                                        returnData += '<li class="badge">'
                                            + name + '</span></li>'
                                    }
                                }
                                returnData += '</div>';
                            }
                            return returnData;
                        }
                    },
                    {"data": "latitude", "visible": false, responsivePriority: 6},
                    {"data": "longitude", "visible": false, responsivePriority: 6},
                    {"data": "screenShotRequested", "render": dataTableTickCrossColumn, "visible": false, "name": "screenShotRequested", responsivePriority: 7},
                    {
                        "name": "thumbnail",
                        responsivePriority: 4,
                        "orderable": false,
                        "data": function (data, type) {
                            if (type != "display")
                                return data.thumbnail;

                            if (data.thumbnail != "") {
                                return '<a class="display-screenshot-container" data-toggle="lightbox" data-type="image" href="' + data.thumbnail + '"><img class="display-screenshot" src="' + data.thumbnail + '" data-display-id="'+ data.displayId +'" data-type="'+ data.clientType +'" data-client-code="'+ data.clientCode +'" /></a>';
                            }
                            else {
                                return "";
                            }
                        },
                        "visible": false
                    },
                    {
                        "data": "isCmsTransferInProgress",
                        "render": dataTableTickCrossColumn,
                        "visible": false,
                        "name": "isCmsTransferInProgress"
                    },
                    {
                        "name": "bandwidthLimit",
                        responsivePriority: 5,
                        "data": null,
                        "render": {"_": "bandwidthLimit", "display": "bandwidthLimitFormatted", "sort": "bandwidthLimit"},
                        "visible": false
                    },
                    {
                        "data": "lastCommandSuccess",
                        responsivePriority: 6,
                        "render": function (data, type, row) {
                            if (type != "display")
                                return data;

                            var icon = "";
                            if (data == 1)
                                icon = "fa-check";
                            else if (data == 0)
                                icon = "fa-times";
                            else
                                icon = "fa-question";

                            return "<span class='fa " + icon + "'></span>";
                        },
                        "visible": false
                    },
                    {
                        "data": "xmrChannel",
                        responsivePriority: 6,
                        "render": function (data, type, row) {
                            if (type === "export") {
                                return (data !== null && data !== "") ? 1 : 0;
                            }

                            if (type != "display")
                                return data;

                            var icon = "";
                            if (data != null && data != "")
                                icon = "fa-check";
                            else
                                icon = "fa-times";

                            return "<span class='fa " + icon + "'></span>";
                        },
                        "visible": false
                    },
                    {
                        "data": "commercialLicence",
                        "name": "commercialLicence",
                        responsivePriority: 5,
                        "render": function (data, type, row) {
                            if (type != "display")
                                return data;

                            var icon = "";
                            if (data == 3) {
                                return "N/A";
                            } else {
                                if (data == 1) {
                                    icon = "fa-check";
                                } else if (data == 0) {
                                    icon = "fa-times";
                                } else if (data == 2) {
                                    icon = "fa-clock-o";
                                }

                                return '<span class="fa ' + icon + '" title="' + (row.commercialLicenceDescription) + '"></span>';
                            }
                        },
                        "visible": false
                    },
                    {
                        "name": "remote",
                        "data": null,
                        responsivePriority: 4,
                        "render": function (data, type, row) {
                            if (type === "display") {
                                var html = "<div class='remote-icons'>";
                                if ("{{ settings.SHOW_DISPLAY_AS_VNCLINK }}" !== "" && row.clientAddress != null && row.clientAddress !== "") {
                                    var link = "{{ settings.SHOW_DISPLAY_AS_VNCLINK }}".replace('%s', row.clientAddress);
                                    html += '<a href="' + link + '" title="{{ "VNC to this Display"|trans }}" target="{{ settings.SHOW_DISPLAY_AS_VNC_TGT }}">'
                                        + '<i class="fa fa-eye"></i></a>';
                                }

                                if (row.teamViewerLink !== "") {
                                    html += '<a href="' + row.teamViewerLink + '" title="{{ "TeamViewer to this Display"|trans }}" target="_blank">'
                                        + '<img src="{{ theme.rootUri() }}theme/default/img/remote_icons/teamviewer.png" alt="TeamViewer Icon"></a>';
                                }

                                if (row.webkeyLink !== "") {
                                    html += '<a href="' + row.webkeyLink + '" title="{{ "Webkey to this Display"|trans }}" target="_blank">'
                                        + '<img src="{{ theme.rootUri() }}theme/default/img/remote_icons/webkey.png" alt="Webkey Icon"></a>';
                                }

                                return html + "</div>";

                            } else if (type === "export") {
                                if (row.teamViewerLink !== "") {
                                    return "TeamViewer: " + row.teamViewerLink;
                                }
                                if (row.webkeyLink !== "") {
                                    return "Webkey: " + row.webkeyLink;
                                }
                                if (row.teamViewerLink === "" && row.webkeyLink === "") {
                                    return "";
                                }
                            } else {
                                return "";
                            }
                        },
                        "visible": true,
                        "orderable": false
                    },
                    {
                        "data": "groupsWithPermissions",
                        visible: false,
                        responsivePriority: 10,
                        "render": dataTableCreatePermissions
                    },
                    {"data": "screenSize", "visible": false, responsivePriority: 6},
                    {
                        "data": "isMobile",
                        "render": dataTableTickCrossColumn,
                        "visible": false,
                        "name": "isMobile"
                    },
                    {
                        "data": "isOutdoor",
                        "render": dataTableTickCrossColumn,
                        "visible": false,
                        "name": "isOutdoor"
                    },
                    {"data": "ref1", "visible": false, responsivePriority: 6},
                    {"data": "ref2", "visible": false, responsivePriority: 6},
                    {"data": "ref3", "visible": false, responsivePriority: 6},
                    {"data": "ref4", "visible": false, responsivePriority: 6},
                    {"data": "ref5", "visible": false, responsivePriority: 6},
                    {"data": "customId", "visible": false, responsivePriority: 6},
                    {"data": "costPerPlay", "visible": false, responsivePriority: 6},
                    {"data": "impressionsPerPlay", "visible": false, responsivePriority: 6},
                    {"data": "createdDt", "visible": false, responsivePriority: 6},
                    {"data": "modifiedDt", "visible": false, responsivePriority: 6},
                    {
                        "data": "countFaults",
                        "name": "countFaults",
                        responsivePriority: 3,
                        "render": function (data, type, row) {
                            if (row.clientCode < 300) {
                              return '';
                            }

                            if (type !== "display") {
                                return data;
                            }

                            if (data > 0) {
                                return '<span class="badge" style="background-color: red; color: white">'+(row.countFaults)+'</span>';
                            } else {
                                return '';
                            }
                        }
                    },
                    {
                        "orderable": false,
                        responsivePriority: 1,
                        "data": dataTableButtonsColumn
                    }
                ]
            });

            table.on('draw', function(e, settings) {

                dataTableDraw(e, settings, function() {

                    var target = $("#" + e.target.id);
                    var $mapController = target.closest(".XiboGrid").find('.map-controller');
                    var $listController = target.closest(".XiboGrid").find('.list-controller');

                    // Move and show map button inside of the table container
                    if ($mapController.length > 0 && target.closest(".dataTables_wrapper").find('.dataTables_folder .map-controller').length == 0) {
                        $mapController.appendTo('.dataTables_folder');
                        $mapController.removeClass('d-none').addClass('d-inline-flex');
                    }
                    // Move and show list button inside of the table container
                    if ($listController.length > 0 && target.closest(".dataTables_wrapper").find('.dataTables_folder .list-controller').length == 0) {
                        $listController.appendTo('.dataTables_folder');
                        $listController.removeClass('d-none').addClass('d-inline-flex');
                    }
                })
            });
            table.on('draw', { form: $("#displays").closest(".XiboGrid").find(".FilterDiv form") }, dataTableCreateTagEvents);
            table.on('processing.dt', dataTableProcessing);
            dataTableAddButtons(table, $('#displays_wrapper').find('.dataTables_buttons'));

            $("#refreshGrid").click(function () {
                table.ajax.reload();
            });

            // </editor-fold>

            //<editor-fold desc="The button click event displaying the map or grid>

            // Detect the dimensions of our container and set to match.
            let map;
            let displayIdCache = [];
            let markerClusterGroup;
            const $displayMap = $('#display-map');
            const $mapBtn = $('#map_button');
            const $listBtn =  $('#list_button');
            const $mapParent = $displayMap.parent();
            const $dataTablesFolder = $('.dataTables_folder');

            $listBtn.hide();

            $mapBtn.click(function () {
              if (!map) {
                initializeMap();
              } else {
                setTimeout(function () {
                  addMarkersToMap(map.getBounds().toBBoxString());
                }, 500);
              }
                $('.map-legend').show()
                $displayMap.show();
                $mapBtn.hide();
                $listBtn.show();
                $dataTablesFolder.siblings().hide();
                $dataTablesFolder.parent().siblings().hide();
            });

            $listBtn.click(function () {
                $('.map-legend').hide();
                $displayMap.hide();
                $listBtn.hide();
                $mapBtn.show();
                $dataTablesFolder.siblings().show();
                $dataTablesFolder.parent().siblings().show();
            });

            // </editor-fold>


            // <editor-fold desc="Leaflet Map>

            // Map resizing when folder is toggled
            window.refreshDisplayMap = function () {
                if (map) {
                    // is display map visible??
                    if ($displayMap.is(':visible')) {
                        map.invalidateSize();
                    } else {
                        map.setView(map.getCenter(), map.getZoom());
                    }
                }
            }

            // Initialise and build map
            function initializeMap() {

                $displayMap.width($mapParent.width() - 10);
                $displayMap.height($(window).height() - 100);

                // Create the map
                map = L.map('display-map', {
                    center: [mapConfig.setArea.lat, mapConfig.setArea.long],
                    zoom: mapConfig.setArea.zoom,
                    fullscreenControl: true,
                    fullscreenControlOptions: {
                        position: 'topleft'
                    }
                });

                // Tile layer
                let tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
                }).addTo(map);

                // Print button
                L.easyPrint({
                    tileLayer: tiles,
                    sizeModes: ['Current', 'A4Landscape', 'A4Portrait'],
                    filename: 'Displays on Map',
                    hideControlContainer: true
                }).addTo(map);

                // Create the marker cluster group
                markerClusterGroup = L.markerClusterGroup({
                    maxClusterRadius: function (mapZoom) {
                        return mapZoom > 9 ? 20 : 80;
                    },

                    // This defines the icon appearance of the cluster markers
                    iconCreateFunction: function (cluster) {
                        let upToDate = 0;
                        let outOfDate = 0;
                        let downloading = 0;

                        const children = cluster.getAllChildMarkers();
                        for (const marker of children) {
                            switch (marker.mediaInventoryStatus) {
                                case 1:
                                    upToDate++;
                                    break;
                                case 3:
                                    outOfDate++;
                                    break;
                                default:
                                    downloading++;
                                    break;
                            }
                        }

                        // Create a div showing number of displays by status in the cluster group
                        let pieHtml = createPieChart(
                            [upToDate, outOfDate, downloading],
                            ['rgba(181, 226, 140, 0.9)', 'rgba(243, 194, 18, 0.9)', 'rgba(219, 70, 79, 0.9)']
                        );

                        // Create custom icons for the cluster markers
                        return L.divIcon({
                            html:  pieHtml,
                            className: '',
                            iconSize: L.point(40, 40)
                        });
                    }
                });

                let bounds = map.getBounds().toBBoxString();

                map.on("moveend", _.debounce(function() {
                    bounds = map.getBounds().toBBoxString();
                    // is display map visible??
                    const isDisplayMapVisible = $displayMap.is(":visible");
                    addMarkersToMap(bounds, !isDisplayMapVisible);
                }, 500));

                map.on("resize", function() {
                    map.invalidateSize();
                });

                // Get display points and add to the map
                // Do not clear layers
                addMarkersToMap(bounds, false);

                // Bind the filter form
                $('.XiboGrid').find('.XiboFilter form input').on('keyup',  function() { addMarkersToMap(bounds); });
                $('.XiboGrid').find('.XiboFilter form select').on('change', function() { addMarkersToMap(bounds); });

                // Hide map/ Show Display List
                $displayMap.hide();
            }

          // Add display markers to the cluster group
          function addMarkersToMap(bounds, clear = true) {

            if (clear) {
              markerClusterGroup.clearLayers();
              displayIdCache = [];
            }

            if (!$displayMap.is(':visible')) {
              return;
            }

            // Make an ajax request for the displays feature
            // Load GeoJSON data and add it to the marker cluster group
            $.ajax($displayMap.data('displaysUrl'), {
              method: 'GET',
              data: $('.XiboGrid').find(".XiboFilter form").serialize() + '&bounds=' + bounds,
              success: function(response) {
                // displays
                if (response.features.length > 0) {

                  // Define icons for display
                  let uptoDateLoggedInIcon = L.icon({
                    iconUrl: '{{ theme.rootUri() }}dist/assets/map-marker-green-check.png',
                    iconRetinaUrl: '{{ theme.rootUri() }}dist/assets/map-marker-green-check-2x.png',
                    iconSize: [24, 40],
                    iconAnchor: [12, 40]
                  });
                  let uptoDateLoggedOutIcon = L.icon({
                    iconUrl: '{{ theme.rootUri() }}dist/assets/map-marker-green-cross.png',
                    iconRetinaUrl: '{{ theme.rootUri() }}dist/assets/map-marker-green-cross-2x.png',
                    iconSize: [24, 40],
                    iconAnchor: [12, 40]
                  });
                  let outOfDateLoggedInIcon = L.icon({
                    iconUrl: '{{ theme.rootUri() }}dist/assets/map-marker-yellow-check.png',
                    iconRetinaUrl: '{{ theme.rootUri() }}dist/assets/map-marker-yellow-check-2x.png',
                    iconSize: [24, 40],
                    iconAnchor: [12, 40]
                  });
                  let outOfDateLoggedOutIcon = L.icon({
                    iconUrl: '{{ theme.rootUri() }}dist/assets/map-marker-yellow-cross.png',
                    iconRetinaUrl: '{{ theme.rootUri() }}dist/assets/map-marker-yellow-cross-2x.png',
                    iconSize: [24, 40],
                    iconAnchor: [12, 40]
                  });
                  let downloadingLoggedInIcon = L.icon({
                    iconUrl: '{{ theme.rootUri() }}dist/assets/map-marker-red-check.png',
                    iconRetinaUrl: '{{ theme.rootUri() }}dist/assets/map-marker-red-check-2x.png',
                    iconSize: [24, 40],
                    iconAnchor: [12, 40]
                  });
                  let downloadingLoggedOutIcon = L.icon({
                    iconUrl: '{{ theme.rootUri() }}dist/assets/map-marker-red-cross.png',
                    iconRetinaUrl: '{{ theme.rootUri() }}dist/assets/map-marker-red-cross-2x.png',
                    iconSize: [24, 40],
                    iconAnchor: [12, 40]
                  });

                  // Loop through features (GeoJSON data) and add each marker to the cluster
                  let feature = L.geoJSON(response, {
                    pointToLayer: function (feature, latlng) {
                      let icon;

                      const icons = {
                        1: {
                          true: uptoDateLoggedInIcon,
                          false: uptoDateLoggedOutIcon
                        },
                        3: {
                          true: outOfDateLoggedInIcon,
                          false: outOfDateLoggedOutIcon
                        },
                        default: {
                          true: downloadingLoggedInIcon,
                          false: downloadingLoggedOutIcon
                        }
                      };

                      // The value of "mediaInventoryStatus" and "loggedIn" determines the "icon"
                      const loggedIn = feature.properties.loggedIn ? true: false;
                      const iconType = icons[feature.properties.mediaInventoryStatus] || icons.default;
                      icon = iconType[loggedIn];

                      let options = {
                        icon: icon
                      };

                      let popup = '<strong>' + feature.properties.display + '</strong>';
                      if (feature.properties.orientation) {
                        popup += '<br/><div style="width: 180px;"><span>Orientation: ' + feature.properties.orientation + '</span></div>';
                      }
                      if (feature.properties.status) {
                        popup += '<div style="width: 180px;"><span>Status: ' + feature.properties.status + '</span>';
                        if (feature.properties.loggedIn) {
                          popup += '<span> (Logged in) </span></div>';
                        } else {
                          popup += '<span> (Not logged in) </span></div>';
                        }
                      }
                      if (feature.properties.displayProfile) {
                        popup += '<div style="width: 180px;"><span>Display profile: ' + feature.properties.displayProfile + '</span></div>';
                      }
                      if (feature.properties.resolution) {
                        popup += '<div style="width: 180px;"><span>Resolution: ' + feature.properties.resolution + '</span></div>';
                      }
                      if (feature.properties.lastAccessed) {
                        let lastAccessed = moment(feature.properties.lastAccessed, "X").tz ?
                          moment(feature.properties.lastAccessed, "X").tz(timezone).format(jsDateFormat) :
                          moment(feature.properties.lastAccessed, "X").format(jsDateFormat);

                        popup += '<div style="width: 180px;"><span>Last accessed: ' + lastAccessed + '</span></div>';
                      }
                      if (feature.properties.thumbnail) {
                        popup += '<div style="width: 180px;"><img class="display-screenshot" src="' + feature.properties.thumbnail + '" /></div>';
                      }

                      if (!displayIdCache.includes(feature.properties.displayId)) {

                        // Cache displayId
                        displayIdCache.push(feature.properties.displayId);

                        var marker = L.marker(latlng, options);

                        // Add the inventory status to each marker so that we can count
                        // the status based displays in iconCreateFunction
                        marker.mediaInventoryStatus = feature.properties.mediaInventoryStatus;

                        // Add a marker
                        return marker.bindPopup(popup)
                          .openPopup()
                          .addTo(markerClusterGroup);
                      }
                    },
                  });
                }
              }
            });

            // Add the cluster group to the map
            markerClusterGroup.addTo(map);

            markerClusterGroup.on('clustermouseover', function(event) {
              var clusterMarkers = event.layer.getAllChildMarkers();

              let upToDate = 0;
              let outOfDate = 0;
              let downloading = 0;

              clusterMarkers.forEach(function(marker) {
                switch (marker.mediaInventoryStatus) {
                  case 1:
                    upToDate++;
                    break;
                  case 3:
                    outOfDate++;
                    break;
                  default:
                    downloading++;
                    break;
                }
              });

              let popContent = '<div><strong>Total number of displays</strong>';
              const statuses = [
                { count: upToDate, text: 'Up to date' },
                { count: outOfDate, text: 'Out of date' },
                { count: downloading, text: 'Downloading' }
              ];
              for (const { count, text } of statuses) {
                if (count > 0) {
                  popContent += `<div>${text}: ${count}</div>`;
                }
              }
              popContent += '</div>';

              var popup = L.popup()
                .setLatLng(event.latlng)
                .setContent(popContent)
                .openOn(map);
            }).on('clustermouseout',function(event){
              map.closePopup();
            }).on('clusterclick',function(event){
              map.closePopup();
            });
          }

            // Creating a pie chart for cluster childrens using HTML, CSS
            const createPieChart = function(data, colors) {
                // Get the total of all the data
                let total = data.reduce(function(a, b) {
                    return a + b;
                });

                // Get the percentage of each data point
                let percentages = data.map(function(d) {
                    return d / total;
                });

                // Create the pie chart
                let pie = $('<div></div>');
                pie.css('width', '30px');
                pie.css('height', '30px');
                pie.css('border-radius', '50%');
                pie.css('display', 'flex');
                pie.css('align-items', 'center');
                pie.css('justify-content', 'center');

                // Create conic-gradient for each data point
                let gradient = 'conic-gradient(';
                let percentageSum = 0;
                percentages.forEach(function(percentages, i) {
                    let color = colors[i];
                    let percentStart = percentageSum * 100;
                    let percentEnd = percentStart + percentages * 100;
                    percentageSum += percentages;
                    gradient += color + ' ' + percentStart + '%, ' + color + ' ' + percentEnd + '%, ';
                });
                gradient += 'white 0%)';

                // Set the pie chart's background to the conic-gradient
                pie.css('background', gradient);
                pie.css('box-shadow', '5px 5px 10px rgba(0, 0, 0, 0.3)');
                pie.append('<div style="color: black; font-weight: bold;">'+ total + '</div>');
                return  $("<div />").append(pie.clone()).html();
            };

            // </editor-fold>
        });

        {% set showThumbnailColumn = currentUser.getOptionValue("showThumbnailColumn", 1) %}

        function displayRequestScreenshotFormSubmit() {
            $("#displayRequestScreenshotForm").submit();
            XiboDialogClose();

            {% if showThumbnailColumn == 1 %}
                var table = $('#displays').DataTable();
                if (!table.column(["thumbnail:name"]).visible()) {
                    table.columns(["screenShotRequested:name", "thumbnail:name"]).visible(true);
                }
            {% endif %}
        }


        function setDefaultMultiSelectFormOpen(dialog) {
            console.log('Multi-select form opened for default layout');

            // Inject a list of layouts into the form, in a drop down.
            var $select = $('<select name="layoutId" class="form-control" data-search-url="{{ url_for("layout.search") }}" data-search-term="layout" data-search-term-tags="tags" data-id-property="layoutId" data-text-property="layout">');
            $select.on('change', function() {
                console.log('Setting commit data to ' + $(this).val());
                dialog.data().commitData = {layoutId: $(this).val()};
            });

            // Add the list to the body.
            $(dialog).find('.modal-body').append($select);

            makePagedSelect($select, dialog);
        }

        function displayFormLicenceCheckSubmit(form) {
            // Display commercial licence table column
            $('table#displays').DataTable().column('commercialLicence:name').visible(true);

            // Submit form
            form.submit();
        }

        function setMoveCmsMultiSelectFormOpen(dialog) {
            console.log('Multi-select form opened for move CMS');

            var $message = $(
                '<div class="col-sm-12 alert alert-info">' +
                    "<p>{{ 'Please note: Once the CMS Address and Key are authenticated in this form the Display will attempt to register with the CMS Instance details entered. Once transferred the Display will stop communicating with this CMS Instance.'|trans }}</p>" +
                '</div>'
            );

            $(dialog).find('.modal-body').append($message);

            var $cmsAddress =   $(
                '<div class="form-group row">' +
                    '<label class="col-sm-2 control-label" for="newCmsAddress" accesskey="">New CMS Address</label>' +
                    '<div class="col-sm-10">' +
                        '<input class="form-control" name="newCmsAddress" type="text" id="newCmsAddress" value="">' +
                        '<span class="help-block">{{ "Full URL to the new CMS, including https:// "|trans }}</span>' +
                    '</div>' +
                '</div>'
            );

            var $cmsKey = $(
                '<div class="form-group row">' +
                    '<label class="col-sm-2 control-label" for="newCmsKey" accesskey="">New CMS Key</label>' +
                    '<div class="col-sm-10">' +
                        '<input class="form-control" name="newCmsKey" type="text" id="newCmsKey" value="">' +
                        '<span class="help-block">{{ "CMS Secret Key associated with the provided new CMS Address"|trans }}</span>' +
                    '</div>' +
                '</div>'
            );

            var $authenticationCode =   $(
                '<div class="form-group row">' +
                    '<label class="col-sm-2 control-label" for="twoFactorCode" accesskey="">Two Factor Code</label>' +
                    '<div class="col-sm-10">' +
                        '<input class="form-control" name="twoFactorCode" type="text" id="twoFactorCode" value="">' +
                        '<span class="help-block">{{ "Please enter your Two Factor authentication code"|trans }}</span>' +
                    '</div>' +
                '</div>'
            );

            $(dialog).find('.modal-body').append($cmsAddress, $cmsKey, $authenticationCode);

            $('#twoFactorCode, #newCmsAddress, #newCmsKey').on('change', function() {

                dialog.data().commitData = {
                        newCmsAddress: $('#newCmsAddress').val(),
                        newCmsKey: $('#newCmsKey').val(),
                        twoFactorCode: $('#twoFactorCode').val()
                    };
            });
        }

        function makeVenueSelect($element) {
          // Get the openOOH venue types
          $element.append(new Option('', '0', false, false));
          $.ajax({
            method: 'GET',
            url: $element.data('searchUrl'),
            dataType: 'json',
            success: function(response) {
              $.each(response.data, function(key, el) {
                const selected = el.venueId === $element.data('venueId');
                $element.append(new Option(el.venueName, el.venueId, selected, selected));
              });

              $element.select2();
            },
            error: function(xhr) {
              SystemMessage(xhr.message || '{{"Unknown error"|trans}}', false);
            }
          });
        }

        function displayEditFormOpen(dialog) {

            // Setup display profile form
            displayProfileFormOpen();
            XiboInitialise('#settings-from-display-profile');

            var $settings = $(dialog).find('#settings-from-display-profile').find('.form-group');
            var $table = $(dialog).find('#settings-from-profile tbody').empty();
            var override = $(dialog).data('extra');
            var $venueIdSelect2 = $(dialog).find(".venue-select select.form-control");
            if ($venueIdSelect2.data('initialValue')) {
              $venueIdSelect2.data('initialised', true);
              makeVenueSelect($venueIdSelect2);
            } else {
              dialog.find('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                const activeTab = $(e.target).attr('href')
                if (activeTab === '#location' && !$venueIdSelect2.data('initialised')) {
                  $venueIdSelect2.data('initialised', true);
                  makeVenueSelect($venueIdSelect2);
                }
              });
            }

            // Parse special fields
            override.forEach(function(field, index) {
                if(['lockOptions','pictureOptions', 'timers'].includes(field.name)) {
                    var parsedValues = JSON.parse(field.value);

                    // Add values to the override array
                    $.each(parsedValues, function(name, value){

                        if(name == 'keylock') {
                            $.each(value, function(keylockName, keylockValue){
                                if(keylockName == 'local') {
                                    keylockName = 'keylockLocal';
                                }

                                if(keylockName == 'remote') {
                                    keylockName = 'keylockRemote';
                                }

                                override.push({name: keylockName, value: keylockValue})
                            });
                        }
                        // Convert boolean and numbers to string
                        value = (['boolean','number'].includes(typeof value)) ? value.toString() : value;

                        override.push({name: name, value: value})
                    });
                }
            });

            // Method to create a new input field based on the hidden form
            var createInputField = function(target, inputName, newValue = null) {
                var select2FixFlag = false;
                var timepickerFixFlag = false;
                var timepickerOptionsFixFlag = false;
                var sliderFixFlag = false;
                var sliderFixOptions = {};

                // Grab input field from hidden table
                var $inputFields = $settings.find('#' + inputName);

                // If no input field is capture by ID, get special fields
                if($inputFields.length == 0) {
                    if( $settings.find('.multiSelect').length > 0) {
                        // Copy special fields ( timers, pictureOptions ) by selected option
                        $inputFields = $settings.find('.multiSelect option:selected[value="' + inputName + '"]').parents('.form-group:first').find('.multiSelect, .multiSelectInputs');

                        $inputFields.each(function(key, el) {
                            if($(el).find('.timePickerDisplayEditForm').length > 0) {
                                timepickerOptionsFixFlag = true;

                                $(el).find('.input-group.timerInit').removeClass('timerInit');

                                destroyDatePicker($(el).find('.timePickerDisplayEditForm:not(.datePickerHelper)'));
                            } else if($(el).find('.pictureControlsSlider').length > 0) {
                                sliderFixFlag = true;
                                sliderFixOptions = $(el).find('.pictureControlsSlider').bootstrapSlider('getAttribute');
                                $(el).find('.pictureControlsSlider').bootstrapSlider('destroy');
                            }
                        });
                    }
                } else if($inputFields.length == 1 && $inputFields.hasClass('dateControl')) {
                    timepickerFixFlag  = true;

                    destroyDatePicker($inputFields);

                    // Time inputs
                    $inputFields = $inputFields.parent();
                } else if($inputFields.length == 1 && $inputFields.hasClass('select2-hidden-accessible')) {
                    select2FixFlag = true;
                    // Destroy select2 before copying
                    $inputFields.select2('destroy');
                }

                // Save old field before cloning
                $inputFieldsOld = $inputFields;

                // Clone input fields ( to be able to reuse the originals )
                $inputFields = $inputFields.clone(true);

                if(select2FixFlag) {
                    // Mark old field as select2 with the select2 class
                    // so it can be reinitialised if needed
                    $inputFieldsOld.addClass('select2-hidden-accessible');
                }
                // Add input field to the target
                $(target).html($inputFields);

                if(timepickerFixFlag) {
                    XiboInitialise('#' + $inputFieldsOld.parents('form').attr('id'));
                    XiboInitialise('#' + $(target).parents('form').attr('id'));
                }

                if(timepickerOptionsFixFlag) {
                    timersFormInit($inputFieldsOld);
                    timersFormInit($(target));

                    // Parent container
                    var $inputParent = $inputFields.parent()
                    $inputParent.addClass('timerOverride');
                    $inputParent.find('.date-clear-button').remove();
                    $inputParent.append('<div class="text-muted">{{ "Adjust the times of this timer. To add or remove a day, use the Display Profile."|trans }}</div>');
                }

                if(sliderFixFlag) {
                    $inputFieldsOld.find('.pictureControlsSlider').bootstrapSlider(sliderFixOptions);
                    $inputFields.find('.pictureControlsSlider').bootstrapSlider(sliderFixOptions);
                }

                // Set value if defined
                if(newValue != null) {
                    if($(target).find('.multiSelectInputs .pictureControlsSlider').length > 0) {
                        // SLIDER
                        if(!$.isNumeric(newValue)) { // If value is a label, get index
                            $(target).find('.multiSelectInputs .slider-tick-label').each(function(idx, el) {
                                if($(el).html() == newValue) {
                                    newValue = idx;
                                    return false;
                                }
                            });
                        }

                        // Set value
                        $(target).find('.pictureControlsSlider').bootstrapSlider('setValue', newValue);
                    } else if($inputFields.attr('type') == 'checkbox') {
                        // CHECKBOX
                        $($inputFields).prop('checked', newValue);
                    } else if(timepickerFixFlag) {
                        $($inputFields).find('input').val(newValue);
                    } else if(timepickerOptionsFixFlag) {
                        $.each(newValue, function(name, value){
                            if(name == 'on') {
                                $($inputFields).find('input.timersOn').val(value);
                            } else if(name == 'off') {
                                $($inputFields).find('input.timersOff').val(value);
                            }
                        })
                    } else {
                        $($inputFields).val(newValue);
                    }
                }

                // Reload select 2 with new value
                if(select2FixFlag) {
                    // Restore select2 after value set
                    makePagedSelect($inputFields);
                }

                // Android dimensions init
                if(inputName == 'screenDimensions') {
                    setAndroidDimensions($(target));

                    // CSS fix
                    $(target).find('.androidDimensionInput').removeClass('col-3').addClass('col-6');
                }

                // If there's a multiselect, set the value of the dropdown ( it's not kept on cloning ) and hide it
                $(target).find('.multiSelect').val(inputName).hide();

                // Style multi selects
                if($(target).find('.multiSelectInputs').length > 0) {
                    // Calculate column size for bootstrap
                    var colSize = Math.round(12/$(target).find('.multiSelectInputs').length);

                    //Remove all style classes and add the new size class
                    $(target).find('.multiSelectInputs').attr('class', 'multiSelectInputs col-sm-' + colSize)
                }

                // Set data propeties
                $(target).attr('data-editing', 'true');
                $(target).attr('data-input-name', inputName);

                // Remove click to edit event
                $(target).unbind('click');

                // Fixes for slider
                $(target).find('.slider').addClass('scaled-slider');
                $(target).find('.pictureControlsSlider').bootstrapSlider('refresh', { useCurrentValue: true });

                // Add help text if exists on label
                let inputHelpText = $(target).parent('tr').find('td:first strong').attr('title');
                if(inputHelpText) {
                    $(target).append('<div class="text-muted">' + inputHelpText + '</div>');
                }

                var $newButton = $('<button class="btn btn-outline-danger btn-sm pull-right button-close-override" type="button"><i class="fa fa-times"></i></button>').click(function (e) {
                    e.stopPropagation();
                    restoreInputField(target, inputName);
                 });
                $(target).append($newButton);
            };


            // Method to restore the input field to the edit button
            var restoreInputField = function(target, inputName) {

                $(target).html('<button class="btn btn-block btn-outline-secondary" type="button"><i class="fa fa-edit"></i></button>');

                // Handlers for field edit
                $(target).off().click(function() {
                    if(!$(this).data('editing')) {
                        createInputField($(this), inputName);
                    }
                });

                $(target).attr('data-editing', 'false');
            };

            // Build table
            $.each($settings, function(index, element) {
                var $label = $(element).find('label');
                var $input = $(element).find('input,select');
                var $help = $(element).find('small.form-text.text-muted');
                var over = $label.prop("for");
                var value = '';
                var text = '';
                var help = $help.length > 0 ? $help.text() : '';

                // Skip for some fields
                if(['name', 'isDefault'].includes(over)) {
                    return true;
                }

                if($(element).hasClass('form-group-timers')) {
                    // Get text and override name
                    over = $(element).find('.multiSelect').val();
                    text = $(element).find('.multiSelect option:selected').text();

                    // Get value
                    value = $(element).find('.timersOn').val() + ' - ' + $(element).find('.timersOff').val();
                } else if($(element).hasClass('form-group-picture-options')) {
                    // Get text and override name
                    over = $(element).find('.multiSelect').val();
                    text = $(element).find('.multiSelect option:selected').text();

                    // Get labels
                    var labels = [];
                    $(element).find('.multiSelectInputs .slider-tick-label').each(function(idx, el) {
                        labels.push($(el).html());
                    });

                    // Get value
                    value = $(element).find('.multiSelectInputs .pictureControlsSlider').bootstrapSlider('getValue');

                    // If specific value has a label, use it as value
                    if(labels[value] != undefined) {
                        value = labels[value];
                    }
                } else if($input.attr('type') == 'checkbox'){
                    // Get text and value
                    text = $label.text();
                    value = $input.is(":checked");

                } else if($input.is('select')){
                    // Get text and value
                    text = $label.text();
                    value = $input.find('option:selected').text();
                } else if(over === 'screenDimensions'){
                    // Get text and value
                    text = $label.text();
                    value = $(element).find('#screenDimensions').val();
                } else {
                    // Get text and value
                    text = $label.text();
                    value = $input.val();
                }

                // Skip empty fields
                if(over == '' || over == undefined || over == null) {
                    return true;
                }

                // Append new row to the table
                var $tableNewRow = $('<tr><td style="width: 40%;"><strong title="' + help + '">' + text + '</strong></td><td style="width: 25%; overflow-x: auto; max-width: 250px;"><div>' + value + '</div></td><td class="override-input text-center" style="width: 35%;" data-editing="false" data-input-name="' + over + '"><button class="btn btn-block btn-outline-secondary" type="button"><i class="fa fa-edit"></i></button></td></tr>').appendTo($table);

                // Get override element
                var overrideEl = override.find(function(x) { return x.name === over; });
                if(overrideEl != undefined) { //If element was found, create an input

                    // Create input with override value
                    createInputField($tableNewRow.find('.override-input'), over, overrideEl.value);
                }
            });

            // Handlers for field edit
            $(dialog).find('.override-input[data-editing="false"]').click(function() {
                var inputName = $(this).data('inputName');
                createInputField($(this), inputName);
            });

            // Refresh on tab switch to fix broken labels
            $('a[data-toggle="tab"]').on('shown.bs.tab', function() {
                $('.pictureControlsSlider').bootstrapSlider('refresh', { useCurrentValue: true });
            });

            // Call XiboInitialise on table
            XiboInitialise('#settings-from-profile');
        }

        // Custom submit for display form
        function displayEditFormSubmit() {
            var $form = $('#displayEditForm');
            // Grab and alter the value in the bandwidth limit field
            var bandwidthLimitField = $form.find("input[name=bandwidthLimit]");
            var bandwidthLimitUnitsField = $form.find("select[name=bandwidthLimitUnits]");
            var bandwidthLimit = bandwidthLimitField.val();

            if (bandwidthLimitUnitsField.val() == 'mb') {
                bandwidthLimit = bandwidthLimit * 1024;
            } else if (bandwidthLimitUnitsField.val() == 'gb') {
                bandwidthLimit = bandwidthLimit * 1024 * 1024;
            }

            // Set the field
            bandwidthLimitField.prop('value', bandwidthLimit);

            // Remove temp fields and enable checkbox after submit
            $form.submit(function(event) {
                event.preventDefault();
                // Re-enable checkboxes
                $form.find('input[type="checkbox"]').each(function () {
                    // Enable checkbox
                    $(this).attr('disabled', false);
                });

                // Remove temp input fields
                $form.find('input.temp-input').each(function () {
                    $(this).remove();
                });
            });

            // Replace all checkboxes with hidden input fields
            $form.find('input[type="checkbox"]').each(function () {
                // Get checkbox values
                var value = $(this).is(':checked') ? 'on' : 'off';
                var id = $(this).attr('id');

                // Create hidden input
                $('<input type="hidden" class="temp-input">')
                    .attr('id', id)
                    .attr('name', id)
                    .val(value)
                    .appendTo($(this).parent());

                // Disable checkbox so it won't be submitted
                $(this).attr('disabled', true);
            });

            // Submit form
            $form.submit();
        }

        $('body').on('click', '.display-screenshot', function(el) {
            var displayId = el.target.dataset.displayId;
            var displayType = el.target.dataset.type;
            var clientCode = el.target.dataset.clientCode;

            var statusWindowData = {};

            $.ajax({
                url: "/display/status/" + displayId,
                method: "GET",
                dataType: "json",
                success: function (data) {
                    if (data != null) {
                        // do some processing on data received from webOS and Tizen Players.
                        if (clientCode < 400 && (displayType === 'webOS' || displayType === 'sssp')) {
                            data.logMessagesArray = JSON.stringify(data.logMessagesArray);
                            data.allLayouts = JSON.stringify(data.allLayouts);
                            data.scheduledLayouts = JSON.stringify(data.scheduledLayouts);
                            data.validLayouts = JSON.stringify(data.validLayouts);
                            data.invalidLayouts = JSON.stringify(data.invalidLayouts);
                            data.blacklistArray = JSON.stringify(data.blacklistArray);
                            data.spaceTotal = formatBytes(data.spaceTotal, 2);
                            data.spaceFree = formatBytes(data.spaceFree, 2);
                            data.spaceUsed = formatBytes(data.spaceUsed, 2);
                        }

                        statusWindowData['data'] = data;
                        statusWindowData['type'] = displayType;
                        var statusWindowTemplate = Handlebars.compile($('#display-status-window-template').html());
                        $('.modal-body').append(statusWindowTemplate(statusWindowData));
                    }
                }
            });
        });
    </script>

    <style>
        #settings-from-profile tr.row-fluid {
            height: 50px;
        }
    </style>
{% endblock %}
