"use strict";
this.name = "GalCopBB_SoftwareInstall";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Control of the F4 Interface for installing security software (mission 62)";
this.license = "CC BY-NC-SA 4.0";

this._debug = false;
this._pirateHermitInfo = {}; // dictionary of systems known to have a Rock Hermit, and the time security software was installed
this._wolfPackOnLaunch = false;

//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
	if (missionVariables.GalCopBBMissions_PirateHermitInfo) {
		this._pirateHermitInfo = JSON.parse(missionVariables.GalCopBBMissions_PirateHermitInfo);
		delete missionVariables.GalCopBBMissions_PirateHermitInfo;
	}
	if (missionVariables.GalCopBBMissions_WolfPackOnLaunch) {
		this._wolfPackOnLaunch = true;
		delete missionVariables.GalCopBBMissions_WolfPackOnLaunch;
	}
	var gcm = worldScripts.GalCopBB_Missions;
	// add these mission types into the main control
	gcm._availableMissionTypes.push(62);
	this._debug = gcm._debug;
}

//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
	this.$doesSystemHavePirateHermit();

	this.$initInterface(player.ship.dockedStation);

	if (worldScripts.Lib_GUI) {
		worldScripts.Lib_GUI.$IDRules["oolite-gcm-secsoftware-summary"] = { pic: 1, snd: 1, mus: 1 };
	}
}

//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
	if (this._pirateHermitInfo.length > 0) missionVariables.GalCopBBMissions_PirateHermitInfo = JSON.stringify(this._pirateHermitInfo);
	if (this._wolfPackOnLaunch === true) missionVariables.GalCopBBMissions_WolfPackOnLaunch = true;
}

//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function (galaxyNumber) {
	this._pirateHermitInfo = {};
}

//-------------------------------------------------------------------------------------------------------------
// set up interstellar space mission entities here
this.shipExitedWitchspace = function () {
	if (system.ID !== -1) {
		this.$doesSystemHavePirateHermit();
	}
}

//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
	this.$initInterface(station);
}

//-------------------------------------------------------------------------------------------------------------
this.shipWillLaunchFromStation = function (station) {
	if (this._wolfPackOnLaunch === true) {
		var num = Math.floor(player.score / 1000) + 1;
		var ships = system.addGroup("pirate", num, player.ship.position.add(player.ship.vectorForward.multiply(10000)), 10000);
		// make sure they will attack the player
		for (var i = 0; i < ships.length; i++) {
			ships[i].switchAI("gcm-pirateAI.js");
		}
		this._wolfPackOnLaunch = false;
	}
}

//-------------------------------------------------------------------------------------------------------------
this.dayChanged = function (newday) {
	this.$checkRockHermitSecSoftware();
}

