"use strict";
this.name = "Lib_SystemMap";
this.author = "phkb";
this.copyright = "2026 phkb";
this.description = "Adds a system map, accessible from the F7 screen.";
this.licence = "CC BY-NC-SA 4.0";

this._exitScreen = "GUI_SCREEN_SYSTEM_DATA";
this._custom = [];
this._hint = false;

//-------------------------------------------------------------------------------------------------------------
this.$addCustomMarker = function (obj) {
    if (!obj.ent && !obj.pos) {
        log(this.name, "No entity (obj.ent) or position (obj.pos) specified. Unable to add marker.");
        return;
    }
    if (!obj.map || obj.map == "") obj.map = "map_station.png";
    if (obj.hasOwnProperty("col") && isNaN(obj.col)) {
        log(this.name, "Invalid color (obj.col) value. Must be an integer between 0 and 12.");
        return;
    }
    this._custom.push(obj);
}

//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
    if (oolite.compareVersion("1.91") <= 0) {
        setExtraGuiScreenKeys(this.name, {
            guiScreen: "GUI_SCREEN_SYSTEM_DATA",
            registerKeys: { "systemkey": [{ key: "s" }] },
            callback: this.$localSystemMap.bind(this)
        });

        if (worldScripts.ContextualHelp) {
            worldScripts.ContextualHelp.$addHelpTextToGuiScreen(this.name, "GUI_SCREEN_SYSTEM_DATA", "\n" + expandDescription("[systemmap_helper]"));
        }
    } else {
        this.$initInterface(player.ship.dockedStation);
        this._exitScreen = "GUI_SCREEN_INTERFACES";
    }
}

//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function () {
    this._custom.length = 0;
}

//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
    if (oolite.compareVersion("1.91") > 0) {
        this.$initInterface(station);
    }
}

//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function (to, from) {
    if (guiScreen == "GUI_SCREEN_SYSTEM_DATA" && oolite.compareVersion("1.91") <= 0 && !this._hint) {
        this._hint = true;
        player.consoleMessage(expandDescription("[systemmap_helper]"))
    }
}

//-------------------------------------------------------------------------------------------------------------
this.$initInterface = function $initInterface(station) {
    station.setInterface(this.name, {
        title: expandDescription("[systemmap_title]"),
        category: expandDescription("[systemmap_category]"),
        summary: expandDescription("[systemmap_summary]"),
        callback: this.$localSystemMap.bind(this)
    });
}

