"use strict";
this.name = "GalCopBB_PirateBases";
this.author = "phkb";
this.copyright = "2018 phkb";
this.description = "Looks after the spawning, and subsequent re-creation, of pirate bases";
this.license = "CC BY-NC-SA 4.0";

// array of dictionaries, containing
//      systemID        system ID where asteroid field is found
//      x,y,z,coordSystem
//      locationType
this._bases = [];
this._populateComplete = false;

// todo: do something different with Qbombs? prevent them from exploding close to base?

//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
    if (missionVariables.GalCopBBMissions_PirateBases) {
        this._bases = JSON.parse(missionVariables.GalCopBBMissions_PirateBases);
    }
}

//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
    missionVariables.GalCopBBMissions_PirateBases = JSON.stringify(this._bases);
}

//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function (cause, destination) {
    if (cause === "galactic jump") this._bases.length = 0;
    this._populateComplete = false;
}

//-------------------------------------------------------------------------------------------------------------
// scripts that will need pirate base should manually call this function from their own "systemWillPopulate" function.
// this ensures any pirate bases will be created before they need to use them
this.systemWillPopulate = function () {
    // make sure we don't run this twice
    if (this._populateComplete === true) return;
    this.$fixPirateBaseData();
    // theoretically there will only be 1 base per system, but just in case that changes, we'll store everything in an array
    var b = this._bases;
    for (var i = 0; i < b.length; i++) {
        if (b[i].systemID === system.ID) {
            var position = Vector3D(b[i].x, b[i].y, b[i].z).fromCoordinateSystem(b[i].coordSystem)
            // add a pirate base
            system.setPopulator("gcm-piratebase-" + i, {
                callback: function (pos) {
                    // add some asteroids around the base
                    system.addShips("asteroid", 30, pos, 40E3);
                    // add the base itself
                    var key = "gcm-pirate-base-core";
                    if (Ship.shipDataForKey("griff_rockhermit") != null) key = "gcm-pirate-base-griff";
                    var checkShips = system.addShips("[" + key + "]", 1, pos, 0);
                    var base = null;
                    if (checkShips) base = checkShips[0];
                    if (base) {
                        base.script.shipDied = worldScripts.GalCopBB_PirateBases.$pb_shipDied;
                        worldScripts.GalCopBB_PirateBases.$addMissionIDToBase(base);
                    }
                    // create some lurking goons
                    worldScripts.GalCopBB_GoonSquads.$createGoonSquad(parseInt((Math.random() * 4) + 3), pos, player.ship.scannerRange * 0.9);

                }.bind(this),
                location: "COORDINATES",
                coordinates: position
            });
        }
    }
    this._populateComplete = true;
}

//-------------------------------------------------------------------------------------------------------------
// pirate bases are added with factor and seed values
// once they are actually spawned, though, they will instead have x,y,z values to keep the field in roughly the same place
this.$addPirateBase = function $addPirateBase(sysID, factor, seed, locationType) {
    this._bases.push({
        systemID: sysID,
        factor: factor,
        seed: seed,
        locationType: locationType
    });
}

//-------------------------------------------------------------------------------------------------------------
this.$addPirateBaseDirect = function $addPirateBaseDirect(sysID, x, y, z, coord, locationType) {
    this._bases.push({
        systemID: sysID,
        x: x,
        y: y,
        z: z,
        coordSystem: coord,
        locationType: locationType
    });
}

//-------------------------------------------------------------------------------------------------------------
this.$systemHasPirateBase = function $systemHasPirateBase(sysID) {
    for (var i = 0; i < this._bases.length; i++) {
        if (this._bases[i].systemID === sysID) return this._bases[i];
    }
    return null;
}

//-------------------------------------------------------------------------------------------------------------
this.$getSystemPirateBase = function $getSystemPirateBase() {
    var bases = system.shipsWithRole("gcm_pirate_base");
    if (bases.length === 0) return null;
    return bases[0];
}

//-------------------------------------------------------------------------------------------------------------
this.$fixPirateBaseData = function $fixPirateBaseData() {
    var gcm = worldScripts.GalCopBB_Missions;
    var b = this._bases;
    for (var i = 0; i < b.length; i++) {
        if (b[i].systemID === system.ID && b[i].hasOwnProperty("factor") === true) {
            var info = gcm.$getRandomPosition(b[i].locationType, b[i].factor, b[i].seed);
            b[i].x = info.x;
            b[i].y = info.y;
            b[i].z = info.z;
            b[i].coordSystem = info.coordSystem;
            delete b[i].factor;
            delete b[i].seed;
        }
    }
}

//-------------------------------------------------------------------------------------------------------------
// used if we're manually creating a base in the current system
this.$forceSpawn = function $forceSpawn() {
    var b = this._bases;
    for (var i = 0; i < b.length; i++) {
        if (b[i].systemID === system.ID) {
            var pos = Vector3D(b[i].x, b[i].y, b[i].z).fromCoordinateSystem(b[i].coordSystem)
            // add some asteroids around the base
            system.addShips("asteroid", 30, pos, 40E3);
            // add the base itself
            var key = "gcm-pirate-base-core";
            if (Ship.shipDataForKey("griff_rockhermit") != null) key = "gcm-pirate-base-griff";
            var checkShips = system.addShips("[" + key + "]", 1, pos, 0);
            var base = null;
            if (checkShips) base = checkShips[0];
            if (base) {
                base.script.shipDied = this.$pb_shipDied;
                this.$addMissionIDToBase(base);
            }
            // create some lurking goons
            worldScripts.GalCopBB_GoonSquads.$createGoonSquad(parseInt((Math.random() * 4) + 3), pos, player.ship.scannerRange * 0.9);
            return pos;
        }
    }
}

//-------------------------------------------------------------------------------------------------------------
this.$pb_shipDied = function $pb_shipDied(whom, why) {
    // remove the base from the data so i can't be recreated
    var pb = worldScripts.GalCopBB_PirateBases;
    var b = pb._bases;
    for (var i = 0; i < b.length; i++) {
        if (b[i].systemID === system.ID) {
            b.splice(i, 1);
            break;
        }
    }
    // check for a related mission and mark it complete
    if (this.ship.script.hasOwnProperty("_missionID") && this.ship.script._missionID != 0) {
        var gcm = worldScripts.GalCopBB_Missions;
        var bb = worldScripts.BulletinBoardSystem;
        var item = bb.$getItem(this.ship.script._missionID);
        if (item) {
            // if the mission has been accepted, mark it complete now
            if (item.accepted === true && item.data.destroyedQuantity === 0 && item.data.quantity === 0) {
                item.data.quantity = 1;
                bb.$updateBBMissionPercentage(item.ID, 1);

                gcm.$logMissionData(item.ID);
                player.consoleMessage(expandDescription("[goal_updated]"));
            }
            // if the mission wasn't accepted, just delete it
            if (item.accepted === false) {
                bb.$removeBBMission(item.ID);
            }
        }
    }
}

//-------------------------------------------------------------------------------------------------------------
this.$addMissionIDToBase = function $addMissionIDToBase(base) {
    var gcm = worldScripts.GalCopBB_Missions;
    var list = gcm.$getListOfMissions(true, 140);
    // there should only ever be 1
    if (list.length > 0) {
        if (list[0].destination === system.ID &&
            list[0].data.quantity === 0 &&
            list[0].data.destroyedQuantity === 0 &&
            (list[0].expiry === -1 || list[0].expiry > clock.adjustedSeconds)) {

            base.script._missionID = list[0].ID;
        }
    }
}