// Woo-woo incense description generator

const adjective = [
	"aromatic",
	"climatic",
	"cooling",
	"deep",
	"dulled",
	"effervescent",
	"effluent",
	"effulgent",
	"endless",
	"evocative",
	"grounding",
	"healing",
	"hidden",
	"indolent",
	"juicy",
	"lactescent",
	"lingering",
	"ministerial",
	"nourishing",
	"open",
	"precious",
	"pungent",
	"resonant",
	"restless",
	"sacred",
	"sensual",
	"shimmering",
	"sparkling",
	"still",
	"undulating",
	"unparalleled",
	"warming",
];

const noun = [
	["astrology", "astrologies"],
	["bloom", "blooms"],
	["breath", "breaths"],
	["chakra", "chakras"],
	["clarity", "clarities"],
	["contribution", "contributions"],
	["curiosity", "curiosities"],
	["direction", "directions"],
	["ember", "embers"],
	["connection", "connections"],
	["constriction", "constrictions"],
	["coolness", "coolnesses"],
	["expression", "expressions"],
	["fire", "fires"],
	["geometry", "geometries"],
	["glow", "glows"],
	["harmony", "harmonies"],
	["meaning", "meanings"],
	["nourishment", "nourishments"],
	["onanism", "onanisms"],
	["relationship", "relationships"],
	["resonance", "resonances"],
	["ritual", "rituals"],
	["smoke", "smokes"],
	["space", "spaces"],
	["surface", "surfaces"],
	["tantra", "tantras"],
	["tension", "tensions"],
	["transformation", "transformations"],
	["vibration", "vibrations"],
	["wonder", "wonders"],
];

const bodyPart = [
	"appendix",
	"armpit",
	"bile",
	"central core",
	"cheeks",
	"chest",
	"cuticles",
	"diaphragm",
	"fingernails",
	"flaps",
	"folds",
	"frenulum",
	"goiter",
	"humors",
	"limbs",
	"lingam",
	"legs",
	"lungs",
	"meatus",
	"mind",
	"paunch",
	"perineum",
	"ribs",
	"spine",
	"spleen",
	"throat",
	"uvula",
	"yoni",
	"wenis",
];

const affliction = [
	"abasement",
	"acne",
	"appropriation",
	"bodaciousness",
	"cirrhosis",
	"concavity",
	"confiscation",
	"corpulence",
	"defenestration",
	"denunciation",
	"despondency",
	"erosion",
	"exasperation",
	"fatigue",
	"fibrillation",
	"flaking",
	"hardening",
	"hypertension",
	"ill-humor",
	"imbalance",
	"impertinence",
	"impotence",
	"impropriety",
	"incontinence",
	"indolence",
	"ingrowth",
	"itching",
	"leprosy",
	"malignancy",
	"mastication",
	"melancholia",
	"miasma",
	"mistreatment",
	"mortification",
	"necrosis",
	"plasticity",
	"protuberance",
	"psoriasis",
	"putrescence",
	"rumination",
	"schadenfreude",
	"scruples",
	"seizure",
	"sinkage",
	"softening",
	"stoppage",
	"swelling",
	"whiffiness",
];

const verb = [
	["appreciate", "appreciates", "appreciating"],
	["blend", "blends", "blending"],
	["bloom", "blooms", "blooming"],
	["breathe", "breathes", "breathing"],
	["carry", "carries", "carrying"],
	["calm", "calms", "calming"],
	["cleanse", "cleanses", "cleansing"],
	["clear", "clears", "clearing"],
	["consolidate", "consolidates", "consolidating"],
	["cool", "cools", "cooling"],
	["dance", "dances", "dancing"],
	["descend", "descends", "descending"],
	["discern", "discerns", "discerning"],
	["exacerbate", "exacerbates", "exacerbating"],
	["fold", "folds", "folding"],
	["govern", "governs", "governing"],
	["harmonize", "harmonizes", "harmonizing"],
	["linger", "lingers", "lingering"],
	["masticate", "masticates", "masticating"],
	["nourish", "nourishes", "nourishing"],
	["retract", "retracts", "retracting"],
	["scatter", "scatters", "scattering"],
	["shift", "shifts", "shifting"],
	["sink", "sinks", "sinking"],
	["soften", "softens", "softening"],
	["tingle", "tingles", "tingling"],
	["titillate", "titillates", "titillating"],
	["ululate", "ululates", "ululating"],
	["undulate", "undulates", "undulating"],
	["vent", "vents", "venting"],
	["vindicate", "vindicates", "vindicating"],
	["warm", "warms", "warming"],
	["waver", "wavers", "wavering"],
	["weave", "weaves", "weaving"],
];

