"use strict";
this.name = "GalCopBB_Charity";
this.author = "phkb";
this.copyright = "2017 phkb";
this.description = "Adds charity missions to the Bulletin Board (80-88)";
this.license = "CC BY-NC-SA 4.0";

/*
	type 80: donation to AI
	type 81: donation to TWOS
	type 82: donation to MCEP
	type 83: donation to PMHS
	type 84: slave cargo donation to AI
	type 85: cargo donation to TWOS
	type 86: cargo donation to MCEP
	type 87: cargo donation to PMHS
	type 88: cargo donation to AI
	type 89: donation for liberation front of system
		how to apply system changes for this "charity"
			- multiple items (eg commodities and equipment)
	type 90: donation to religious group
		how to apply system changes for this charity
			- bounty
*/

this._debug = true;
this._trueValues = ["yes", "1", 1, "true", true];

//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
	var gcm = worldScripts.GalCopBB_Missions;
	this._debug = gcm._debug;
	// add these mission types into the main control
	var list = [80, 81, 82, 83, 84, 85, 86, 87];
	gcm._availableMissionTypes = gcm._availableMissionTypes.concat(list);
	// add our reputation entities
	var ent = worldScripts.GalCopBB_Reputation._entities;
	ent[expandDescription("[gcm_reputation_amnesty]")] = {
		scope: "galactic",
		display: true,
		getValueWS: "",
		getValueFN: "",
		maxValue: 210,
		minValue: 0,
		degrade: "1|30",
		impact: "bounty",
		rewardGrid: [{
			value: 0,
			description: "[gcmAIRep0]",
			impactValue: 0
		},
		{
			value: 1,
			description: "[gcmAIRep1]",
			impactValue: 0
		},
		{
			value: 20,
			description: "[gcmAIRep2]",
			impactValue: 0,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$AI_Rewards"
		},
		{
			value: 35,
			description: "[gcmAIRep3]",
			impactValue: 0,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$AI_Rewards"
		},
		{
			value: 60,
			description: "[gcmAIRep4]",
			impactValue: 0.25,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$AI_Rewards"
		},
		{
			value: 90,
			description: "[gcmAIRep5]",
			impactValue: 0.5,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$AI_Rewards"
		},
		{
			value: 130,
			description: "[gcmAIRep6]",
			impactValue: 0.75,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$AI_Rewards"
		},
		{
			value: 200,
			description: "[gcmAIRep7]",
			impactValue: 1,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$AI_Rewards"
		},
		]
	};
	// Traders Widows and Orphans
	ent["gcmTWOSTitle$G"] = {
		scope: "system",
		display: true,
		getValueWS: "",
		getValueFN: "",
		maxValue: 210,
		minValue: 0,
		degrade: "1|30",
		impact: "markets",
		impactAllegiance: "galcop",
		rewardGrid: [{
			value: 0,
			description: "[gcmTWOSRep0]",
			impactValue: 0
		},
		{
			value: 1,
			description: "[gcmTWOSRep1]",
			impactValue: 0
		},
		{
			value: 20,
			description: "[gcmTWOSRep2]",
			impactValue: 0,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$TWOS_Rewards"
		},
		{
			value: 35,
			description: "[gcmTWOSRep3]",
			impactValue: 0.01,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$TWOS_Rewards"
		},
		{
			value: 60,
			description: "[gcmTWOSRep4]",
			impactValue: 0.02,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$TWOS_Rewards"
		},
		{
			value: 90,
			description: "[gcmTWOSRep5]",
			impactValue: 0.04,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$TWOS_Rewards"
		},
		{
			value: 130,
			description: "[gcmTWOSRep6]",
			impactValue: 0.07,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$TWOS_Rewards"
		},
		{
			value: 200,
			description: "[gcmTWOSRep7]",
			impactValue: 0.1,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$TWOS_Rewards"
		}
		]
	};
	// mechanics childrens education fund
	ent["gcmMCEPTitle$G"] = {
		scope: "system",
		display: true,
		getValueWS: "",
		getValueFN: "",
		maxValue: 210,
		minValue: 0,
		degrade: "1|30",
		impact: "equipment",
		impactAllegiance: "galcop",
		rewardGrid: [{
			value: 0,
			description: "[gcmMCEPRep0]",
			impactValue: 0
		},
		{
			value: 1,
			description: "[gcmMCEPRep1]",
			impactValue: 0
		},
		{
			value: 20,
			description: "[gcmMCEPRep2]",
			impactValue: 0,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$MCEP_Rewards"
		},
		{
			value: 35,
			description: "[gcmMCEPRep3]",
			impactValue: 0.01,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$MCEP_Rewards"
		},
		{
			value: 60,
			description: "[gcmMCEPRep4]",
			impactValue: 0.02,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$MCEP_Rewards"
		},
		{
			value: 90,
			description: "[gcmMCEPRep5]",
			impactValue: 0.04,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$MCEP_Rewards"
		},
		{
			value: 130,
			description: "[gcmMCEPRep6]",
			impactValue: 0.07,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$MCEP_Rewards"
		},
		{
			value: 200,
			description: "[gcmMCEPRep7]",
			impactValue: 0.1,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$MCEP_Rewards"
		}
		]
	};
	// pilots mental health service
	ent["gcmPMHSTitle$G"] = {
		scope: "system",
		display: true,
		getValueWS: "",
		getValueFN: "",
		maxValue: 210,
		minValue: 0,
		degrade: "1|30",
		impact: "ships",
		impactAllegiance: "galcop",
		rewardGrid: [{
			value: 0,
			description: "[gcmPMHSRep0]",
			impactValue: 0
		},
		{
			value: 1,
			description: "[gcmPMHSRep1]",
			impactValue: 0
		},
		{
			value: 20,
			description: "[gcmPMHSRep2]",
			impactValue: 0,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$PMHS_Rewards"
		},
		{
			value: 35,
			description: "[gcmPMHSRep3]",
			impactValue: 0.01,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$PMHS_Rewards"
		},
		{
			value: 60,
			description: "[gcmPMHSRep4]",
			impactValue: 0.02,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$PMHS_Rewards"
		},
		{
			value: 90,
			description: "[gcmPMHSRep5]",
			impactValue: 0.04,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$PMHS_Rewards"
		},
		{
			value: 130,
			description: "[gcmPMHSRep6]",
			impactValue: 0.07,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$PMHS_Rewards"
		},
		{
			value: 200,
			description: "[gcmPMHSRep7]",
			impactValue: 0.1,
			achievementWS: "GalCopBB_Charity",
			achievementFN: "$PMHS_Rewards"
		}
		]
	};
}