//-------------------------------------------------------------------------------------------------------------
this.$localSystemMap = function () {
    var p = player.ship;
    if (!p.docked) return; // only while docked

    if (system.isInterstellarSpace) {
        // inform player you can't access screen in interstellar space
        mission.runScreen({
            title: expandDescription("[systemmap_title]"),
            message: expandDescription("[systemmap_interstellar]"),
            exitScreen: this._exitScreen
        });
        return;
    }

    // if xenon installed and active, pick the appropriate background
    var xenon = null;
    if (worldScripts.XenonUI) {
        var found = true;
        if (worldScripts.Lib_GUI) {
            var lib = worldScripts.Lib_GUI;
            if (lib.$cur != "XenonUI") found = false;
        }
        if (found) {
            var xui = worldScripts.XenonUI;
            xenon = { name: "xenon_" + xui._ratio + (xui._amber ? "_amber" : "") + ".png", height: 546 };
        }
    }

    var stn_found = false;
    if (p.docked && p.dockedStation.isMainStation) stn_found = true;

    // create array and add the sun
    var sini = [{ map: "lib_starmap_0.png", ent: system.sun, col: 12 }];

    // add in the witchpoint
    var wp = system.shipsWithRole("buoy-witchpoint")[0];
    if (wp) {
        sini.push({ map: "lib_starmap_2.png", ent: wp, displayName:expandDescription("[systemmap_witchpoint]")});
    }

    // add in the players location
    if (p.docked && p.dockedStation.hasRole("planetFall2_surface")) {
        sini.push({ map: "map_point.png", pos: p.dockedStation.linkedVE.position, col: 1, displayName: expandDescription("[systemmap_yourlocation]") });
    } else {
        sini.push({ map: "map_point.png", ent: p, col: 1, displayName: expandDescription("[systemmap_yourlocation]") })
    }

    // add the main planet
    var pf = this.$planetHasLandingSpots(system.mainPlanet);
    if (system.mainPlanet.isGasGiant || system.mainPlanet.solarGasGiant) {
        sini.push({ map: "map_planet_1.png", ent: system.mainPlanet, col: 4 });
    } else {
        sini.push({ map: "map_planet_" + (pf ? "pf" : "") + "1.png", ent: system.mainPlanet, col: 2 });
    }

    // add all the planets and moons (except for the main planet)
    function plfn(entity) { return entity.isPlanet && !entity.isMainPlanet; }

    var pl = system.filteredEntities(this, plfn, system.sun);
    var p_count = 2;
    for (var i = 0; i < pl.length; i++) {
        pf = this.$planetHasLandingSpots(pl[i]);
        if (!pl[i].hasAtmosphere) {
            sini.push({ map: "map_moon" + (pf ? "_pf" : "") + ".png", ent: pl[i], col: 10 });
        } else {
            if (p_count > 9) {
                if (pl[i].solarGasGiant || pl[i].isGasGiant) {
                    sini.push({ map: "map_planet.png", ent: pl[i], col: 4 });
                } else {
                    sini.push({ map: "map_planet" + (pf ? "_pf" : "") + ".png", ent: pl[i], col: 2 });
                }
            } else {
                if (pl[i].solarGasGiant || pl[i].isGasGiant) {
                    sini.push({ map: "map_planet_" + p_count + ".png", ent: pl[i], col: 4 });
                } else {
                    sini.push({ map: "map_planet_" + (pf ? "pf" : "") + p_count + ".png", ent: pl[i], col: 2 });
                }
            }
            p_count += 1;
        }
    }

    // add the main station
    sini.push({ map: "map_station.png", ent: system.mainStation, col: 3 });

    // add all the main stations (except for the actual main station)
    function stfn(entity) {
        return entity.isShip &&
            entity.hasNPCTraffic && // only stations with traffic
            (entity.scanClass != "CLASS_ROCK" || entity.beaconCode != null) && // only rock hermits with a beacon
            (["hunter", "neutral", "private"].indexOf(entity.allegiance) == -1 || entity.beaconCode != null) && // only hunter/neutral/private stations with a beacon          
            !entity.hasRole("planetFall2_surface") && // not planetfall locations
            !entity.isMainStation && // not the main station
            entity.maxSpeed == 0; // must not be moving
    }

    var stns = system.filteredEntities(this, stfn, system.mainPlanet);
    for (var i = 0; i < stns.length; i++) {
        if (p.docked && stns[i] == p.dockedStation) stn_found = true;
        sini.push({ map: "map_station.png", ent: stns[i] });
    }

    // make sure the players current station is on the map.
    if (stn_found == false) {
        if (p.docked && !p.dockedStation.hasRole("planetFall2_surface")) {
            sini.push({ map: "map_station.png", ent: p.dockedStation, col: 5 });
        }
    }

    // add in the tianve pulsar, if installed
    if (galaxyNumber == 0 && system.ID == 246 && worldScripts["oolite-tianve"]) {
        var ve = system.allVisualEffects;
        for (var i = 0; i < ve.length; i++) {
            if (ve[i].dataKey == "tianve_pulsar_flashers") {
                sini.push({ map: "lib_starmap_i8.png", pos: ve[i].position, col: 6, displayName: expandDescription("[systemmap_pulsar]") })
            }
        }
    }

    // add any custom items
    if (this._custom.length > 0) {
        for (var i = 0; i < this._custom.length; i++) {
            sini.push(this._custom[i]);
        }
    }

    worldScripts.Lib_Starmap._start({ 
        ini: sini, 
        title: expandDescription("[systemmap_screen_title]"), 
        exit: this._exitScreen, 
        viewControls: true, 
        background: xenon, 
        exitText: expandDescription("[systemmap_close]")
    });
}

//-------------------------------------------------------------------------------------------------------------
this.$planetHasLandingSpots = function (planet) {
    if (!worldScripts.PlanetFall2 && !worldScripts.PlanetFall) return false;
    if (worldScripts.PlanetFall) {
        return !(planet.hasOwnProperty("PFNoLand") || planet.hasOwnProperty("solarGasGiant") || planet.hasOwnProperty("isGasGiant"));
    }
    return (worldScripts.PlanetFall2.$getPlanetLandingSites(planet).length > 0);
}
