1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sourceforge.jhunters.pool.data;
18
19 import java.time.LocalDate;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import javafx.beans.property.ObjectProperty;
27 import javafx.beans.property.SimpleObjectProperty;
28
29
30
31
32 public class CompetitionFixtures
33 implements Comparable<CompetitionFixtures> {
34
35
36
37 public static final int OUTLOOK_DEPTH = 5;
38
39
40
41
42 private static final char CHAR_CBASE = 'A';
43
44
45
46
47 private static final int RADIX_INDEX = 26;
48
49
50
51
52 private final ObjectProperty<Player> thePlayer;
53
54
55
56
57 private final ObjectProperty<Integer> theIndex;
58
59
60
61
62 private final ObjectProperty<String> theId;
63
64
65
66
67 private final List<ObjectProperty<FixtureRecord>> theFixtures;
68
69
70
71
72 private final List<ObjectProperty<FixtureOutlook>> theOutlook;
73
74
75
76
77 private final List<FixtureOutlook> theOutlookCache;
78
79
80
81
82
83
84 protected CompetitionFixtures(final Player pPlayer,
85 final int pNumPlayers) {
86 thePlayer = new SimpleObjectProperty<Player>(this, PlayerFixtureField.NAME.toString(), pPlayer);
87 theIndex = new SimpleObjectProperty<Integer>(this, PlayerFixtureField.INDEX.toString());
88 theId = new SimpleObjectProperty<String>(this, PlayerFixtureField.ID.toString());
89 theFixtures = new ArrayList<ObjectProperty<FixtureRecord>>();
90 for (int i = 0; i < pNumPlayers; i++) {
91 theFixtures.add(new SimpleObjectProperty<FixtureRecord>(this, PlayerFixtureField.FIXTURE.toString()));
92 }
93 theOutlook = new ArrayList<ObjectProperty<FixtureOutlook>>();
94 for (int i = 0; i < OUTLOOK_DEPTH; i++) {
95 theOutlook.add(new SimpleObjectProperty<FixtureOutlook>(this, PlayerFixtureField.OUTLOOK.toString()));
96 }
97 theOutlookCache = new ArrayList<FixtureOutlook>();
98 }
99
100
101
102
103
104 public ObjectProperty<Player> playerProperty() {
105 return thePlayer;
106 }
107
108
109
110
111
112 public ObjectProperty<Integer> indexProperty() {
113 return theIndex;
114 }
115
116
117
118
119
120 public ObjectProperty<String> idProperty() {
121 return theId;
122 }
123
124
125
126
127
128 public Player getPlayer() {
129 return thePlayer.getValue();
130 }
131
132
133
134
135
136 public Integer getIndex() {
137 return theIndex.getValue();
138 }
139
140
141
142
143
144 private String getId() {
145 return theId.getValue();
146 }
147
148
149
150
151
152
153 public ObjectProperty<FixtureRecord> fixtureProperty(final int pIndex) {
154 return theFixtures.get(pIndex);
155 }
156
157
158
159
160
161
162 public ObjectProperty<FixtureOutlook> outlookProperty(final int pIndex) {
163 return theOutlook.get(pIndex);
164 }
165
166
167
168
169
170
171 public static String getIdForIndex(final int pIndex) {
172
173 int myId = pIndex;
174 int myTopId = myId
175 / RADIX_INDEX;
176 myId = myId
177 % RADIX_INDEX;
178
179
180 StringBuilder myBuilder = new StringBuilder();
181 if (myTopId > 0) {
182 myBuilder.append((char) (CHAR_CBASE
183 + myTopId));
184 }
185 myBuilder.append((char) (CHAR_CBASE + myId));
186 return myBuilder.toString();
187 }
188
189
190
191
192 protected void resetOutlook() {
193
194 theOutlookCache.clear();
195 }
196
197
198
199
200
201 protected void setIndex(final int pIndex) {
202
203 theIndex.setValue(pIndex);
204 theId.setValue(getIdForIndex(pIndex));
205 }
206
207
208
209
210
211
212 protected void setResult(final Result pResult,
213 final CompetitionFixtures pOpponent) {
214
215 ObjectProperty<FixtureRecord> myFixture = fixtureProperty(pOpponent.getIndex());
216 myFixture.setValue(new FixtureRecord(pResult));
217 }
218
219
220
221
222
223
224 protected void setOutlook(final LocalDate pDate,
225 final CompetitionFixtures pOpponent) {
226
227 ObjectProperty<FixtureRecord> myFixture = fixtureProperty(pOpponent.getIndex());
228 myFixture.setValue(new FixtureRecord(pDate));
229
230
231 theOutlookCache.add(new FixtureOutlook(pDate, pOpponent));
232 }
233
234
235
236
237 protected void determineOutlook() {
238
239 Collections.sort(theOutlookCache);
240
241
242 int i = 0;
243 Iterator<FixtureOutlook> myIterator = theOutlookCache.iterator();
244 while (myIterator.hasNext() && (i < OUTLOOK_DEPTH)) {
245 FixtureOutlook myOutlook = myIterator.next();
246
247
248 ObjectProperty<FixtureOutlook> myFixture = outlookProperty(i++);
249 myFixture.setValue(myOutlook);
250 }
251
252
253 while (i < OUTLOOK_DEPTH) {
254
255 ObjectProperty<FixtureOutlook> myFixture = outlookProperty(i++);
256 myFixture.setValue(null);
257 }
258 }
259
260 @Override
261 public boolean equals(final Object pThat) {
262
263 if (pThat == this) {
264 return true;
265 }
266 if (pThat == null) {
267 return false;
268 }
269
270
271 if (!(pThat instanceof CompetitionFixtures)) {
272 return false;
273 }
274
275
276 CompetitionFixtures myThat = (CompetitionFixtures) pThat;
277
278
279 return thePlayer.getValue().equals(myThat.thePlayer.getValue());
280 }
281
282 @Override
283 public int hashCode() {
284 return thePlayer.hashCode();
285 }
286
287 @Override
288 public int compareTo(final CompetitionFixtures pThat) {
289 return thePlayer.getValue().compareTo(pThat.thePlayer.getValue());
290 }
291
292
293
294
295 protected static final class FixtureComparator
296 implements Comparator<CompetitionFixtures> {
297 @Override
298 public int compare(final CompetitionFixtures pFirst,
299 final CompetitionFixtures pSecond) {
300 return pFirst.compareTo(pSecond);
301 }
302 }
303
304
305
306
307 public static final class FixtureRecord {
308
309
310
311 private final LocalDate theDate;
312
313
314
315
316 private final Result theResult;
317
318
319
320
321
322 private FixtureRecord(final Result pResult) {
323 theResult = pResult;
324 theDate = null;
325 }
326
327
328
329
330
331 private FixtureRecord(final LocalDate pDate) {
332 theDate = pDate;
333 theResult = null;
334 }
335
336
337
338
339
340 public Result getResult() {
341 return theResult;
342 }
343
344 @Override
345 public String toString() {
346 return theResult != null
347 ? theResult.toString()
348 : DataParser.formatShortDate(theDate);
349 }
350 }
351
352
353
354
355 public static final class FixtureOutlook
356 implements Comparable<FixtureOutlook> {
357
358
359
360 private final LocalDate theDate;
361
362
363
364
365 private final CompetitionFixtures theOpponent;
366
367
368
369
370
371
372 private FixtureOutlook(final LocalDate pDate,
373 final CompetitionFixtures pOpponent) {
374 theDate = pDate;
375 theOpponent = pOpponent;
376 }
377
378 @Override
379 public String toString() {
380 StringBuilder myBuilder = new StringBuilder();
381 myBuilder.append(DataParser.formatShortDate(theDate));
382 myBuilder.append(' ');
383 myBuilder.append(Fixture.MATCH_VERSUS);
384 myBuilder.append(' ');
385 myBuilder.append(theOpponent.getId());
386 return myBuilder.toString();
387 }
388
389 @Override
390 public boolean equals(final Object pThat) {
391
392 if (pThat == this) {
393 return true;
394 }
395 if (pThat == null) {
396 return false;
397 }
398
399
400 if (!(pThat instanceof FixtureOutlook)) {
401 return false;
402 }
403
404
405 FixtureOutlook myThat = (FixtureOutlook) pThat;
406
407
408 return theDate.equals(myThat.theDate)
409 && theOpponent.equals(myThat.theOpponent);
410 }
411
412 @Override
413 public int hashCode() {
414 return (theDate.hashCode() * DataSet.HASH_PRIME)
415 + theOpponent.hashCode();
416 }
417
418 @Override
419 public int compareTo(final FixtureOutlook pThat) {
420 int iDiff = theDate.compareTo(pThat.theDate);
421 if (iDiff != 0) {
422 return iDiff;
423 }
424 return theOpponent.compareTo(pThat.theOpponent);
425 }
426 }
427
428
429
430
431 public enum PlayerFixtureField {
432
433
434
435 NAME,
436
437
438
439
440 INDEX,
441
442
443
444
445 ID,
446
447
448
449
450 FIXTURE,
451
452
453
454
455 OUTLOOK,
456
457
458
459
460 CONTACT;
461
462
463
464
465 private String theName;
466
467 @Override
468 public String toString() {
469
470 if (theName == null) {
471
472 theName = DataResource.getKeyForPlayerFixtureField(this).getValue();
473 }
474
475
476 return theName;
477 }
478 }
479 }