View Javadoc
1   /*******************************************************************************
2    * jhunters: Pool League
3    * Copyright 2015 Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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   * Competition Table.
31   */
32  public class CompetitionFixtures
33          implements Comparable<CompetitionFixtures> {
34      /**
35       * Outlook depth.
36       */
37      public static final int OUTLOOK_DEPTH = 5;
38  
39      /**
40       * Base for Id.
41       */
42      private static final char CHAR_CBASE = 'A';
43  
44      /**
45       * Index radix.
46       */
47      private static final int RADIX_INDEX = 26;
48  
49      /**
50       * Player.
51       */
52      private final ObjectProperty<Player> thePlayer;
53  
54      /**
55       * PlayerIndex.
56       */
57      private final ObjectProperty<Integer> theIndex;
58  
59      /**
60       * PlayerId.
61       */
62      private final ObjectProperty<String> theId;
63  
64      /**
65       * Fixture Records.
66       */
67      private final List<ObjectProperty<FixtureRecord>> theFixtures;
68  
69      /**
70       * Outlook Records.
71       */
72      private final List<ObjectProperty<FixtureOutlook>> theOutlook;
73  
74      /**
75       * Outlook Cache.
76       */
77      private final List<FixtureOutlook> theOutlookCache;
78  
79      /**
80       * Constructor.
81       * @param pPlayer the player.
82       * @param pNumPlayers the number of players
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      * Obtain the player property.
102      * @return the player property.
103      */
104     public ObjectProperty<Player> playerProperty() {
105         return thePlayer;
106     }
107 
108     /**
109      * Obtain the index property.
110      * @return the player index property.
111      */
112     public ObjectProperty<Integer> indexProperty() {
113         return theIndex;
114     }
115 
116     /**
117      * Obtain the id property.
118      * @return the player id property.
119      */
120     public ObjectProperty<String> idProperty() {
121         return theId;
122     }
123 
124     /**
125      * Obtain the player.
126      * @return the player.
127      */
128     public Player getPlayer() {
129         return thePlayer.getValue();
130     }
131 
132     /**
133      * Obtain the index.
134      * @return the player index.
135      */
136     public Integer getIndex() {
137         return theIndex.getValue();
138     }
139 
140     /**
141      * Obtain the id.
142      * @return the player id.
143      */
144     private String getId() {
145         return theId.getValue();
146     }
147 
148     /**
149      * Obtain the fixture record for the index.
150      * @param pIndex the index
151      * @return the fixture record property.
152      */
153     public ObjectProperty<FixtureRecord> fixtureProperty(final int pIndex) {
154         return theFixtures.get(pIndex);
155     }
156 
157     /**
158      * Obtain the fixture outlook for the index.
159      * @param pIndex the index
160      * @return the fixture record property.
161      */
162     public ObjectProperty<FixtureOutlook> outlookProperty(final int pIndex) {
163         return theOutlook.get(pIndex);
164     }
165 
166     /**
167      * get Id for index.
168      * @param pIndex the index
169      * @return the id
170      */
171     public static String getIdForIndex(final int pIndex) {
172         /* Calculate indexes */
173         int myId = pIndex;
174         int myTopId = myId
175                       / RADIX_INDEX;
176         myId = myId
177                % RADIX_INDEX;
178 
179         /* Build the name */
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      * ReSet the outlook cache.
191      */
192     protected void resetOutlook() {
193         /* Record the index */
194         theOutlookCache.clear();
195     }
196 
197     /**
198      * Set the index.
199      * @param pIndex the index
200      */
201     protected void setIndex(final int pIndex) {
202         /* Record the index */
203         theIndex.setValue(pIndex);
204         theId.setValue(getIdForIndex(pIndex));
205     }
206 
207     /**
208      * Set the result.
209      * @param pResult the result
210      * @param pOpponent the opponent
211      */
212     protected void setResult(final Result pResult,
213                              final CompetitionFixtures pOpponent) {
214         /* Record the fixture */
215         ObjectProperty<FixtureRecord> myFixture = fixtureProperty(pOpponent.getIndex());
216         myFixture.setValue(new FixtureRecord(pResult));
217     }
218 
219     /**
220      * Set the outlook.
221      * @param pDate the date
222      * @param pOpponent the opponent
223      */
224     protected void setOutlook(final LocalDate pDate,
225                               final CompetitionFixtures pOpponent) {
226         /* Record the fixture */
227         ObjectProperty<FixtureRecord> myFixture = fixtureProperty(pOpponent.getIndex());
228         myFixture.setValue(new FixtureRecord(pDate));
229 
230         /* Store in the outlook cache */
231         theOutlookCache.add(new FixtureOutlook(pDate, pOpponent));
232     }
233 
234     /**
235      * determine outlook.
236      */
237     protected void determineOutlook() {
238         /* Sort the outlook cache */
239         Collections.sort(theOutlookCache);
240 
241         /* Loop through the cache */
242         int i = 0;
243         Iterator<FixtureOutlook> myIterator = theOutlookCache.iterator();
244         while (myIterator.hasNext() && (i < OUTLOOK_DEPTH)) {
245             FixtureOutlook myOutlook = myIterator.next();
246 
247             /* Store as outlook */
248             ObjectProperty<FixtureOutlook> myFixture = outlookProperty(i++);
249             myFixture.setValue(myOutlook);
250         }
251 
252         /* If we stopped early */
253         while (i < OUTLOOK_DEPTH) {
254             /* Store null */
255             ObjectProperty<FixtureOutlook> myFixture = outlookProperty(i++);
256             myFixture.setValue(null);
257         }
258     }
259 
260     @Override
261     public boolean equals(final Object pThat) {
262         /* Handle trivial cases */
263         if (pThat == this) {
264             return true;
265         }
266         if (pThat == null) {
267             return false;
268         }
269 
270         /* Check for class */
271         if (!(pThat instanceof CompetitionFixtures)) {
272             return false;
273         }
274 
275         /* Access as CompetitionFixtures */
276         CompetitionFixtures myThat = (CompetitionFixtures) pThat;
277 
278         /* Check fields */
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      * Comparator class.
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      * FixtureRecord class.
306      */
307     public static final class FixtureRecord {
308         /**
309          * Date of game.
310          */
311         private final LocalDate theDate;
312 
313         /**
314          * Result of game.
315          */
316         private final Result theResult;
317 
318         /**
319          * Constructor.
320          * @param pResult the result
321          */
322         private FixtureRecord(final Result pResult) {
323             theResult = pResult;
324             theDate = null;
325         }
326 
327         /**
328          * Constructor.
329          * @param pDate the date
330          */
331         private FixtureRecord(final LocalDate pDate) {
332             theDate = pDate;
333             theResult = null;
334         }
335 
336         /**
337          * Obtain result.
338          * @return the result
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      * FixtureOutlook class.
354      */
355     public static final class FixtureOutlook
356             implements Comparable<FixtureOutlook> {
357         /**
358          * Date of game.
359          */
360         private final LocalDate theDate;
361 
362         /**
363          * Opponent for game.
364          */
365         private final CompetitionFixtures theOpponent;
366 
367         /**
368          * Constructor.
369          * @param pDate the date
370          * @param pOpponent the opponent
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             /* Handle trivial cases */
392             if (pThat == this) {
393                 return true;
394             }
395             if (pThat == null) {
396                 return false;
397             }
398 
399             /* Check for class */
400             if (!(pThat instanceof FixtureOutlook)) {
401                 return false;
402             }
403 
404             /* Access as FixtureOutlook */
405             FixtureOutlook myThat = (FixtureOutlook) pThat;
406 
407             /* Check fields */
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      * PlayerFixture fields.
430      */
431     public enum PlayerFixtureField {
432         /**
433          * Name.
434          */
435         NAME,
436 
437         /**
438          * Contact.
439          */
440         INDEX,
441 
442         /**
443          * Selected.
444          */
445         ID,
446 
447         /**
448          * Fixture.
449          */
450         FIXTURE,
451 
452         /**
453          * Outlook.
454          */
455         OUTLOOK,
456 
457         /**
458          * Contact.
459          */
460         CONTACT;
461 
462         /**
463          * The String name.
464          */
465         private String theName;
466 
467         @Override
468         public String toString() {
469             /* If we have not yet loaded the name */
470             if (theName == null) {
471                 /* Load the name */
472                 theName = DataResource.getKeyForPlayerFixtureField(this).getValue();
473             }
474 
475             /* return the name */
476             return theName;
477         }
478     }
479 }