const healingMethod = [
	["abate", "abates", "abating"],
	["alleviate", "alleviates", "alleviating"],
	["assuage", "assuages", "assuaging"],
	["balance", "balances", "balancing"],
	["broaden", "broadens", "broadening"],
	["cool", "cools", "cooling"],
	["discipline", "disciplines", "disciplining"],
	["edify", "edifies", "edifying"],
	["elevate", "elevates", "elevating"],
	["enrich", "enriches", "enriching"],
	["harmonize", "harmonizes", "harmonizing"],
	["heal", "heals", "healing"],
	["invigorate", "invigorates", "invigorating"],
	["lift", "lifts", "lifting"],
	["lighten", "lightens", "lightening"],
	["mitigate", "mitigates", "mitigating"],
	["promote", "promotes", "promoting"],
	["re-balance", "re-balances", "re-balancing"],
	["refine", "refines", "refining"],
	["regenerate", "regenerates", "regenerating"],
	["relieve", "relieves", "relieving"],
	["soften", "softens", "softening"],
	["sooth", "soothes", "soothing"],
	["uplift", "uplifts", "uplifting"],
	["warm", "warms", "warming"],
];

const recipe = [
	"agarbatti",
	"blend",
	"composition",
	"fragrance",
	"incense",
	"recipe",
	"stick",
];

const amount = [
	"base",
	"blessing",
	"boatload",
	"crumb",
	"dash",
	"dollop",
	"dusting",
	"glob",
	"hint",
	"pinch",
	"shred",
	"smattering",
	"smidgen",
	"sprinkling",
	"touch",
	"trace",
];

const preposition = [
	"above",
	"across",
	"after",
	"against",
	"along",
	"amid",
	"among",
	"around",
	"as",
	"before",
	"behind",
	"below",
	"beneath",
	"beside",
	"between",
	"beyond",
	"following",
	"from",
	"into",
	"like",
	"near",
	"onto",
	"opposite",
	"over",
	"past",
	"round",
	"through",
	"to",
	"toward",
	"under",
	"underneath",
	"upon",
	"versus",
	"via",
	"with",
	"within",
];

const ingredient = [
	"agarwood",
	"amber",
	"ambergris",
	"ambrette seed",
	"atlas cedar",
	"bergamot",
	"balsam of tolu",
	"basil",
	"bay laurel",
	"benzoin",
	"borneol camphor",
	"burgundy pitch",
	"calamus root",
	"cardamom",
	"cassia",
	"catnip",
	"chen pi",
	"chamomile",
	"cinnamon",
	"clove",
	"colophony pine",
	"copal",
	"coriander",
	"dammar",
	"dragon’s blood",
	"elemi",
	"eucalyptus",
	"frankincense",
	"galangal root",
	"galbanum",
	"ginger root",
	"guggul",
	"hibiscus",
	"hyssop",
	"juniper berry",
	"juniper",
	"labdanum",
	"laurel leaf",
	"lavender",
	"lemon balm",
	"lemon grass",
	"marjoram",
	"mastic",
	"mugwort",
	"musk root",
	"myrrh",
	"nutmeg",
	"oakmoss",
	"onycha",
	"opoponax",
	"orris root",
	"palo santo",
	"patchouli",
	"pine needle",
	"pine resin",
	"red cedar",
	"red sandalwood",
	"rose",
	"rosemary",
	"saffron",
	"sage",
	"sandalwood",
	"sandarac",
	"spikenard",
	"spruce",
	"star anise",
	"storax",
	"sweetgrass",
	"thyme",
	"tolu balsam",
	"tonka bean",
	"turkey rhubarb",
	"turmeric",
	"valerian",
	"vanilla",
	"vetiver",
	"weeping cypress",
];

