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  
21  import javafx.beans.property.ObjectProperty;
22  import javafx.beans.property.SimpleObjectProperty;
23  import net.sourceforge.jhunters.pool.PoolStatus;
24  
25  /**
26   * Individual Fixture.
27   */
28  public class Fixture {
29      /**
30       * Fixture Name.
31       */
32      protected static final String OBJECT_NAME = DataResource.FIXTURE_NAME.getValue();
33  
34      /**
35       * Null indication.
36       */
37      public static final String NULL = DataResource.FIXTURE_NULL.getValue();
38  
39      /**
40       * Versus indication.
41       */
42      public static final String MATCH_VERSUS = DataResource.FIXTURE_VERSUS.getValue();
43  
44      /**
45       * Blank character.
46       */
47      private static final char CHAR_BLANK = ' ';
48  
49      /**
50       * Open bracket character.
51       */
52      private static final char CHAR_OPEN = '(';
53  
54      /**
55       * Close bracket character.
56       */
57      private static final char CHAR_CLOSE = ')';
58  
59      /**
60       * Date of fixture.
61       */
62      private final ObjectProperty<LocalDate> theDate;
63  
64      /**
65       * Home Player.
66       */
67      private final ObjectProperty<Player> theHomePlayer;
68  
69      /**
70       * Away Player.
71       */
72      private final ObjectProperty<Player> theAwayPlayer;
73  
74      /**
75       * Result of fixture.
76       */
77      private final ObjectProperty<Result> theResult;
78  
79      /**
80       * New Date of fixture.
81       */
82      private final ObjectProperty<LocalDate> theNewDate;
83  
84      /**
85       * Fixture Status.
86       */
87      private final ObjectProperty<PoolStatus> theStatus;
88  
89      /**
90       * Constructor.
91       */
92      public Fixture() {
93          /* Allocate properties */
94          theDate = new SimpleObjectProperty<LocalDate>(this, FixtureField.DATE.toString());
95          theHomePlayer = new SimpleObjectProperty<Player>(this, FixtureField.HOME.toString());
96          theAwayPlayer = new SimpleObjectProperty<Player>(this, FixtureField.AWAY.toString());
97          theResult = new SimpleObjectProperty<Result>(this, FixtureField.RESULT.toString());
98          theNewDate = new SimpleObjectProperty<LocalDate>(this, FixtureField.NEWDATE.toString());
99          theStatus = new SimpleObjectProperty<PoolStatus>(this, FixtureField.STATUS.toString());
100     }
101 
102     @Override
103     public String toString() {
104         /* Access details */
105         LocalDate myDate = getDate();
106         LocalDate myNewDate = getNewDate();
107         Player myHome = getHomePlayer();
108         Player myAway = getAwayPlayer();
109         Result myResult = getResult();
110 
111         /* build display string */
112         StringBuilder myBuilder = new StringBuilder();
113         myBuilder.append(myDate == null
114                                        ? NULL
115                                        : DataParser.formatDate(myDate));
116         myBuilder.append(CHAR_BLANK);
117         myBuilder.append(myHome == null
118                                        ? Player.PLAYER_BYE
119                                        : myHome);
120         myBuilder.append(CHAR_BLANK);
121         myBuilder.append(myResult == null
122                                          ? MATCH_VERSUS
123                                          : myResult);
124         myBuilder.append(CHAR_BLANK);
125         myBuilder.append(myAway == null
126                                        ? Player.PLAYER_BYE
127                                        : myAway);
128         if (myNewDate != null) {
129             myBuilder.append(CHAR_BLANK);
130             myBuilder.append(CHAR_OPEN);
131             myBuilder.append(DataParser.formatDate(myNewDate));
132             myBuilder.append(CHAR_CLOSE);
133         }
134         return myBuilder.toString();
135     }
136 
137     /**
138      * Set named property.
139      * @param pPlayers the player list.
140      * @param pName the name of the property.
141      * @param pValue the value of the property.
142      */
143     protected void setNamedProperty(final PlayerList pPlayers,
144                                     final String pName,
145                                     final String pValue) {
146         if (pName.equals(FixtureField.HOME.toString())) {
147             setHomePlayer(pPlayers.getNamedPlayer(pValue));
148         } else if (pName.equals(FixtureField.AWAY.toString())) {
149             setAwayPlayer(pPlayers.getNamedPlayer(pValue));
150         } else if (pName.equals(FixtureField.DATE.toString())) {
151             setDate(DataParser.parseDate(pValue));
152         } else if (pName.equals(FixtureField.NEWDATE.toString())) {
153             setNewDate(DataParser.parseDate(pValue));
154         } else if (pName.equals(FixtureField.RESULT.toString())) {
155             setResult(DataParser.parseResult(pValue));
156         }
157     }
158 
159     /**
160      * Obtain the date property.
161      * @return the date property.
162      */
163     public ObjectProperty<LocalDate> dateProperty() {
164         return theDate;
165     }
166 
167     /**
168      * Obtain the new date property.
169      * @return the new date property.
170      */
171     public ObjectProperty<LocalDate> newDateProperty() {
172         return theNewDate;
173     }
174 
175     /**
176      * Obtain the homePlayer property.
177      * @return the homePlayer property.
178      */
179     public ObjectProperty<Player> homePlayerProperty() {
180         return theHomePlayer;
181     }
182 
183     /**
184      * Obtain the awayPlayer property.
185      * @return the away player property.
186      */
187     public ObjectProperty<Player> awayPlayerProperty() {
188         return theAwayPlayer;
189     }
190 
191     /**
192      * Obtain the result property.
193      * @return the result property.
194      */
195     public ObjectProperty<Result> resultProperty() {
196         return theResult;
197     }
198 
199     /**
200      * Obtain the status property.
201      * @return the status.
202      */
203     public ObjectProperty<PoolStatus> statusProperty() {
204         return theStatus;
205     }
206 
207     /**
208      * Obtain the date.
209      * @return the date.
210      */
211     protected LocalDate getDate() {
212         return theDate.getValue();
213     }
214 
215     /**
216      * Obtain the new date.
217      * @return the new date.
218      */
219     private LocalDate getNewDate() {
220         return theNewDate.getValue();
221     }
222 
223     /**
224      * Obtain the planned date.
225      * @return the planned date.
226      */
227     protected LocalDate getPlannedDate() {
228         LocalDate myDate = getNewDate();
229         return myDate == null
230                              ? getDate()
231                              : myDate;
232     }
233 
234     /**
235      * Obtain the homePlayer.
236      * @return the home player.
237      */
238     public Player getHomePlayer() {
239         return theHomePlayer.getValue();
240     }
241 
242     /**
243      * Obtain the awayPlayer.
244      * @return the away player.
245      */
246     public Player getAwayPlayer() {
247         return theAwayPlayer.getValue();
248     }
249 
250     /**
251      * Obtain the result.
252      * @return the result.
253      */
254     public Result getResult() {
255         return theResult.getValue();
256     }
257 
258     /**
259      * Obtain the status.
260      * @return the status.
261      */
262     public PoolStatus getStatus() {
263         return theStatus.getValue();
264     }
265 
266     /**
267      * Is this a bye?
268      * @return true/false.
269      */
270     public boolean isBye() {
271         return getHomePlayer() == null || getAwayPlayer() == null;
272     }
273 
274     /**
275      * Set the date.
276      * @param pDate the date.
277      */
278     protected void setDate(final LocalDate pDate) {
279         theDate.setValue(pDate);
280     }
281 
282     /**
283      * Set the new date.
284      * @param pDate the new date.
285      */
286     private void setNewDate(final LocalDate pDate) {
287         theNewDate.setValue(pDate);
288     }
289 
290     /**
291      * Set the homePlayer.
292      * @param pPlayer the player.
293      */
294     protected void setHomePlayer(final Player pPlayer) {
295         theHomePlayer.setValue(pPlayer);
296     }
297 
298     /**
299      * Set the awayPlayer.
300      * @param pPlayer the player.
301      */
302     protected void setAwayPlayer(final Player pPlayer) {
303         theAwayPlayer.setValue(pPlayer);
304     }
305 
306     /**
307      * Set the result.
308      * @param pResult the result.
309      */
310     public void setResult(final Result pResult) {
311         theResult.setValue(pResult);
312     }
313 
314     /**
315      * Set the status.
316      * @param pStatus the status.
317      */
318     protected void setStatus(final PoolStatus pStatus) {
319         theStatus.setValue(pStatus);
320     }
321 
322     /**
323      * Set Bye player.
324      * @param pPlayer the final player
325      */
326     protected void setByePlayer(final Player pPlayer) {
327         /* If home player is bye */
328         if (getHomePlayer() == null) {
329             setHomePlayer(pPlayer);
330         } else {
331             setAwayPlayer(pPlayer);
332         }
333     }
334 
335     @Override
336     public boolean equals(final Object pThat) {
337         /* Handle trivial cases */
338         if (this == pThat) {
339             return true;
340         }
341         if (pThat == null) {
342             return false;
343         }
344 
345         /* Handle wrong class */
346         if (!(pThat instanceof Fixture)) {
347             return false;
348         }
349 
350         /* Access as fixture */
351         Fixture myThat = (Fixture) pThat;
352 
353         /* Test on dates */
354         if (!DataSet.isEqual(getDate(), myThat.getDate())) {
355             return false;
356         }
357         if (!DataSet.isEqual(getNewDate(), myThat.getNewDate())) {
358             return false;
359         }
360 
361         /* Test on players */
362         if (!DataSet.isEqual(getHomePlayer(), myThat.getHomePlayer())) {
363             return false;
364         }
365         if (!DataSet.isEqual(getAwayPlayer(), myThat.getAwayPlayer())) {
366             return false;
367         }
368 
369         /* Test on result */
370         return DataSet.isEqual(getResult(), myThat.getResult());
371     }
372 
373     @Override
374     public int hashCode() {
375         int myHash = (theDate.hashCode() * DataSet.HASH_PRIME)
376                 + theNewDate.hashCode();
377         myHash = (myHash * DataSet.HASH_PRIME)
378                 + theHomePlayer.hashCode();
379         myHash = (myHash * DataSet.HASH_PRIME)
380                 + theAwayPlayer.hashCode();
381         return (myHash * DataSet.HASH_PRIME)
382                 + theResult.hashCode();
383     }
384 
385     /**
386      * validate the fixture.
387      * @param pParticipants the player list
388      * @return the status
389      */
390     protected PoolStatus validate(final PlayerList pParticipants) {
391         /* Must have date */
392         LocalDate myDate = getDate();
393         PoolStatus myStatus = (myDate == null)
394                                               ? PoolStatus.INVALID
395                                               : PoolStatus.VALID;
396 
397         /* If we are valid */
398         if (myStatus.isValid()) {
399             Player myHome = getHomePlayer();
400             Player myAway = getAwayPlayer();
401 
402             /* Check home player is one of the participants */
403             if ((myHome != null)
404                     && (pParticipants.getNamedPlayer(myHome.getName()) == null)) {
405                 myStatus = PoolStatus.INVALID;
406             }
407 
408             /* Check away player is one of the participants */
409             if ((myAway != null)
410                     && (pParticipants.getNamedPlayer(myAway.getName()) == null)) {
411                 myStatus = PoolStatus.INVALID;
412             }
413 
414             /* Check that we do not have a double bye */
415             if ((myHome == null) && (myAway == null)) {
416                 myStatus = PoolStatus.INVALID;
417             }
418         }
419 
420         setStatus(myStatus);
421         return myStatus;
422     }
423 
424     /**
425      * Fixture fields.
426      */
427     public enum FixtureField {
428         /**
429          * Name.
430          */
431         DATE,
432 
433         /**
434          * Home player.
435          */
436         HOME,
437 
438         /**
439          * Away Player.
440          */
441         AWAY,
442 
443         /**
444          * Result.
445          */
446         RESULT,
447 
448         /**
449          * NewDate.
450          */
451         NEWDATE,
452 
453         /**
454          * Status.
455          */
456         STATUS;
457 
458         /**
459          * The String name.
460          */
461         private String theName;
462 
463         @Override
464         public String toString() {
465             /* If we have not yet loaded the name */
466             if (theName == null) {
467                 /* Load the name */
468                 theName = DataResource.getKeyForFixtureField(this).getValue();
469             }
470 
471             /* return the name */
472             return theName;
473         }
474     }
475 }