//17.7.2015 -spara-

"use strict";
this.name = "blackmonks";
this.author = "spara";
this.description = "Main script for Black Monks";

this.startUp = function () {
	if (missionVariables.blackmonk_contract) {
		this.$contract = JSON.parse(missionVariables.blackmonk_contract);
		delete missionVariables.blackmonk_contract;
	}
	this._setMonkSystems();
	//control payback on docking
	this.$offerOnce = false;
	//control one shot welcome screen
	if (!missionVariables.blackmonk_intro) this.$monkIntro = true;
	else this.$monkIntro = false;
}

this.playerEnteredNewGalaxy = function () {
	this._setMonkSystems();
}

//make a list of suitable monk systems
this._setMonkSystems = function () {
	this.$monkSystems = new Array();
	this.$monkSystemIDs = new Array();

	//first we'll utilize the basic rules
	var systems = SystemInfo.filteredSystems(this, function (other) {
		if (other.government >= 6 && other.techlevel >= 11 && !other.sun_gone_nova) {
			return (other);
		}
	});

	//only systems that are connected to others so that missions work are accepted
	for (var i = 0; i < systems.length; i++) {
		var destinations = 0;
		for (var j = 0; j < systems.length; j++) {
			var routeInfo = System.infoForSystem(galaxyNumber, systems[i].systemID).routeToSystem(systems[j]);
			if (routeInfo && routeInfo.route.length > 9) destinations++;
		}
		if (destinations > 0) {
			this.$monkSystems.push(systems[i]);
			this.$monkSystemIDs.push(systems[i].systemID);
		}
	}
}

this.playerWillSaveGame = function () {
	if (this.$contract) {
		missionVariables.blackmonk_contract = JSON.stringify(this.$contract);
	}
}

this.startUpComplete = this.shipDockedWithStation = function () {
	if (player.ship.dockedStation.hasRole("blackmonk_monastery")) {
		player.ship.dockedStation.setInterface("blackmonks", {
			title: expandMissionText("monk_interface_title"),
			category: expandDescriptions("[interfaces-category-employment]"),
			summary: expandMissionText("monk_interface_summary"),
			callback: this._bankingInterface.bind(this)
		});
	}
}

this.shipWillDockWithStation = function (station) {
	//offer payback on docking
	this.$offerOnce = true;
}

//force payback the the player is late and the destination is correct
this.missionScreenOpportunity = function () {
	//one shot welcome screen
	if (this.$monkIntro && player.ship.dockedStation.hasRole("blackmonk_monastery")) {
		mission.runScreen({
			titleKey: "monk_title",
			screenID: "blackmonks",
			messageKey: "monk_first_visit_one_off_intro",
		});
		setScreenOverlay({ name: "monk.png", height: 480 });
		this.$monkIntro = false;
		missionVariables.blackmonk_intro = 1;
	}
	if (player.ship.dockedStation.hasRole("blackmonk_monastery") && this.$contract) {
		//correct destination
		if ((this.$contract.galaxy === galaxyNumber && this.$contract.system === system.ID) || this.$contract.galaxy !== galaxyNumber) {
			missionVariables.monk_dest_name = System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name;
			//late, force payback
			if (this.$contract["dealine"] - clock.seconds < 0) {
				mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks",
					messageKey: "monk_payback_late",
					choicesKey: "monk_payback_force"
				},
					function (choice) {
						this._payback();
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
			}
			//enough credits
			else if (this.$offerOnce && player.credits >= 30000) {
				screenID: "blackmonks",
					mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_early",
						choicesKey: "monk_payback_choices"
					},
						function (choice) {
							if (choice === "1_YES") {
								this._payback();
							}
						}
					);
				setScreenOverlay({ name: "monk.png", height: 480 });
			}
			delete missionVariables.monk_dest_name;
		}
	}
	this.$offerOnce = false;
}