const getWord = (wordArr, usedArr, tense, plural) => {
	if (wordArr == noun) {
		let word = wordArr[(wordArr.length * Math.random()) | 0][0];
		let pluralWord = wordArr[(wordArr.length * Math.random()) | 0][1];

		let wordIsUsed = usedArr.indexOf(word) >= 0 ? true : false;
		let pluralIsUsed = usedArr.indexOf(pluralWord) >= 0 ? true : false;

		while (wordIsUsed == true || pluralIsUsed == true) {
			word = wordArr[(wordArr.length * Math.random()) | 0][0];
			pluralWord = wordArr[(wordArr.length * Math.random()) | 0][1];

			wordIsUsed = usedArr.indexOf(word) >= 0 ? true : false;
			pluralIsUsed = usedArr.indexOf(word) >= 0 ? true : false;
		}

		return plural ? pluralWord : word;
	} else if (wordArr == verb || wordArr == healingMethod) {
		let word = wordArr[(wordArr.length * Math.random()) | 0][0];
		let present = wordArr[(wordArr.length * Math.random()) | 0][1];
		let continuous = wordArr[(wordArr.length * Math.random()) | 0][2];

		let wordIsUsed = usedArr.indexOf(word) >= 0 ? true : false;
		let presentIsUsed = usedArr.indexOf(present) >= 0 ? true : false;
		let continuousIsUsed = usedArr.indexOf(continuous) >= 0 ? true : false;

		while (
			wordIsUsed == true ||
			presentIsUsed == true ||
			continuousIsUsed == true
		) {
			word = wordArr[(wordArr.length * Math.random()) | 0][0];
			present = wordArr[(wordArr.length * Math.random()) | 0][1];
			continuous = wordArr[(wordArr.length * Math.random()) | 0][2];

			wordIsUsed = usedArr.indexOf(word) >= 0 ? true : false;
			presentIsUsed = usedArr.indexOf(word) >= 0 ? true : false;
			continuousIsUsed = usedArr.indexOf(continuous) >= 0 ? true : false;
		}

		if (tense == "present") {
			return present;
		} else if (tense == "continuous") {
			return continuous;
		} else {
			return word;
		}
	} else {
		let word = wordArr[(wordArr.length * Math.random()) | 0];
		let isUsed = usedArr.indexOf(word) >= 0 ? true : false;

		while (isUsed == true) {
			word = wordArr[(wordArr.length * Math.random()) | 0];
			isUsed = usedArr.indexOf(word) >= 0 ? true : false;
		}

		return word;
	}
};

const capitalize = (str) => {
	return str[0].toUpperCase() + str.slice(1);
};

const coinFlip = () => {
	return Math.random() < 0.5 ? true : false;
};

const randomNumber = (min, max) => {
	return Math.floor(Math.random() * (max - min + 1) + min);
};

