// Storage for the spot data that the server gives us.
var spots = []
// List of people the user has worked. Each entry has the format callsign-band-mode. These can be added to the list by
// ticking the checkbox on a row of the table, and cleared from the Display menu. Where a row would be added to the
// table and the callsign-band-mode is in this list, it is shown struck through as already worked. This is persisted
// to localStorage.
let worked = []

// Dynamically add CSS code for the band toggle buttons to be in the appropriate colour.
// Some band names contain decimal points which are not allowed in CSS classes, so we text-replace them to "p".
function addBandToggleColourCSS(band_options) {
    var $style = $('<style>');
    band_options.forEach(o => {
        var domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
        $style.append(`#filter-button-label-band-${domSafeName} { border-color: ${bandToColor(o['name'])}; color: var(--bs-secondary);}`);
        $style.append(`.btn-check:checked + #filter-button-label-band-${domSafeName} { background-color: ${bandToColor(o['name'])}; color: ${bandToContrastColor(o['name'])};}`);
    });
    $('html > head').append($style);
}

// Generate bands filter card. This one is a special case.
function generateBandsMultiToggleFilterCard(band_options) {
    // Create a button for each option
    band_options.forEach(o => {
        var domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
        $("#band-options").append(`<input type="checkbox" class="btn-check filter-button-band storeable-checkbox" name="options" id="filter-button-band-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="btn btn-outline-secondary" id="filter-button-label-band-${domSafeName}" for="filter-button-band-${domSafeName}">${o['name']}</label> `);
    });
    // Create All/None/Ham HF buttons
    $("#band-options").append(` <span style="display: inline-block"><button id="filter-button-band-all" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('band', true);">All</button> <button id="filter-button-band-none" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('band', false);">None</button> <button id="filter-button-band-none" type="button" class="btn btn-outline-secondary" onclick="setHamHFBandToggles();">Ham HF</button></span>`);
}

// Set the band toggles so that only the amateur radio HF bands are selected. This includes 160m and 6m because that's
// widely expected by hams to be included. Special case of toggleFilterButtons().
function setHamHFBandToggles() {
    const hamHFBands = ["160m", "80m", "60m", "40m", "30m", "20m", "17m", "15m", "12m", "10m", "6m"];
    $(".filter-button-band").each(function() {
        $(this).prop('checked', hamHFBands.includes($(this).val().replace("filter-button-band-", "")));
    });
    filtersUpdated();
}

// Generate SIGs filter card. This one is also a special case.
function generateSIGsMultiToggleFilterCard(sig_options) {
    // Create a button for each option
    sig_options.forEach(o => {
        var domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
        $("#sig-options").append(`<input type="checkbox" class="btn-check filter-button-sig storeable-checkbox" name="options" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="btn btn-outline-success" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${sigToIcon(o['name'], 'fa-tower-cell')}"></i> ${o['name']}</label> `);
    });
    // Create a bonus "NO_SIG" / "General DX" option
    $("#sig-options").append(`<input type="checkbox" class="btn-check filter-button-sig storeable-checkbox" name="options" id="filter-button-sig-NO_SIG" value="NO_SIG" autocomplete="off" onClick="filtersUpdated()" checked><label class="btn btn-outline-success" id="filter-button-label-sig-NO_SIG" for="filter-button-sig-NO_SIG"><i class="fa-solid fa-tower-cell"></i> General DX</label> `);
    // Create All/None buttons
    $("#sig-options").append(` <span style="display: inline-block"><button id="filter-button-sig-all" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('sig', true);">All</button>&nbsp;<button id="filter-button-sig-none" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('sig', false);">None</button></span>`);
}

