From c04af1e19410ba7fc789f29177176a2776a535db Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@mailbox.org>
Date: Sat, 25 Feb 2023 00:12:26 +0100
Subject: [PATCH] Rework loans to use no unnecessary tooltips

---
 src/budget/loans.js | 127 +++++++++++++++++++++++---------------------
 1 file changed, 67 insertions(+), 60 deletions(-)

diff --git a/src/budget/loans.js b/src/budget/loans.js
index 855278661f8..8c0e1cf4214 100644
--- a/src/budget/loans.js
+++ b/src/budget/loans.js
@@ -78,45 +78,37 @@ App.Budget.loans = function() {
 		const values = [10000, 100000, 1000000];
 		const disabledReasons = [];
 		const links = [];
-		const text = [];
-
-		let allowed = true;
 
-		text.push(`You can take out a loan from one of the credit unions in the Free City, if you have the reputation for them to trust you.`);
+		div.append(`You can take out a loan from one of the credit unions in the Free City, if you have the reputation for them to trust you.`);
+		App.UI.DOM.appendNewElement("div", div,
+			`If for any reason you lack the credits, sectors of ${V.arcologies[0].name} will be used in lieu of payment.`,
+			["note", "indent"]);
 
 		if (V.rep < 10000) {
 			disabledReasons.push(`You need at least ${num(10000)} reputation to take a loan from this lender.`);
-			allowed = false;
 		}
 		if (loan('bank')) {
 			disabledReasons.push(`You have already taken out a loan from this lender.`);
-			allowed = false;
 		}
 
-		if (allowed) {
-			values.map(val => links.push(App.UI.DOM.link(cashFormat(val), () => {
-				const term = Math.max(val / 50000, 4);
-				const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
-				const interest = val * (term / 52) * (apr / 100);
-				const full = val + interest;
-				V.loans.push({
-					name: 'bank',
-					principal: val,
-					deadline: V.week + term,
-					installments: term,
-					apr,
-					interest,
-					full,
-				});
-				cashX(val, "loan");
-
-				App.UI.reload();
-			}, [], '', terms('bank', val))));
+		if (disabledReasons.length === 0) {
+			for (const amount of values) {
+				const loan = createLoan("bank", amount);
+				const f = new DocumentFragment();
+				f.append(App.UI.DOM.link(cashFormat(amount), () => {
+					V.loans.push(loan);
+					cashX(amount, "loan");
+					App.UI.reload();
+				}));
+				const info = new DocumentFragment();
+				App.Events.addNode(info, [`${cashFormatColor(loan.full)} over ${num(loan.deadline - V.week)} weeks`]);
+				f.append(" – ", App.UI.DOM.spanWithTooltip(info, terms("bank", loan)));
+				links.push(f);
+			}
 		} else {
 			values.map(val => links.push(App.UI.DOM.disabledLink(cashFormat(val), disabledReasons)));
 		}
 
-		div.append(text.join(' '));
 		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
 
 		return div;
@@ -127,67 +119,82 @@ App.Budget.loans = function() {
 		const values = [10000, 100000, 1000000];
 		const disabledReasons = [];
 		const links = [];
-		const text = [];
-
-		let allowed = true;
 
-		text.push(`If you're not quite reputable enough, you can also borrow money from one of the local loansharks in the area.`);
+		div.append(`If you're not quite reputable enough, you can also borrow money from one of the local loan-sharks in the area.`);
+		App.UI.DOM.appendNewElement("div", div,
+			`If for any reason you miss a payment the lender will send his men to collect – forcibly, if necessary.`,
+			["note", "indent"]);
 
 		if (V.rep < 2000) {
 			disabledReasons.push(`You need at least ${num(2000)} reputation to take a loan from this lender.`);
-			allowed = false;
 		}
 		if (loan('shark')) {
 			disabledReasons.push(`You have already taken out a loan from this lender.`);
-			allowed = false;
 		}
 
-		if (allowed) {
-			values.map(val => links.push(App.UI.DOM.link(cashFormat(val), () => {
-				const term = Math.max(val / 50000, 4);
-				const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
-				const interest = (val * (term / 52) * (apr / 100)) * 3;
-				const full = val + interest;
-				V.loans.push({
-					name: 'shark',
-					principal: val,
-					deadline: V.week + (Math.max(val / 50000, 4)),
-					installments: 1,
-					apr,
-					interest,
-					full,
-				});
-				cashX(val, "loan");
-
-				App.UI.reload();
-			}, [], '', terms('shark', val))));
+		if (disabledReasons.length === 0) {
+			for (const amount of values) {
+				const loan = createLoan("shark", amount);
+				const f = new DocumentFragment();
+				f.append(App.UI.DOM.link(cashFormat(amount), () => {
+					V.loans.push(loan);
+					cashX(amount, "loan");
+
+					App.UI.reload();
+				}));
+				const info = new DocumentFragment();
+				App.Events.addNode(info, [`${cashFormatColor(loan.full)} after ${num(loan.deadline - V.week)} weeks`]);
+				f.append(" – ", App.UI.DOM.spanWithTooltip(info, terms("shark", loan)));
+				links.push(f);
+			}
 		} else {
 			values.map(val => links.push(App.UI.DOM.disabledLink(cashFormat(val), disabledReasons)));
 		}
 
-		div.append(text.join(' '));
 		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
 
 		return div;
 	}
 
 	/**
-	 * @param {Lender} lender
+	 * @param {"bank"|"shark"}lender
 	 * @param {number} amount
+	 * @returns {FC.Loan}
 	 */
-	function terms(lender, amount) {
+	function createLoan(lender, amount) {
 		const term = Math.max(amount / 50000, 4);
 		const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
-		const interest = amount * (term / 52) * (apr / 100);
+		let interest;
+		let installments;
+		if (lender === "shark") {
+			interest = (amount * (term / 52) * (apr / 100)) * 3;
+			installments = 1;
+		} else {
+			interest = amount * (term / 52) * (apr / 100);
+			installments = term;
+		}
 		const full = amount + interest;
-		const text = [];
 
+		return {
+			name: 'shark',
+			principal: amount,
+			deadline: V.week + term,
+			installments,
+			apr,
+			interest,
+			full: Math.trunc(full),
+		};
+	}
+
+	/**
+	 * @param {Lender} lender
+	 * @param {FC.Loan} loan
+	 */
+	function terms(lender, loan) {
 		if (lender === 'bank') {
-			text.push(`You will pay about ${cashFormat(Math.trunc(full / term))} per week for ${num(term)} weeks until you have paid off the entire balance. If for any reason you lack the credits, sectors of ${V.arcologies[0].name} will be used in lieu of payment. You will end up paying back about ${cashFormat(Math.trunc(full))} after interest.`);
+			return `You will pay about ${cashFormat(Math.trunc(loan.full / loan.deadline - V.week))} per week for ${num(loan.deadline - V.week)} weeks until you have paid off the entire balance. You will end up paying back about ${cashFormat(Math.trunc(loan.full))} after interest.`;
 		} else {
-			text.push(`You will have ${num(term)} weeks to pay off the full amount, after which the lender will send his men to collect – forcibly, if necessary. You will end up paying back about ${cashFormat(Math.trunc(amount + (interest * 3)))} after interest.`);
+			return `You will have ${num(loan.deadline - V.week)} weeks to pay off the full amount. You will end up paying back about ${cashFormat(Math.trunc(loan.full))} after interest.`;
 		}
-
-		return text.join(' ');
 	}
 };
-- 
GitLab