this._bankingInterface = function (page) {
	//contract running
	if (this.$contract) {
		//correct destination early with sufficient credits
		if (((this.$contract.galaxy === galaxyNumber && this.$contract.system === system.ID) || (this.$contract.galaxy !== galaxyNumber)) && player.credits >= 30000) {
			mission.runScreen({
				titleKey: "monk_title",
				screenID: "blackmonks",
				messageKey: "monk_payback_early",
				choicesKey: "monk_payback_choices",
				exitScreen: "GUI_SCREEN_INTERFACES"
			},
				function (choice) {
					if (choice === "1_YES") {
						this._payback();
					}
				}
			);
		}
		//wrong destination or early without sufficient funds
		else {
			missionVariables.monk_dest_name = System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name;	//in time, godspeed to the player
			if (this.$contract["dealine"] - clock.seconds >= 0) {
				mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks",
					messageKey: "monk_payback_wrong_destination",
					exitScreen: "GUI_SCREEN_INTERFACES"
				}
				);
			}
			//too late, hurry the player up
			else {
				mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks",
					messageKey: "monk_payback_wrong_destination_late",
					exitScreen: "GUI_SCREEN_INTERFACES"
				}
				);
			}
			delete missionVariables.monk_dest_name;
		}
		setScreenOverlay({ name: "monk.png", height: 480 });
	}
	//offer contract, if there isn't one running
	else {
		switch (page) {
			case "blackmonks":
				//only offer for hyperspace capable ships
				if (player.ship.hasHyperspaceMotor) {
					mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_welcome",
						choicesKey: "monk_welcome_choices",
						exitScreen: "GUI_SCREEN_INTERFACES"
					},
						function (choice) {
							if (choice === "1_YES") {
								this._bankingInterface("offer_list");
							}
						}
					);
				}
				else {
					mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_welcome_no_dice",
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
					);
				}
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
			case "offer_list":
				this.$destinations = new Array();
				for (var i = 0; i < this.$monkSystems.length; i++) {
					var routeInfo = system.info.routeToSystem(this.$monkSystems[i]);
					if (routeInfo && routeInfo.route.length > 9) {
						this.$destinations.push(this.$monkSystems[i]);
					}
				}

				//offer max five shortest routest
				this.$destinations.sort(function (a, b) { return system.info.routeToSystem(a).route.length - system.info.routeToSystem(b).route.length });
				if (this.$destinations.length > 5) {
					this.$destinations = this.$destinations.slice(0, 5);
				}
				var options = {};
				for (var i = 0; i < this.$destinations.length; i++) {
					var info = system.info.routeToSystem(this.$destinations[i]);
					var origHours = info.time;
					var days = Math.ceil(origHours / 24) + Math.ceil(info.route.length / 12); //extra 0.5 hours per system on route rounded up
					var distance = System.infoForSystem(galaxyNumber, system.ID).distanceToSystem(this.$destinations[i]).toFixed(1);
					options[i + "_DEST"] = expandMissionText("monk_distance", { dest: this.$destinations[i].name, distance: distance, days: days });
				}
				options["99_EXIT"] = expandMissionText("monk_exit");
				mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks",
					messageKey: "monk_offer_list",
					choices: options,
					exitScreen: "GUI_SCREEN_INTERFACES"
				},
					function (choice) {
						if (choice !== "99_EXIT") {
							this.$offerPointer = choice.split('_')[0];
							this._setOffer("init");
							this.$mapMode = "LONG_RANGE_CHART_SHORTEST";
							this.$prevChoice = "3_NEXT";
							this.$restoreDestination = player.ship.targetSystem;
							this._bankingInterface("offer_map");
						}
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
			case "offer_map":
				player.ship.hudHidden = true;
				player.ship.targetSystem = this.$destinations[this.$offerPointer].systemID;

				var options = new Object;
				options["2_PREV"] = expandMissionText("monk_map_prev");
				options["3_NEXT"] = expandMissionText("monk_map_next");
				options["4_BACK"] = expandMissionText("monk_map_back");
				options["5_SIGN"] = expandMissionText("monk_map_sign");
				options["6_EXIT"] = expandMissionText("monk_map_exit");
				if (player.ship.equipmentStatus("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === "EQUIPMENT_OK") {
					if (this.$mapMode === "LONG_RANGE_CHART_SHORTEST") {
						options["1_MODE"] = expandMissionText("monk_map_mode1");
					}
					else {
						options["1_MODE"] = expandMissionText("monk_map_mode2");
					}
				}

				mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks-map",
					backgroundSpecial: this.$mapMode,
					messageKey: "monk_offer_details",
					choices: options,
					exitScreen: "GUI_SCREEN_INTERFACES",
					initialChoicesKey: this.$prevChoice
				},
					function (choice) {
						this.$prevChoice = choice;
						if (choice === "1_MODE") {
							if (this.$mapMode === "LONG_RANGE_CHART_SHORTEST") {
								this.$mapMode = "LONG_RANGE_CHART_QUICKEST";
							}
							else {
								this.$mapMode = "LONG_RANGE_CHART_SHORTEST";
							}
							this._bankingInterface("offer_map");
						}
						else if (choice === "3_NEXT") {
							this._setOffer("next");
							this._bankingInterface("offer_map");
						}
						else if (choice === "2_PREV") {
							this._setOffer("prev");
							this._bankingInterface("offer_map");
						}
						else if (choice === "4_BACK") {
							this._cleanUp();
							this._bankingInterface("offer_list");
						}
						else if (choice === "5_SIGN") {
							player.ship.hudHidden = false;
							this._bankingInterface("offer_sign");
						}
						else this._cleanUp();
					}
				);
				break;
			case "offer_sign":
				mission.runScreen({
					titleKey: "monk_title",
					messageKey: "monk_offer_sign",
					screenID: "blackmonks",
					exitScreen: "GUI_SCREEN_INTERFACES"
				}
				);
				//tip the player about the ANA
				if (player.ship.equipmentStatus("EQ_ADVANCED_NAVIGATIONAL_ARRAY") !== "EQUIPMENT_OK") {
					mission.addMessageTextKey("monk_offer_sign_tip");
				}
				this._cleanUp();
				this.$contract = new Object;
				this.$contract["galaxy"] = galaxyNumber;
				this.$contract["system"] = this.$destinations[this.$offerPointer].systemID;
				this.$contract["dealine"] = clock.seconds + this.$days * 86400;
				player.credits += 20000;
				mission.markSystem({ system: this.$contract["system"], name: "blackmonks" });
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
		}
	}
}

