/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string} Slave's scar. Slave is the slave in question, but call the body part without modifiers. Rather than using "left breast" and "right breast" just use "breast". The function will then describe any scars on the breasts, if present, in natural language.
 */
App.Desc.scar = function(slave, surface) {
	"use strict";
	let r = ``;
	const bellyAccessory = slave.bellyAccessory;
	/* eslint-disable no-unused-vars*/
	const {
		he, him, his, hers, himself, boy, He, His
	} = getPronouns(slave);
	/* eslint-enable */
	if (V.showBodyMods === 1) {
		if (surface === "extra") { // Make a sentence that describes all body parts that aren't explicitly described elsewhere in longSlave. If you scar a slave on her thumb, for instance. But why.
			let extraMarks = App.Desc.extraMarks(slave, "scar");
			extraMarks = Object.keys(extraMarks);
			let length = extraMarks.length;
			if (length === 0) {
				return r;
			} else if (length === 1) {
				r += `${He} also has a single unusual scar: `;
			} else {
				r += `${He} also has several unusual scars: `;
			}

			// If L/R parts of this object match, they will be described in the same phrase. Length is used only to calculate punctuation, so we prepare to skip.
			for (const bodyPart of extraMarks) {
				if (bodyPart.startsWith("left ")) {
					let right = "right " + bodyPart.replace("left ", "");
					if (slave.scar[bodyPart] && slave.scar[right]) {
						length--;
					}
				}
			}
			let counter = 0;
			for (const bodyPart of extraMarks) {
				counter++;
				surface = App.Desc.oppositeSides(bodyPart);
				if (slave.scar[surface.center]) { // center defined, body part has no mirror.
					r += `${App.Desc.expandScarString(slave, surface.center)} on ${his} ${surface.center}`;
				} else { // Center not defined, body part has a mirror.
					let left = App.Desc.expandScarString(slave, surface.left);
					let right = App.Desc.expandScarString(slave, surface.right);
					if (!slave.scar[surface.left] && !slave.scar[surface.right]) {
						// no marks
					} else if (bodyPart.startsWith("right ") && slave.scar[surface.left]) {
						// we already described it on the left
					} else if (left === right) {
						// matching places and marks
						// note that the slave.scar object won't have slave.scar["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
						r += `${left} on both ${his} ${surface.both}`;
					} else if (slave.scar[surface.left] && slave.scar[surface.right]) {
						// matching places but different marks
						r += `both ${left} on ${his} ${surface.left}, and ${right} scared into ${his} ${surface.right}`;
					} else if (slave.scar[surface.left]) {
						// left
						r += `${left} on ${his} ${surface.left}`;
					} else if (slave.scar[surface.right]) {
						// right
						r += `${right} on ${his} ${surface.right}`;
					}
				}
				if (counter === length) {
					r += `. `;
				} else if (counter === length - 1) {
					r += `, and `;
				} else if (counter < length) {
					r += `, `;
				}
			}
		} else if (surface) { /* describes a single scarred body part */
			surface = App.Desc.oppositeSides(surface);
			if (surface.center === "belly" && setup.fakeBellies.includes(bellyAccessory) && slave.scar.hasOwnProperty("belly")) {
				r += `${His} fake belly has the same scar, ${App.Desc.expandScarString(slave, surface.center)}, as ${his} real one. `;
			} else {
				if (slave.scar[surface.center]) { // center defined, body part has no mirror.
					r += `${He} has ${App.Desc.expandScarString(slave, surface.center)} on ${his} ${surface.center}. `;
				} else { // Center not defined, body part has a mirror.
					let left = App.Desc.expandScarString(slave, surface.left);
					let right = App.Desc.expandScarString(slave, surface.right);
					if (!slave.scar[surface.left] && !slave.scar[surface.right]) {
						// no marks
					} else if (left === right) {
						// matching places and marks
						// note that the slave.scar object won't have slave.scar["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
						r += `${He} has ${left} on both ${his} ${surface.both}. `;
					} else if (slave.scar[surface.left] && slave.scar[surface.right]) {
						// matching places but different marks
						r += `${He} has both ${left} on ${his} ${surface.left}, and ${right} scared into ${his} ${surface.right}. `;
					} else if (slave.scar[surface.left]) {
						// left
						r += `${He} has ${left} on ${his} ${surface.left}. `;
					} else if (right) {
						// right
						r += `${He} has ${right} on ${his} ${surface.right}. `;
					}
				}
			}
		} else { /* describes all scarred body parts */
			for (let [key, value] of Object.entries(slave.scar)) {
				if (r === ``) {
					r += `${He} has `;
				}
				if (key === "belly" && setup.fakeBellies.includes(bellyAccessory) && slave.scar.hasOwnProperty("belly")) {
					r += `${value} scared on both ${his} real belly and ${his} fake one, `;
				} else {
					r += `${value} on ${his} ${key}, `;
				}
			}
			if (r !== ``) {
				r += `marking ${him} as yours. `;
			} else {
				r += `${His} body is unmarked by scars. `;
			}
		}
	}
	return r;
};