const descriptionConstructor = (
	adjective,
	noun,
	bodyPart,
	verb,
	preposition,
	ingredient,
) => {
	let used = [];
	let description = "<p>";
	let currentWord = "";

	const addWord = (list, plural, punctuation, tense, capitalizeBool) => {
		currentWord = getWord(list, used, tense, plural);

		capitalizeBool
			? (description += capitalize(currentWord))
			: (description += currentWord);
		description += punctuation;

		used.push(currentWord);
	};

	const addAdjective = (punctuation, capitalize) => {
		addWord(adjective, false, punctuation, null, capitalize);
	};
	const addAffliction = (punctuation, capitalize) => {
		addWord(affliction, false, punctuation, null, capitalize);
	};
	const addAmount = (punctuation, capitalize) => {
		addWord(amount, false, punctuation, null, capitalize);
	};
	const addBodyPart = (punctuation, capitalize) => {
		addWord(bodyPart, false, punctuation, null, capitalize);
	};
	const addHealingMethod = (punctuation, tense, capitalize) => {
		addWord(healingMethod, false, punctuation, tense, capitalize);
	};
	const addIngredient = (punctuation, capitalize) => {
		addWord(ingredient, false, punctuation, null, capitalize);
	};
	const addNoun = (punctuation, plural, capitalize) => {
		addWord(noun, plural, punctuation, null, capitalize);
	};
	const addPreposition = (punctuation, capitalize) => {
		addWord(preposition, false, punctuation, null, capitalize);
	};
	const addRecipe = (punctuation, capitalize) => {
		addWord(recipe, false, punctuation, null, capitalize);
	};
	const addVerb = (punctuation, tense, capitalize) => {
		addWord(verb, false, punctuation, tense, capitalize);
	};

	const insertCustomString = (str) => {
		description += str;
	};

	const removeLastCharacter = () => {
		description = description.slice(0, description.length - 1);
	};

	// Construct opening sentence.
	addAdjective(" ", true);
	addNoun(" ");
	addVerb(" ", "present");
	if (coinFlip()) addPreposition(" ");
	addVerb(" ", "continuous");
	coinFlip() ? addNoun(". ", true) : addNoun(". ");
	insertCustomString("</p>");

	// Construct recipe description
	insertCustomString("<p>This ");
	addAdjective(" ");
	addRecipe(" ");
	addVerb(" ", "present");
	insertCustomString("and ");
	addVerb(" ", "present");
	addPreposition(" ");
	addNoun(" ");
	insertCustomString("and ");
	addNoun(".</p>");

	// Construct ingredient roles
	const numOfIngredients = randomNumber(2, 5);

	for (let i = 0; i < numOfIngredients; i++) {
		i == 0 ? insertCustomString("<p>") : null;
		if (coinFlip()) {
			insertCustomString("A ");
			addAmount(" ");
			insertCustomString("of ");
			addAdjective(" ");
		} else {
			addAdjective(" ", true);
		}
		if (coinFlip()) {
			if (coinFlip()) {
				insertCustomString("and ");
				addAdjective(" ");
				addIngredient(" ");
			} else {
				removeLastCharacter();
				insertCustomString(", yet ");
				addAdjective(", ");
				addIngredient(" ");
			}
		} else {
			addIngredient(" ");
		}
		addVerb(" ", "present");
		if (coinFlip()) {
			insertCustomString("and ");
			addVerb(" ", "present");
		}
		if (coinFlip()) {
			if (coinFlip()) {
				insertCustomString("while ");
				addHealingMethod(" ", "continuous");
				addAffliction(" ");
				insertCustomString("of the ");
			} else {
				insertCustomString("and ");
				addHealingMethod(" ", "present");
				addAffliction(" ");
				insertCustomString("of the ");
			}
			i == numOfIngredients - 1 ? addBodyPart(".</p>") : addBodyPart(". ");
		} else {
			i == numOfIngredients - 1 ? addNoun(".</p>") : addNoun(". ");
		}
	}

	// Healing properties
	insertCustomString("<p>Also good for: ");
	const numOfHealingProps = randomNumber(1, 5);
	for (let i = 1; i <= numOfHealingProps; i++) {
		i == 1 ? addAffliction(" ", true) : addAffliction(" ");
		insertCustomString("of the ");
		if (i == numOfHealingProps - 1) {
			addBodyPart(", and ");
		} else if (i == numOfHealingProps) {
			addBodyPart(".</p>");
		} else {
			addBodyPart(", ");
		}
	}

	return description;
};