this._payback = function () {
	//clear the marker
	mission.unmarkSystem({ system: this.$contract["system"], name: "blackmonks" });
	//enough credits
	if (player.credits >= 30000) {
		player.credits -= 30000;
		delete this.$contract;
		mission.runScreen({
			titleKey: "monk_title",
			messageKey: "monk_payback_enough",
			screenID: "blackmonks"
		}
		);
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
	}
	//not enough credits, but enough equipment
	else if (this._evaluateEquipment() + player.credits >= 30000) {
		var sellOutcome = this._sellEquipment();
		missionVariables.monk_equipment_total = formatCredits(sellOutcome[1], true, true);
		missionVariables.monk_equipment_list = sellOutcome[0].join(", ");
		player.credits -= 30000;
		delete this.$contract;
		mission.runScreen({
			titleKey: "monk_title",
			messageKey: "monk_payback_not_enough",
			screenID: "blackmonks"
		}
		);
		mission.addMessageTextKey("monk_payback_equipment");
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
		delete missionVariables.monk_equipment_total;
		delete missionVariables.monk_equipment_list;
	}
	//not enough credits, not enough equipment, have to sell the ship
	else {
		var sellOutcome = this._sellEquipment();
		missionVariables.monk_equipment_total = formatCredits(sellOutcome[1], true, true);
		missionVariables.monk_equipment_list = sellOutcome[0].join(", ");
		missionVariables.monk_old_ship = formatCredits(0.5 * player.ship.price, true, true);
		this._sellShip();
		missionVariables.monk_new_ship = formatCredits(player.ship.price, true, true);
		player.credits -= 30000;
		player.credits -= player.ship.price;
		delete this.$contract;
		player.ship.hudHidden = true;
		mission.runScreen({
			titleKey: "monk_title",
			messageKey: "monk_payback_not_nearly_enough",
			screenID: "blackmonks"
		}
		);
		missionVariables.monk_balance = formatCredits(player.credits, true, true);
		mission.addMessageTextKey("monk_payback_equipment");
		mission.addMessageTextKey("monk_payback_ship");
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });

		delete missionVariables.monk_equipment_total;
		delete missionVariables.monk_equipment_list;
		delete missionVariables.monk_old_ship;
		delete missionVariables.monk_new_ship;
		delete missionVariables.monk_balance;
	}
}

