xref: /webtrees/app/Module/LanguageEnglishUnitedStates.php (revision b63ebfff10c4f748c10374a14a84550d3b653912)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2022 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Module;
21
22use Fisharebest\Localization\Locale\LocaleEnUs;
23use Fisharebest\Localization\Locale\LocaleInterface;
24use Fisharebest\Webtrees\Relationship;
25
26use function abs;
27use function min;
28use function str_repeat;
29
30/**
31 * Class LanguageEnglishUnitedStates.
32 */
33class LanguageEnglishUnitedStates extends AbstractModule implements ModuleLanguageInterface
34{
35    use ModuleLanguageTrait;
36
37    protected const COUSIN = [
38        'sibling',
39        'first cousin',
40        'second cousin',
41        'third cousin',
42        'fourth cousin',
43        'fifth cousin',
44        'sixth cousin',
45        'seventh cousin',
46        'eighth cousin',
47        'ninth cousin',
48        'tenth cousin',
49        'eleventh cousin',
50        'twelfth cousin',
51        'thirteenth cousin',
52        'fourteenth cousin',
53        'fifteenth cousin',
54        'sixteenth cousin',
55        'seventeenth cousin',
56        'eighteenth cousin',
57        'nineteenth cousin',
58        'twentieth cousin',
59        'twenty-first cousin',
60        'twenty-second cousin',
61        'twenty-third cousin',
62        'twenty-fourth cousin',
63        'twenty-fifth cousin',
64        'twenty-sixth cousin',
65        'twenty-seventh cousin',
66        'twenty-eighth cousin',
67        'twenty-ninth cousin',
68        'thirtieth cousin',
69    ];
70
71    protected const REMOVED = [
72        '',
73        ' once removed',
74        ' twice removed',
75        ' three times removed',
76        ' four times removed',
77        ' five times removed',
78        ' six times removed',
79        ' seven times removed',
80        ' eight times removed',
81        ' nine times removed',
82        ' ten times removed',
83        ' eleven removed',
84        ' twelve removed',
85        ' thirteen removed',
86        ' fourteen times removed',
87        ' fifteen times removed',
88        ' sixteen times removed',
89        ' seventeen times removed',
90        ' eighteen times removed',
91        ' nineteen times removed',
92        ' twenty times removed',
93        ' twenty-one times removed',
94        ' twenty-two times removed',
95        ' twenty-three times removed',
96        ' twenty-four times removed',
97        ' twenty-five times removed',
98        ' twenty-six times removed',
99        ' twenty-seven times removed',
100        ' twenty-eight times removed',
101        ' twenty-nine times removed',
102    ];
103
104    protected const DIRECTION = [
105        -1 => ' descending',
106        0  => '',
107        1  => ' ascending',
108    ];
109
110    /**
111     * @return LocaleInterface
112     */
113    public function locale(): LocaleInterface
114    {
115        return new LocaleEnUs();
116    }
117
118    /**
119     * @return array<Relationship>
120     */
121    public function relationships(): array
122    {
123        // Genitive forms in English are simple/regular, as no relationship name ends in "s".
124        $genitive = static fn (string $s): array => [$s, $s . '’s %s'];
125
126        $cousin = static fn (int $up, int $down): array => $genitive(
127            (static::COUSIN[min($up, $down)] ?? 'distant cousin') .
128            (static::REMOVED[abs($up - $down)] ?? ' many times removed') .
129            static::DIRECTION[$up <=> $down]
130        );
131
132        $great = static fn (int $n, string $prefix, string $suffix): array => $genitive(
133            $prefix . ($n > 3 ? 'great ×' . $n . ' ' : str_repeat('great-', $n)) . $suffix
134        );
135
136        return [
137            // Adopted
138            Relationship::fixed('adoptive-mother', 'adoptive-mother’s %s')->adoptive()->mother(),
139            Relationship::fixed('adoptive-father', 'adoptive-father’s %s')->adoptive()->father(),
140            Relationship::fixed('adoptive-parent', 'adoptive-parent’s %s')->adoptive()->parent(),
141            Relationship::fixed('adopted-daughter', 'adopted-daughter’s %s')->adopted()->daughter(),
142            Relationship::fixed('adopted-son', 'adopted-son’s %s')->adopted()->son(),
143            Relationship::fixed('adopted-child', 'adopted-child’s %s')->adopted()->child(),
144            // Fostered
145            Relationship::fixed('foster-mother', 'foster-mother’s %s')->fostering()->mother(),
146            Relationship::fixed('foster-father', 'foster-father’s %s')->fostering()->father(),
147            Relationship::fixed('foster-parent', 'foster-parent’s %s')->fostering()->parent(),
148            Relationship::fixed('foster-daughter', 'foster-daughter’s %s')->fostered()->daughter(),
149            Relationship::fixed('foster-son', 'foster-son’s %s')->fostered()->son(),
150            Relationship::fixed('foster-child', 'foster-child’s %s')->fostered()->child(),
151            // Parents
152            Relationship::fixed('mother', 'mother’s %s')->mother(),
153            Relationship::fixed('father', 'father’s %s')->father(),
154            Relationship::fixed('parent', 'parent’s %s')->parent(),
155            // Children
156            Relationship::fixed('daughter', 'daughter’s %s')->daughter(),
157            Relationship::fixed('son', 'son’s %s')->son(),
158            Relationship::fixed('child', 'child’s %s')->child(),
159            // Siblings
160            Relationship::fixed('twin sister', 'twin sister’s %s')->twin()->sister(),
161            Relationship::fixed('twin brother', 'twin brother’s %s')->twin()->brother(),
162            Relationship::fixed('twin sibling', 'twin sibling’s %s')->twin()->sibling(),
163            Relationship::fixed('elder sister', 'elder sister’s %s')->older()->sister(),
164            Relationship::fixed('elder brother', 'elder brother’s %s')->older()->brother(),
165            Relationship::fixed('elder sibling', 'elder sibling’s %s')->older()->sibling(),
166            Relationship::fixed('younger sister', 'younger sister’s %s')->younger()->sister(),
167            Relationship::fixed('younger brother', 'younger brother’s %s')->younger()->brother(),
168            Relationship::fixed('younger sibling', 'younger sibling’s %s')->younger()->sibling(),
169            Relationship::fixed('sister', 'sister’s %s')->sister(),
170            Relationship::fixed('brother', 'brother’s %s')->brother(),
171            Relationship::fixed('sibling', 'sibling’s %s')->sibling(),
172            // Half-siblings
173            Relationship::fixed('half-sister', 'half-sister’s %s')->parent()->daughter(),
174            Relationship::fixed('half-brother', 'half-brother’s %s')->parent()->son(),
175            Relationship::fixed('half-sibling', 'half-sibling’s %s')->parent()->child(),
176            // Stepfamily
177            Relationship::fixed('stepmother', 'stepmother’s %s')->parent()->wife(),
178            Relationship::fixed('stepfather', 'stepfather’s %s')->parent()->husband(),
179            Relationship::fixed('stepparent', 'stepparent’s %s')->parent()->married()->spouse(),
180            Relationship::fixed('stepdaughter', 'stepdaughter’s %s')->married()->spouse()->daughter(),
181            Relationship::fixed('stepson', 'stepson’s %s')->married()->spouse()->son(),
182            Relationship::fixed('stepchild', 'stepchild’s %s')->married()->spouse()->child(),
183            Relationship::fixed('stepsister', 'stepsister’s %s')->parent()->spouse()->daughter(),
184            Relationship::fixed('stepbrother', 'stepbrother’s %s')->parent()->spouse()->son(),
185            Relationship::fixed('stepsibling', 'stepsibling’s %s')->parent()->spouse()->child(),
186            // Partners
187            Relationship::fixed('ex-wife', 'ex-wife’s %s')->divorced()->partner()->female(),
188            Relationship::fixed('ex-husband', 'ex-husband’s %s')->divorced()->partner()->male(),
189            Relationship::fixed('ex-spouse', 'ex-spouse’s %s')->divorced()->partner(),
190            Relationship::fixed('fiancée', 'fiancée’s %s')->engaged()->partner()->female(),
191            Relationship::fixed('fiancé', 'fiancé’s %s')->engaged()->partner()->male(),
192            Relationship::fixed('wife', 'wife’s %s')->wife(),
193            Relationship::fixed('husband', 'husband’s %s')->husband(),
194            Relationship::fixed('spouse', 'spouse’s %s')->spouse(),
195            Relationship::fixed('partner', 'partner’s %s')->partner(),
196            // In-laws
197            Relationship::fixed('mother-in-law', 'mother-in-law’s %s')->married()->spouse()->mother(),
198            Relationship::fixed('father-in-law', 'father-in-law’s %s')->married()->spouse()->father(),
199            Relationship::fixed('parent-in-law', 'parent-in-law’s %s')->married()->spouse()->parent(),
200            Relationship::fixed('daughter-in-law', 'daughter-in-law’s %s')->child()->wife(),
201            Relationship::fixed('son-in-law', 'son-in-law’s %s')->child()->husband(),
202            Relationship::fixed('child-in-law', 'child-in-law’s %s')->child()->married()->spouse(),
203            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->sibling()->spouse()->sister(),
204            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->sibling()->spouse()->brother(),
205            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->sibling()->spouse()->sibling(),
206            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->spouse()->sister(),
207            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->spouse()->brother(),
208            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->spouse()->sibling(),
209            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->sibling()->wife(),
210            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->sibling()->husband(),
211            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->sibling()->spouse(),
212            // Grandparents
213            Relationship::fixed('maternal-grandmother', 'maternal-grandmother’s %s')->mother()->mother(),
214            Relationship::fixed('maternal-grandfather', 'maternal-grandfather’s %s')->mother()->father(),
215            Relationship::fixed('maternal-grandparent', 'maternal-grandfather’s %s')->mother()->parent(),
216            Relationship::fixed('paternal-grandmother', 'paternal-grandmother’s %s')->father()->mother(),
217            Relationship::fixed('paternal-grandfather', 'paternal-grandfather’s %s')->father()->father(),
218            Relationship::fixed('paternal-grandparent', 'paternal-grandfather’s %s')->father()->parent(),
219            Relationship::fixed('grandmother', 'grandmother’s %s')->parent()->mother(),
220            Relationship::fixed('grandfather', 'grandfather’s %s')->parent()->father(),
221            Relationship::fixed('grandparent', 'grandparent’s %s')->parent()->parent(),
222            // Grandchildren
223            Relationship::fixed('granddaughter', 'granddaughter’s %s')->child()->daughter(),
224            Relationship::fixed('grandson', 'grandson’s %s')->child()->son(),
225            Relationship::fixed('grandchild', 'grandchild’s %s')->child()->child(),
226            // Relationships with dynamically generated names
227            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'aunt'))->ancestor()->sister(),
228            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'aunt'))->ancestor()->sibling()->wife(),
229            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'uncle'))->ancestor()->brother(),
230            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'uncle'))->ancestor()->sibling()->husband(),
231            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'niece'))->sibling()->descendant()->female(),
232            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'niece'))->married()->spouse()->sibling()->descendant()->female(),
233            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'nephew'))->sibling()->descendant()->male(),
234            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'nephew'))->married()->spouse()->sibling()->descendant()->male(),
235            Relationship::dynamic(static fn (int $n) => $great($n - 2, 'maternal ', 'grandmother'))->mother()->ancestor()->female(),
236            Relationship::dynamic(static fn (int $n) => $great($n - 1, 'maternal ', 'grandfather'))->mother()->ancestor()->male(),
237            Relationship::dynamic(static fn (int $n) => $great($n - 1, 'paternal ', 'grandmother'))->father()->ancestor()->female(),
238            Relationship::dynamic(static fn (int $n) => $great($n - 1, 'paternal ', 'grandfather'))->father()->ancestor()->male(),
239            Relationship::dynamic(static fn (int $n) => $great($n - 1, '', 'grandparent'))->ancestor(),
240            Relationship::dynamic(static fn (int $n) => $great($n - 2, '', 'granddaughter'))->descendant()->female(),
241            Relationship::dynamic(static fn (int $n) => $great($n - 2, '', 'grandson'))->descendant()->male(),
242            Relationship::dynamic(static fn (int $n) => $great($n - 2, '', 'grandchild'))->descendant(),
243            Relationship::dynamic($cousin)->ancestor()->sibling()->descendant(),
244        ];
245    }
246}
247