//-------------------------------------------------------------------------------------------------------------
// executed if the player selected the "give cargo and continue" option
this.$partialComplete = function $partialComplete(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var amt = player.ship.manifest[item.data.commodity];
	if (amt > 0 && (item.data.targetQuantity - item.data.quantity) >= 0) {
		if (amt > (item.data.targetQuantity - item.data.quantity)) amt = (item.data.targetQuantity - item.data.quantity);
		item.data.quantity += amt;
		player.ship.manifest[item.data.commodity] -= amt;
		bb.$updateBBMissionPercentage(item.ID, (item.data.quantity / item.data.targetQuantity));
	}
	// add a new custom menu (same as the old one which will be autoremoved)
	// but only if there is a possibility the player could do another partial complete
	if ((item.data.targetQuantity - item.data.quantity) >= 1) {
		var mnu = expandDescription("[missionType" + item.data.missionType + "_customMenu]");
		var itms = mnu.split("|");
		item.customMenuItems.push({
			text: itms[0],
			worldScript: itms[1],
			callback: itms[2],
			condition: itms[3],
			autoRemove: (this._trueValues.indexOf(itms[4]) >= 0 ? true : false)
		});
	}
}

//-------------------------------------------------------------------------------------------------------------
// checks if the partial load and continue menu can be selected by the player
this.$partialCondition = function $partialCondition(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var amt = player.ship.manifest[item.data.commodity];
	var result = "";
	if (amt === 0) result = "No " + displayNameForCommodity(item.data.commodity).toLowerCase() + " in cargo hold";
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// add additional reputation value for each 2000 cr in the donation
// so a donation of 10000 credits will result in a reputation increase of 5
this.$completeDonationMission = function $completeDonationMission(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var amt = item.data.targetQuantity;
	if (amt > player.credits) {
		amt = player.credits;
	}
	// if the player has a bounty, doing these missions will reduce it
	if (player.ship.bounty > 0) {
		player.ship.setBounty(player.ship.bounty - 1, "community service");
		if (amt > 10000 && player.ship.bounty >= 2) player.ship.setBounty(player.ship.bounty - 2, "community service");;
		player.ship.consoleMessage(expandDescription("[gcm_bounty_reduced]"));
	}
	var base = parseInt(expandDescription("[missionType" + item.data.missionType + "_reputationSuccess]"));
	// rep will increase by 1 anyway, so only increase if target is > 2000
	player.credits -= parseInt(amt);
	var rep = parseInt(amt) / 2000;
	if (rep <= 1) return;
	// increase the rep amount by the base amount
	for (var i = 1; i < rep; i++) {
		worldScripts.GalCopBB_Reputation.$adjustReputationSuccess(item.data.missionType, item.source, item.destination, base);
	}
}

//-------------------------------------------------------------------------------------------------------------
// add additional reputation value for each t/kg/g in the donation
// so a donation of 6 t will result in a reputation increase of 3
this.$completeCargoMission = function $completeCargoMission(missID) {
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	var amt = item.data.targetQuantity;
	var base = parseInt(expandDescription("[missionType" + item.data.missionType + "_reputationSuccess]"));
	var rep = parseInt(amt / 2);
	if (rep < 1) return;
	// increase the rep amount by the base amount
	for (var i = 1; i < rep; i++) {
		worldScripts.GalCopBB_Reputation.$adjustReputationSuccess(item.data.missionType, item.source, item.destination, base);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$TWOS_Rewards = function $TWOS_Rewards(entity, sysID, repLevel) {
	// apart from medals, TWOS rewards player by increasing/decreasing value of commodities
	// commodity price adjustments made by reputation script
}

//-------------------------------------------------------------------------------------------------------------
this.$AI_Rewards = function $AI_Rewards(entity, sysID, repLevel) {
	// apart from medals, AI rewards player by reducing any bounty
	worldScripts.GalCopBB_Reputation.$performBountyAdjustment(entity);
}

//-------------------------------------------------------------------------------------------------------------
this.$MCEP_Rewards = function $MCEP_Rewards(entity, sysID, repLevel) {
	// apart from medals, MCEP rewards players by providing a cash-back on items purchased on F3 screen
	// commodity price adjustments made by reputation script
}

//-------------------------------------------------------------------------------------------------------------
this.$PMHS_Rewards = function $PMHS_Rewards(entity, sysID, repLevel) {
	// apart from medals, PMHS rewards players by providing a cash-back on new ship purchases
	// commodity price adjustments made by reputation script
}

//-------------------------------------------------------------------------------------------------------------
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);

	// missions 80 - 83 donation missions	
	if (item.data.missionType >= 80 && item.data.missionType <= 83) {
		// automatically set this item to "complete" status
		bb.$updateBBMissionPercentage(item.ID, 1);
	}
}

//-------------------------------------------------------------------------------------------------------------
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);

	// mission types 80-83 (donation missions)
	if (item.data.missionType >= 80 && item.data.missionType <= 83) {
		this.$completeDonationMission(item.ID);
	}
	// mission types 84-87 (cargo donation missions)
	if (item.data.missionType >= 84 && item.data.missionType <= 87) {
		this.$completeCargoMission(item.ID);
	}
	// mission type 84 - repatriate slaves on station
	// mission types 85/86/87 - donate cargo
	if (item.data.missionType === 84 || item.data.missionType === 85 || item.data.missionType === 86 || item.data.missionType === 87) {
		var amt = 0;
		// we can partially complete these, so only take out what the player has
		if (p.manifest[item.data.commodity] >= item.data.targetQuantity) {
			p.manifest[item.data.commodity] -= item.data.targetQuantity;
			amt = item.data.targetQuantity;
		} else {
			amt = p.manifest[item.data.commodity];
			p.manifest[item.data.commodity] = 0;
		}
		if (worldScripts.market_observer3 && amt > 0) {
			var mo = worldScripts.market_observer3;
			mo.playerSoldCargo(item.data.commodity, amt, 0);
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$confirmCompleted = function $confirmCompleted(missID) {
	var p = player.ship;
	var m = p.manifest;
	var result = "";
	var bb = worldScripts.BulletinBoardSystem;
	var item = bb.$getItem(missID);
	if (item) {
		// mission types 80-83 (donation missions)
		if (item.data.missionType >= 80 && item.data.missionType <= 83) {
			if (player.credits < item.data.target) {
				//result += (result === "" ? "" : "\n") + "Insufficient funds to meet the donation amount.";
			}
		}
		// *** type 84 - repatriate slaves
		// *** type 85/85/87 - donate cargo
		if (item.data.missionType === 84 || item.data.missionType === 85 || item.data.missionType === 86 || item.data.missionType === 87) {
			if (m[item.data.commodity] < (item.data.targetQuantity - item.data.quantity)) {
				var unit = worldScripts.GalCopBB_Missions.$getCommodityUnit(item.data.commodity);
				result += (result === "" ? "" : "\n") + expandDescription("[gcm_insufficient_cargo]", { commodity: displayNameForCommodity(item.data.commodity).toLowerCase(), target: item.data.targetQuantity, unit:"t" });
			}
		}
	}
	return result;
}

//-------------------------------------------------------------------------------------------------------------
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.$addMissionHistory(item.source, item.data.missionType, 0, 1);

		// reputation only goes in one way (up or down)
		// so even if the player completes 90% of a mission and then terminates it, their reputation will go down even if they received most of the payment credits
		var rep = worldScripts.GalCopBB_Reputation;
		if (rep._disabled === false) {
			rep.$adjustReputationFailure(item.data.missionType, item.source, item.destination, item.percentComplete);
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$failedMission = function $failedMission(missID) {
	this.$terminateMission(missID);
}

//-------------------------------------------------------------------------------------------------------------
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);
}

//-------------------------------------------------------------------------------------------------------------
// cash donations
this.$missionType80818283_Values = function $missionType80818283_Values(workTime, routeTime, routeDistance, destSysInfo) {
	if (player.score < 1000) return null;

	var factor = Math.floor(Math.round(player.score / 1000));
	var amt = (Math.floor(Math.random() * (6 + factor)) + 1) * 1000;
	if (amt === 0) return null;

	var result = {};
	result["quantity"] = amt;
	result["expiry"] = -1;
	result["donation"] = amt;

	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 84 - give slaves to AI
this.$missionType84_Values = function $missionType84_Values(workTime, routeTime, routeDistance, destSysInfo) {
	if (!system.mainStation) return null;
	var slaves = system.mainStation.market["slaves"].quantity;
	if (slaves === 0) return null;
	var result = {};
	result["quantity"] = slaves;
	result["commodity"] = "slaves";
	result["price"] = 0;
	result["expiry"] = -1;
	return result;
}

//-------------------------------------------------------------------------------------------------------------
// 85/86/87 - cargo donation to entity
this.$missionType858687_Values = function $missionType858687_Values(workTime, routeTime, routeDistance, destSysInfo) {
	if (system.ID === -1) return null;
	// we're leaving out food, textiles 
	var c_types = ["luxuries", "computers", "furs", "liquor_wines", "alloys", "radioactives", "alien_items", "machinery", "gold", "platinum", "gem_stones"];
	var result = {};
	var tries = 0;
	result["quantity"] = 0;
	// make sure we don't create missions where the quantity of cargo is more than the player ship
	//var max = player.ship.cargoSpaceCapacity;
	var max = 128;
	// work out mission details - commodity and quantity
	do {
		result["commodity"] = c_types[Math.floor(Math.random() * c_types.length)];;
		result["quantity"] = max;
		//if ("gold platinum gem_stones".indexOf(result.commodity) >= 0) result.quantity = system.mainStation.market[result.commodity].quantity;
		// make sure we only set a quantity the local system can provide
		if (system.mainStation.market[result.commodity].quantity < result.quantity) result.quantity = parseInt(system.mainStation.market[result.commodity].quantity * (Math.random() * 0.4 + 0.5));
		tries += 1;
	} while (result.quantity > max || result.quantity <= 0 || tries < 5);
	// if we aborted the loop, just return null
	if (tries >= 5 && (result.quantity > max || result.quantity === 0)) return null;
	// otherwise, just set a token reward - player will also receive bonus from waiting ship
	// make sure the deposit amount is included in the price so the BB knows how to display it
	result["price"] = 0;
	result["expiry"] = -1;
	result["penalty"] = 0;
	return result;
}