import { Builder } from "../string_utils.js";
import { pluralize } from "../string_utils.js";
import Model from "./model.js";
const REL_LABELS = new Map(
Object.entries({
deceased: "deceased",
absent: "absent",
married: "married to",
divorced: "divorced from",
separated: "separated from",
couple: "lives with",
})
);
// It is surprisingly hard to get this right.
function relatedNames(ch1, ch2, relationship) {
let relLabel = REL_LABELS.get(relationship);
let arr = [];
if (ch1.name.family === ch2.name.family) {
arr.push(ch1.name.given);
arr.push(relLabel);
arr.push(ch2.name.given);
arr.push(ch2.name.toLastNameString());
} else {
arr.push(ch1.name.toString());
arr.push(relLabel);
arr.push(ch2.name.toString());
}
let detail = `(Ages ${ch1.age} and ${ch2.age}`;
if (ch1.status && ch1.status === ch2.status) {
detail += `; both are ${ch1.status}`;
} else {
if (ch1.status) {
detail += `; ${ch1.name.given} is ${ch1.status}`;
}
if (ch2.status) {
detail += `; ${ch2.name.given} is ${ch2.status}`;
}
}
detail += `).`;
arr.push(detail);
var b = new Builder();
b.append(arr.join(" "));
return b.toString() + " ";
}
/**
* A family. This means (in the context of this game), a set of parents with some kids,
* some of whom may themselves be in family objects with kids, etc. One of the building
* blocks of encounters and homesteads, at the least.
*/
class Family extends Model {
constructor(params) {
super(params);
this.parent = params.parent;
this.partner = params.partner;
this.relationship = params.relationship;
// Unmarried children
this.children = []; // Character
// Children in families of their own
this.couples = []; // Family
}
/**
* The number of all children (including grown children who are
* now part of a descendant couple).
*/
get childCount() {
return this.children.length + this.couples.length;
}
/**
* The male parent
*/
get male() {
return this.parent.male ? this.parent : this.partner;
}
/**
* The female parent
*/
get female() {
return this.parent.male ? this.partner : this.parent;
}
/**
* The single parent (if one of the parents has died or the parents are separated).
*/
get single() {
if (this.parent.status && !this.partner.status) {
return this.partner;
} else if (this.partner.status && !this.parent.status) {
return this.parent;
}
return null;
}
isParent(person) {
return person === this.parent || person === this.partner;
}
toString() {
var b = new Builder();
b.append(relatedNames(this.parent, this.partner, this.relationship));
b.if(this.childCount > 0, pluralize(`{|}{1 |}child{ren}: `, this.childCount));
this.children.map((c) => b.append(`${c.name} (${c.age}). `));
this.couples.map((c) => b.append(`${c.parent.name} (${c.parent.age}). `));
b.append(this.couples.map((c) => `\n\n${c.toString()}`).join(" "));
return b.toString().replaceAll(") (", "; ");
}
}
export default Family;