//-------------------------------------------------------------------------------------------------------------
this.alertConditionChanged = function (newCondition, oldCondition) {
	function gcm_findhermits(entity) {
		return (entity.isShip === true && entity.isStation === true && entity.hasRole("rockhermit-pirate"));
	}
	if (newCondition === 3 && this._pirateHermitInfo[system.ID] && this._pirateHermitInfo[system.ID] >= 0) {
		var targets = system.filteredEntities(this, gcm_findhermits);
		for (var i = 0; i < targets.length; i++) {
			if (targets[i].position.distanceTo(player.ship) < 50000) {
				var gcm = worldScripts.GalCopBB_Missions;
				var list = gcm.$getListOfMissions(true, 62);
				for (var i = 0; i < list.length; i++) {
					if (list[i].destination === system.ID &&
						list[i].data.quantity === 0 &&
						list[i].data.targetQuantity === 1) {
						// we got spotted! mission failed!
						list[i].data.targetQuantity = 0;
					}
				}
			}
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$initInterface = function $initInterface(station) {
	var inst = false;
	if (station.hasRole("rockhermit-pirate")) {
		var gcm = worldScripts.GalCopBB_Missions;
		var list = gcm.$getListOfMissions(true, 62);
		for (var i = 0; i < list.length; i++) {
			if (list[i].destination === system.ID &&
				list[i].data.targetQuantity > 0 &&
				(this._pirateHermitInfo[system.ID] == null || this._pirateHermitInfo[system.ID] > 0)) {
				inst = true;
				station.setInterface(this.name, {
					title: expandDescription("[gcm_install_software_title]"),
					category: expandDescription("[gcm_install_software_category]"),
					summary: expandDescription("[gcm_install_software_summary]"),
					callback: this.$installSoftware.bind(this)
				});
			}
		}
	}
	if (inst === false) {
		station.setInterface(this.name, null);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$installSoftware = function $installSoftware() {
	this._pirateHermitInfo[system.ID] = clock.adjustedSeconds;

	// remove the interface screen
	player.ship.dockedStation.setInterface(this.name, null);

	// flag the mission as complete
	var bb = worldScripts.BulletinBoardSystem;
	var gcm = worldScripts.GalCopBB_Missions;
	var list = gcm.$getListOfMissions(true, 62);
	for (var i = 0; i < list.length; i++) {
		if (list[i].destination === system.ID &&
			list[i].data.quantity === 0) {
			// we got spotted! mission failed!
			list[i].data.quantity = 1;
			bb.$updateBBMissionPercentage(list[i].ID, 1);

			gcm.$logMissionData(list[i].ID);
			player.consoleMessage(expandDescription("[goal_updated]"));

			if (Math.random() > 0.6) this._wolfPackOnLaunch = true;
		}
	}

	// confirm the action to the player
	mission.runScreen({
		screenID: "oolite-gcm-secsoftware-summary",
		title: expandDescription("[gcm_galcop_software_title]"),
		message: expandDescription("[gcm_software_installed]"),
		exitScreen: "GUI_SCREEN_INTERFACES",
		overlay: {
			name: "gcm-ok.png",
			height: 546
		}
	});
}

//-------------------------------------------------------------------------------------------------------------
// check for and remove security software installed at rock hermits
this.$checkRockHermitSecSoftware = function $checkRockHermitSecSoftware() {
	var keys = Object.keys(this._pirateHermitInfo);
	for (var i = 0; i < keys.length; i++) {
		// if it's been a month since the software was installed at the hermit, remove it now.
		if (this._pirateHermitInfo[keys[i]] !== 0 && clock.adjustedSeconds - this._pirateHermitInfo[keys[i]] > 2592000) {
			delete this._pirateHermitInfo[keys[i]];
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
// checks if the current system has a pirate rock hermit
this.$doesSystemHavePirateHermit = function $doesSystemHavePirateHermit() {
	function gcm_findhermits(entity) {
		return (entity.isStation && entity.hasRole("rockhermit-pirate"));
	}
	var targets = system.filteredEntities(this, gcm_findhermits);
	if (targets.length > 0) {
		if (this._pirateHermitInfo[system.ID] == null) this._pirateHermitInfo[system.ID] = 0;
		// attach a shipDied event to the hermits so we can remove them from the array if they are destroyed
		for (var i = 0; i < targets.length; i++) {
			// monkey patch if necessary
			if (targets[i].script.shipDied && targets[i].script.$gcm_hold_shipDied == null) {
				targets[i].script.$gcm_hold_shipDied = targets[i].script.shipDied;
			}
			targets[i].script.shipDied = this.$gcm_pirateHermit_shipDied;
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$gcm_pirateHermit_shipDied = function $gcm_pirateHermit_shipDied(whom, why) {
	function gcm_findhermits(entity) {
		return (entity.isShip && entity.hasRole("rockhermit-pirate"));
	}

	if (this.ship.script.$gcm_hold_shipDied) this.ship.script.$gcm_hold_shipDied(whom, why);

	var targets = system.filteredEntities(this, gcm_findhermits);
	if (targets.length === 0) {
		delete worldScripts.GalCopBB_SoftwareInstall._pirateHermitInfo[system.ID];
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$acceptedMission = function $acceptedMission(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var gcm = worldScripts.GalCopBB_Missions;

	if (this._debug) log(this.name, "accepted mission id = " + missID);

	if (!item) {
		log(this.name, "!!ERROR: BB returned null value from $getItem on mission ID " + missID);
		return;
	}
	gcm.$updateLastMissionDate(item.source, item.data.missionType);
	gcm.$updateGeneralSettings(item);

}

//-------------------------------------------------------------------------------------------------------------
this.$completedMission = function $completedMission(missID) {
	var p = player.ship;
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var gcm = worldScripts.GalCopBB_Missions;

	// update mission history
	gcm.$updateSuccessHistoryReputation(item);

	if (item.data.missionType === 62) {
		var sbm = worldScripts.Smugglers_BlackMarket;
		if (sbm) sbm.$removeSaleItem("DTA_GALCOP_SEC_SOFTWARE:" + missID);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$confirmCompleted = function $confirmCompleted(missID) {
	return "";
}

//-------------------------------------------------------------------------------------------------------------
this.$terminateMission = function $terminateMission(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var gcm = worldScripts.GalCopBB_Missions;

	// adjust reputation only when the terminatePenalty flag is set to true 
	if (item.data.terminatePenalty === true) {
		// update mission history
		gcm.$updateFailedHistoryReputation(item);
	}

	// *** type 62 - galcop security software for pirate hermit monitoring
	if (item.data.missionType === 62) {
		var sbm = worldScripts.Smugglers_BlackMarket;
		if (sbm) sbm.$removeSaleItem("DTA_GALCOP_SEC_SOFTWARE:" + missID);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$failedMission = function $failedMission(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var gcm = worldScripts.GalCopBB_Missions;
	var eq = "";

	if (!worldScripts.Smugglers_BlackMarket) {
		// if there's no blackmarket option, just remove the equipment
		gcm.$terminateMission(missID);
		return;
	}

	var item = bb.$getItem(missID);
	// update mission history
	gcm.$updateFailedHistoryReputation(item);

	if (item.data.missionType === 62 && item.data.quantity === 0) eq = "DTA_GALCOP_SEC_SOFTWARE";

	if (eq != "") gcm._equipmentFromFailedMissions.push({
		missionType: item.data.missionType,
		source: item.source,
		equip: eq,
		date: clock.adjustedSeconds
	});
}

//-------------------------------------------------------------------------------------------------------------
this.$updateManifestEntry = function $updateManifestEntry(missID) {
	var gcm = worldScripts.GalCopBB_Missions;
	gcm.$updateManifestEntry(missID);
}

//-------------------------------------------------------------------------------------------------------------
this.$missionAvailability = function $missionAvailability(missID, missType, origSysID) {
	return worldScripts.GalCopBB_Missions.$missionAvailability(missID, missType, origSysID);
}

//-------------------------------------------------------------------------------------------------------------
// 62 - security software install
this.$missionType62_Values = function $missionType62_Values(workTime, routeTime, routeDistance, destSysInfo) {
	var result = {};
	result["quantity"] = 1;
	result["price"] = parseInt((parseInt(Math.random() * 500) + 500) / 10) * 10 +
		worldScripts.GalCopBB_CoreMissionValues.$calcPlayerBonus(500); // plus a possible bonus price, based on player score 
	result["expiry"] = clock.adjustedSeconds + routeTime + workTime; // transit time + 1 hour to complete
	result["penalty"] = parseInt(result.price / 4);
	return result;
}