// Generate modes filter card. This one is also a special case.
function generateModesMultiToggleFilterCard(mode_options) {
    // Create a button for each option
    mode_options.forEach(o => {
        var domSafeName = o.replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
        $("#mode-options").append(`<input type="checkbox" class="btn-check filter-button-mode storeable-checkbox" name="options" id="filter-button-mode-${domSafeName}" value="${o}" autocomplete="off" onClick="filtersUpdated()" checked><label class="btn btn-outline-success" id="filter-button-label-mode-${domSafeName}" for="filter-button-mode-${domSafeName}">${o}</label> `);
    });
    // Create All/None buttons
    $("#mode-options").append(` <span style="display: inline-block"><button id="filter-button-mode-all" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('mode', true);">All</button>&nbsp;<button id="filter-button-mode-none" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('mode', false);">None</button></span>`);
    // Create category buttons
    $("#mode-options").append(` <button id="filter-button-mode-av" type="button" class="btn btn-outline-secondary" onclick="toggleAnalogVoiceModeToggles();">Analog Voice</button>&nbsp;<button id="filter-button-mode-dv" type="button" class="btn btn-outline-secondary" onclick="toggleDigitalVoiceModeToggles();">Digital Voice</button>&nbsp;<button id="filter-button-mode-digi" type="button" class="btn btn-outline-secondary" onclick="toggleDigiModeToggles();">Digimodes</button></span>`);
}

// Toggle the mode toggles that relate to Analog Voice.
function toggleAnalogVoiceModeToggles() {
    toggleToggles("mode", ["PHONE", "SSB", "LSB", "USB", "AM", "FM"]);
}

// Toggle the mode toggles that relate to Digital Voice.
function toggleDigitalVoiceModeToggles() {
    toggleToggles("mode", ["DV", "DMR", "DSTAR", "C4FM", "M17"]);
}

// Toggle the mode toggles that relate to Digimodes.
function toggleDigiModeToggles() {
    toggleToggles("mode", ["DATA", "FT8", "FT4", "RTTY", "SSTV", "JS8", "HELL", "PSK", "OLIVIA", "PKT", "MSK144"]);
}

// Toggle the a set of toggles of the given type (e.g. "mode") that match the given values (e.g. ["SSB", "AM", "FM"]).
function toggleToggles(type, values) {
    let toggle = null;
    $(".filter-button-" + type).each(function() {
        console.log($(this));
        if (values.includes($(this).val().replace("filter-button-" + type, ""))) {
            if (toggle == null) {
                toggle = !$(this).prop('checked');
            }
            $(this).prop('checked', toggle);
        }
    });
    filtersUpdated();
}

// Generate Sources filter card. This one is a minor special case as we create the buttons in the normal way, but then
// set which ones are enabled by default based on config rather than having them all enabled by default. We also sanitise
// names here for HTML elements.
function generateSourcesMultiToggleFilterCard(source_options, sources_enabled_by_default) {
    // Create a button for each option
    source_options.forEach(o => {
        var enable = sources_enabled_by_default.includes(o);
        var domSafeName = o.replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
        $("#source-options").append(`<input type="checkbox" class="btn-check filter-button-source storeable-checkbox" name="options" id="filter-button-source-${domSafeName}" value="${o}" autocomplete="off" onClick="filtersUpdated()" ${enable ? "checked" : ""}><label class="btn btn-outline-success" for="filter-button-source-${domSafeName}">${o}</label> `);
    });
    // Create All/None buttons
    $("#source-options").append(` <span style="display: inline-block"><button id="filter-button-source-all" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('source', true);">All</button>&nbsp;<button id="filter-button-source-none" type="button" class="btn btn-outline-secondary" onclick="toggleFilterButtons('source', false);">None</button></span>`);
}

// Method called when any filter is changed to reload the spots and persist the filter settings.
function filtersUpdated() {
    loadSpots();
    saveSettings();
}

// Function to update the band colour scheme in spots, bands and map pages
function setBandColorSchemeFromUI() {
    setBandColorScheme($("#band-color-scheme option:selected").val());
    saveSettings();
    // Fudge a full reload because we need to update not just colours in the list/map/bands but also the filters
    window.location.reload();
}

// Query if a callsign-band-mode combination as has already been worked
function alreadyWorked(callsign, band, mode) {
    return worked.includes(callsign + "-" + band + "-" + mode);
}

// Reload spots on becoming visible. This forces a refresh when used as a PWA and the user switches back to the PWA
// after some time has passed with it in the background.
addEventListener("visibilitychange", (event) => {
    if (!document.hidden) {
        loadSpots();
    }
});

// Startup
$(document).ready(function() {
    // Load worked list
    var tmpWorked = JSON.parse(localStorage.getItem("worked"));
    if (tmpWorked) {
        worked = tmpWorked;
    }
});