/**
 * @param {App.Entity.SlaveState} slave
 * @returns {string} Slave's scar. Slave is the slave in question, but call the body part without modifiers. Rather than using "left breast" and "right breast" just use "breast". The function will then describe any scars on the breasts, if present, in natural language.
 */
App.Desc.expandScarString = function(slave, surface) { // scars can sometimes be an int. This function generates a reasonable description. It can later be expanded to apply to different body parts, or include features of the slave such as skin tone or weight
	let r = "";
	if (!slave.scar[surface]) {
		return r;
	}
	const {he, his} = getPronouns(slave);
	const bodypart = Object.keys(slave.scar[surface]);
	for (const kind of bodypart) {
		let scar = slave.scar[surface][kind];
		if (scar === 0) {
			continue;
		}
		if (r !== "") {
			r += ", ";
		}
		switch (kind) {
			case "generic":
				r += "a generic scar";
				break;
			case "whip":
				if (["back"].includes(surface)) {
					r += "a ";
					if (scar > 2) {
						r += "deeply scored ";
					}
					if (scar > 1) {
						r += "network of welts like a map of hell";
					} else {
						r += "record of being beaten";
					}
				} else if (["left breast", "right breast", "left buttock", "right buttock"].includes(surface)) {
					if (scar > 2) {
						r += "thick ";
					} else {
						r += "thin ";
					}
					r += "raised lines from a whip tracing the curves";
				} else if (["left upper arm", "right upper arm"].includes(surface)) {
					r += `rough edges where a whip abused ${his} skin`;
				} else {
					if (scar > 2) {
						r += "frightening ";
					} else if (scar > 1) {
						r += "serious ";
					}
					r += "whip scars";
				}
				break;
			case "chain":
				if (["left wrist", "right wrist", "left ankle", "right ankle"].includes(surface)) {
					if (scar > 1) {
						r += "scars from heavy manacles";
					} else {
						r += "scars from manacles";
					}
				} else {
					if (scar > 1) {
						r += "scars from heavy chains";
					} else {
						r += "scars from chains";
					}
				}
				break;
			case "burn":
				if (scar > 2) {
					r += "frightening ";
				} else if (scar > 1) {
					r += "serious ";
				}
				r += "burn scars";
				break;
			case "menacing":
				r += "a menacing scar";
				break;
			case "exotic":
				r += "an exotic scar";
				break;
			case "surgical":
				if (surface === "left breast" || surface === "right breast") {
					if (slave.boobsImplant > 0) {
						r += "scars from ";
						if (scar > 3) {
							r += "horribly botched ";
						} else if (scar > 2) {
							r += "sloppily inserted ";
						} else if (scar > 1) {
							r += "carelessly inserted ";
						}
						r += "implants";
					} else {
						r += "scars from ";
						if (scar > 3) {
							r += "horribly botched ";
						} else if (scar > 2) {
							r += "sloppily done ";
						} else if (scar > 1) {
							r += "carelessly done ";
						}
						r += "surgery to remove implants";
					}
				} else if (surface === "left buttock" || surface === "right buttock") {
					if (slave.buttImplant > 0) {
						r += "scars from ";
						if (scar > 3) {
							r += "horribly botched ";
						} else if (scar > 2) {
							r += "sloppily inserted ";
						} else if (scar > 1) {
							r += "carelessly inserted ";
						}
						r += "implants";
					} else {
						r += "scars from ";
						if (scar > 3) {
							r += "horribly botched ";
						} else if (scar > 2) {
							r += "sloppily done ";
						} else if (scar > 1) {
							r += "carelessly done ";
						}
						r += "surgery to remove implants";
					}
				} else if (surface === "belly" ) {
					r += "scars from ";
					if (scar > 1) {
						r += "a crazy network of scars, as though a hack had tried internal surgery";
					} else {
						r += "some faint scarring as though from internal surgery";
					}
				} else {
					r += "a ";
					if (scar > 1) {
						r += "pronounced ";
					} else {
						r += "faint ";
					}
					r += "surgical scar";
				}
				break;
			case "c-section":
				r += "an ";
				if (scar > 1) {
					r += "especially ";
				}
				r += "unsightly c-section scar";
				break;
			case "cutting":
				if (["left wrist", "right wrist", "neck"].includes(surface)) {
					r += `some scars as though ${he} attempted self harm`;
				} else {
					r += "some cuts as though from a razor";
				}
				break;
			default:
				if (scar > 2) {
					r += "serious ";
				} else if (scar) {
					r += kind;
				}
				break;
		}
	}
	r = r.replace(/,(?=[^,]*$)/, ' and'); /* replace the last comma with the word "and" so we can use this in a sentence.*/
	return r;
};

src/npc/descriptions/describeScars.js