//calculate the value of weapons, missiles and the installed equipment
this._evaluateEquipment = function () {
	var value = 0;
	var equipments = player.ship.equipment;
	for (var i = 0; i < equipments.length; i++) {
		if (equipments[i].price > 0 && player.ship.equipmentStatus(equipments[i]) === "EQUIPMENT_OK" && equipments[i].equipmentKey !== "EQ_CARGO_BAY" && equipments[i].equipmentKey !== "EQ_PASSENGER_BERTH") {
			value += equipments[i].price;
		}
	}
	var missiles = player.ship.missiles;
	for (var i = 0; i < missiles.length; i++) {
		if (missiles[i].price > 0) {
			value += missiles[i].price;
		}
	}
	if (player.ship.portWeapon && player.ship.portWeapon.price > 0) {
		value += player.ship.portWeapon.price;
	}
	if (player.ship.aftWeapon && player.ship.aftWeapon.price > 0) {
		value += player.ship.aftWeapon.price;
	}
	if (player.ship.starboardWeapon && player.ship.starboardWeapon.price > 0) {
		value += player.ship.starboardWeapon.price;
	}
	if (player.ship.forwardWeapon && player.ship.forwardWeapon.price > 0) {
		value += player.ship.forwardWeapon.price;
	}
	return value / 10;
}

//pay with equipment
this._sellEquipment = function () {

	var stripped = new Array();
	var oldBalance = player.credits;

	//strip the missiles
	var missiles = player.ship.missiles;
	for (var i = 0; i < missiles.length; i++) {
		if (player.credits < 30000) {
			if (missiles[i].price > 0) {
				player.credits += missiles[i].price / 10;
				stripped.push(missiles[i].name);
				player.ship.removeEquipment(missiles[i]);
			}
		}
	}
	//strip equipment except for LCB and berths. EQ_CARGO_BAY,EQ_PASSENGER_BERTH
	var equipments = player.ship.equipment;
	for (var i = 0; i < equipments.length; i++) {
		if (player.credits < 30000) {
			if (equipments[i].price > 0 && player.ship.equipmentStatus(equipments[i]) === "EQUIPMENT_OK" && equipments[i].equipmentKey !== "EQ_CARGO_BAY" && equipments[i].equipmentKey !== "EQ_PASSENGER_BERTH") {
				player.credits += equipments[i].price / 10;
				stripped.push(equipments[i].name);
				player.ship.removeEquipment(equipments[i]);
			}
		}
	}
	//strip lasers
	if (player.credits < 30000) {
		if (player.ship.portWeapon && player.ship.portWeapon.price > 0) {
			player.credits += player.ship.portWeapon.price / 10;
			stripped.push([player.ship.portWeapon.name, player.ship.portWeapon.price / 10]);
			player.ship.boardWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.starboardWeapon && player.ship.starboardWeapon.price > 0) {
			player.credits += player.ship.starboardWeapon.price / 10;
			stripped.push(player.ship.starboardWeapon.name);
			player.ship.starboardWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.aftWeapon && player.ship.aftWeapon.price > 0) {
			player.credits += player.ship.aftWeapon.price / 10;
			stripped.push(player.ship.aftWeapon.name);
			player.ship.aftWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.forwardWeapon && player.ship.forwardWeapon.price > 0) {
			player.credits += player.ship.forwardWeapon.price / 10;
			stripped.push(player.ship.forwardWeapon.name);
			player.ship.forwardWeapon = null;
		}
	}


	return ([stripped, player.credits - oldBalance]);
}

this._sellShip = function () {
	//no matter in what condition the player ship is, always sell for 50% of mint price
	var refundFactor = 0.5;
	player.credits += player.ship.price * refundFactor;
	player.replaceShip("adder-player");
	player.ship.removeEquipment("EQ_HEAT_SHIELD");
	player.ship.removeEquipment("EQ_MISSILE");
	player.ship.serviceLevel = 75;
}


//clean up mission variables and restore target system
this._cleanUp = function () {
	if (missionVariables.monk_dest_name) {
		player.ship.hudHidden = false;
		delete missionVariables.monk_dest_name;
		delete missionVariables.monk_time;
		delete missionVariables.monk_deadline;
		player.ship.targetSystem = this.$restoreDestination;
	}
}

this.guiScreenWillChange = function (to, from) {
	if (this.$contract && to === "GUI_SCREEN_MANIFEST") {
		var secsLeft = this.$contract["dealine"] - clock.seconds;
		var hoursLeft = Math.floor((secsLeft) / 3600);
		if (hoursLeft > 0) {
			var daysText = expandMissionText("monk_hours_left", { hours: hoursLeft });
		}
		else if (hoursLeft === 0) {
			var daysText = expandMissionText("monk_hour_left");
		}
		else var daysText = expandMissionText("monk_deadline_passed");
		mission.setInstructions(expandMissionText("monk_demand", { system: System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name, days: daysText }));
	}
	else if (!this.$contract) {
		player.ship.hudHidden = false;
		mission.setInstructions(null);
	}
}

this._setOffer = function (action) {
	if (action === "next") {
		this.$offerPointer++;
		if (this.$offerPointer >= this.$destinations.length) {
			this.$offerPointer = 0;
		}
	}
	else if (action === "prev") {
		this.$offerPointer--;
		if (this.$offerPointer <= 0) {
			this.$offerPointer = this.$destinations.length - 1;
		}
	}
	var info = system.info.routeToSystem(this.$destinations[this.$offerPointer]);
	var origHours = info.time;
	this.$days = Math.ceil(origHours / 24) + Math.ceil(info.route.length / 12);//0.5 hours per system on route rounded up to full days
	missionVariables.monk_dest_name = this.$destinations[this.$offerPointer].name;
	missionVariables.monk_time = expandMissionText("monk_days_hours", { days: this.$days, hours: this.$days * 24 });
	missionVariables.monk_deadline = clock.days + this.$days;
}

this.systemWillPopulate = function () {

	if (this.$monkSystemIDs.indexOf(system.ID) !== -1) {
		system.setPopulator("blackmonk_station", {

			callback: function (pos) {
				var monastery = system.addShips("blackmonk_monastery", 1, pos, 0)[0];
				monastery.orientation = [1, 0, 1, 0];
				var minesweepers = system.addShips("blackmonk_minesweeper", 10, pos, 15E3);
				for (var i = 0; i < minesweepers.length; i++) {
					//init the alert mechanism of minesweepers.
					minesweepers[i].script.$mother = monastery;
				}
			}.bind(this),
			location: "LANE_WP",
			locationSeed: 937,
			deterministic: true
		});
	}

	//retribution time

	//now the player is in trouble. increasing number of gunships are being spawned close to the witchpoint every time the player enters a system.
	if (this.$contract && this.$contract["dealine"] - clock.seconds < 0) {
		var count = Math.ceil((clock.seconds - this.$contract["dealine"]) / 86400);
		if (count > 5) count = 5;
		system.setPopulator("blackmonk_punishers", {
			callback: function (pos) {
				system.addGroup("blackmonk_gunship", count, pos);
			}.bind(this),
			location: "WITCHPOINT"
		});
	}

	//ambiance

	//gunships are ridiculously powerful, but very rare. roughly every tenth system has one cruising. running contract doubles the odds to start with and ramps them up close to the deadline.
	if (this.$contract) {
		var div = (Math.ceil(this.$contract["dealine"] - clock.seconds) / 86400);
		if (div >= 2) {
			var prob = 2 / (Math.ceil(this.$contract["dealine"] - clock.seconds) / 86400);
			if (prob < 0.2) prob = 0.2;
		}
		else var prob = 1;
	}
	else var prob = 0.1;

	if (Math.random() < prob) {
		system.setPopulator("blackmonk_ambience_gunship", {
			callback: function (pos) {
				//half the time, spawn ambiance ships close to the witchpoint and move them a bit closer to the planet. a bit is a 0.75 * scanner range. it's a bit boring to all the time have them sitting next to the witchpoint. a bit too staged to my liking.
				if (Math.random() < 0.5) {
					var gunship = system.addShips("blackmonk_gunship", 1)[0];
					gunship.position = gunship.position.add([0, 0, 19200]);
					var debtor = system.addShips("trader", 1, gunship.position)[0];
				}
				else {
					var gunship = system.addShips("blackmonk_gunship", 1, pos)[0];
					var debtor = system.addShips("trader", 1, gunship.position)[0];
				}
				debtor.$monkDebtor = true;
				debtor.fuel = 0;//no escape
			}.bind(this),
			location: "LANE_WP"
		});
		//this is a long shot, a lonely debtor leisurely cruising the lane. with some seriusly bad load of luck it just might meet a blackmonk gunship.
		system.setPopulator("blackmonk_ambiance_wandering_debtor", {
			callback: function (pos) {
				var debtor = system.addShips("trader", 1, pos)[0];
				debtor.$monkDebtor = true;
				debtor.fuel = 0;//no escape
			}.bind(this),
			location: "LANE_WP"
		});
	}
}
