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.Comparator;
21  import java.util.Iterator;
22  
23  import javafx.beans.Observable;
24  import javafx.beans.property.ObjectProperty;
25  import javafx.beans.property.SimpleObjectProperty;
26  import javafx.collections.FXCollections;
27  import javafx.collections.ObservableList;
28  import net.sourceforge.jhunters.pool.PoolStatus;
29  
30  /**
31   * Competition.
32   */
33  public class Competition
34          implements Comparable<Competition> {
35      /**
36       * Object name.
37       */
38      protected static final String OBJECT_NAME = DataResource.COMPETITION_NAME.getValue();
39  
40      /**
41       * Participant List Name.
42       */
43      protected static final String PARTICIPANT_LIST = "Participants";
44  
45      /**
46       * Participant Name.
47       */
48      protected static final String PARTICIPANT_NAME = "Participant";
49  
50      /**
51       * Competition Name.
52       */
53      private final ObjectProperty<String> theName;
54  
55      /**
56       * Competition Start Date.
57       */
58      private final ObjectProperty<LocalDate> theStartDate;
59  
60      /**
61       * Competition Player Count.
62       */
63      private final ObjectProperty<Integer> thePlayerCount;
64  
65      /**
66       * Competition Active.
67       */
68      private final ObjectProperty<Boolean> theActive;
69  
70      /**
71       * ParticipantList.
72       */
73      private final PlayerList theParticipants;
74  
75      /**
76       * FixtureList.
77       */
78      private final FixtureList theFixtures;
79  
80      /**
81       * CompetitionMatrix.
82       */
83      private final CompetitionMatrix theMatrix;
84  
85      /**
86       * The status of the list.
87       */
88      private PoolStatus theStatus;
89  
90      /**
91       * Table.
92       */
93      private final CompetitionStandings theTable;
94  
95      /**
96       * Constructor.
97       */
98      public Competition() {
99          theName = new SimpleObjectProperty<String>(this, CompetitionField.NAME.toString());
100         theStartDate = new SimpleObjectProperty<LocalDate>(this, CompetitionField.STARTDATE.toString());
101         thePlayerCount = new SimpleObjectProperty<Integer>(this, CompetitionField.PLAYERS.toString());
102         theActive = new SimpleObjectProperty<Boolean>(this, CompetitionField.ACTIVE.toString());
103         theParticipants = new PlayerList();
104         theFixtures = new FixtureList();
105         theTable = new CompetitionStandings(this);
106         theMatrix = new CompetitionMatrix();
107     }
108 
109     /**
110      * Set named property.
111      * @param pName the name of the property.
112      * @param pValue the value of the property.
113      */
114     protected void setNamedProperty(final String pName,
115                                     final String pValue) {
116         if (pName.equals(CompetitionField.NAME.toString())) {
117             setName(pValue);
118         } else if (pName.equals(CompetitionField.STARTDATE.toString())) {
119             setStartDate(DataParser.parseDate(pValue));
120         }
121     }
122 
123     /**
124      * Obtain the name property.
125      * @return the competition name property.
126      */
127     public ObjectProperty<String> nameProperty() {
128         return theName;
129     }
130 
131     /**
132      * Obtain the startDate property.
133      * @return the startDate property.
134      */
135     public ObjectProperty<LocalDate> startDateProperty() {
136         return theStartDate;
137     }
138 
139     /**
140      * Obtain the player count property.
141      * @return the player count property.
142      */
143     public ObjectProperty<Integer> playerCountProperty() {
144         return thePlayerCount;
145     }
146 
147     /**
148      * Obtain the active property.
149      * @return the active property.
150      */
151     public ObjectProperty<Boolean> activeProperty() {
152         return theActive;
153     }
154 
155     /**
156      * Obtain the name.
157      * @return the player name.
158      */
159     public String getName() {
160         return theName.getValue();
161     }
162 
163     /**
164      * Obtain startDate.
165      * @return the startDate
166      */
167     protected LocalDate getStartDate() {
168         return theStartDate.getValue();
169     }
170 
171     /**
172      * Is the player active?
173      * @return true/false.
174      */
175     public Boolean isActive() {
176         return theActive.getValue();
177     }
178 
179     /**
180      * Obtain participants.
181      * @return the participants
182      */
183     public PlayerList getParticipants() {
184         return theParticipants;
185     }
186 
187     /**
188      * Obtain fixture list.
189      * @return the fixture list
190      */
191     public FixtureList getFixtureList() {
192         return theFixtures;
193     }
194 
195     /**
196      * Obtain the number of FixtureSets.
197      * @return the # fixture sets.
198      */
199     public Integer getNumWeeks() {
200         return theFixtures.size();
201     }
202 
203     /**
204      * Obtain the player count.
205      * @return the # players.
206      */
207     public Integer getPlayerCount() {
208         return thePlayerCount.getValue();
209     }
210 
211     /**
212      * Obtain the numbered fixtureSet.
213      * @param pWeek the week #
214      * @return the fixture set.
215      */
216     public FixtureSet getFixtureSet(final Integer pWeek) {
217         return theFixtures.getFixtureSet(pWeek);
218     }
219 
220     /**
221      * Obtain participants iterator.
222      * @return the iterator
223      */
224     protected Iterator<Player> participantIterator() {
225         return theParticipants.playerIterator();
226     }
227 
228     /**
229      * Obtain fixture list.
230      * @return the fixture list
231      */
232     protected Iterator<FixtureSet> fixtureIterator() {
233         return theFixtures.fixtureIterator();
234     }
235 
236     /**
237      * Obtain table.
238      * @return the table
239      */
240     public CompetitionStandings getTable() {
241         return theTable;
242     }
243 
244     /**
245      * Obtain matrix.
246      * @return the matrix
247      */
248     public CompetitionMatrix getMatrix() {
249         return theMatrix;
250     }
251 
252     /**
253      * Obtain the status.
254      * @return the status.
255      */
256     public PoolStatus getStatus() {
257         return theStatus;
258     }
259 
260     /**
261      * Set the name.
262      * @param pName the name.
263      */
264     public void setName(final String pName) {
265         theName.setValue(pName == null
266                                        ? null
267                                        : pName.trim());
268     }
269 
270     /**
271      * Set the startDate.
272      * @param pDate the date.
273      */
274     public void setStartDate(final LocalDate pDate) {
275         theStartDate.setValue(pDate);
276     }
277 
278     /**
279      * Set the active flag.
280      * @param pValue the new value.
281      */
282     protected void setActive(final Boolean pValue) {
283         theActive.setValue(pValue);
284     }
285 
286     /**
287      * Set the status.
288      * @param pStatus the status.
289      */
290     protected void setStatus(final PoolStatus pStatus) {
291         theStatus = pStatus;
292     }
293 
294     /**
295      * Set the participants.
296      * @param pParticipants the participants
297      */
298     protected void setParticipants(final Iterator<Player> pParticipants) {
299         /* Copy the players */
300         theParticipants.setPlayers(pParticipants);
301 
302         /* Set player count */
303         thePlayerCount.setValue(theParticipants.size());
304 
305         /* Reset the fixture list and table */
306         theFixtures.reset();
307         theMatrix.setPlayers(theParticipants.getPlayers());
308     }
309 
310     /**
311      * Set the fixture list.
312      * @param pFixtures the fixture list
313      */
314     protected void setFixtures(final Iterator<FixtureSet> pFixtures) {
315         /* Copy the fixtures */
316         theFixtures.setFixtures(pFixtures);
317     }
318 
319     /**
320      * update dates.
321      */
322     public void updateDates() {
323         /* Update the dates */
324         theFixtures.setDates(getStartDate());
325     }
326 
327     @Override
328     public String toString() {
329         return getName();
330     }
331 
332     @Override
333     public boolean equals(final Object pThat) {
334         /* Handle trivial cases */
335         if (this == pThat) {
336             return true;
337         }
338         if (pThat == null) {
339             return false;
340         }
341 
342         /* Handle wrong class */
343         if (!(pThat instanceof Competition)) {
344             return false;
345         }
346 
347         /* Access as competition */
348         Competition myThat = (Competition) pThat;
349 
350         /* Test on name */
351         if (!DataSet.isEqual(getName(), myThat.getName())) {
352             return false;
353         }
354 
355         /* Test on participants */
356         if (!theParticipants.equals(myThat.getParticipants())) {
357             return false;
358         }
359 
360         /* Test on fixture list */
361         return theFixtures.equals(myThat.getFixtureList());
362     }
363 
364     @Override
365     public int hashCode() {
366         int myHash = (theParticipants.hashCode() * DataSet.HASH_PRIME)
367                      + theFixtures.hashCode();
368         return (myHash * DataSet.HASH_PRIME)
369                + theName.hashCode();
370     }
371 
372     @Override
373     public int compareTo(final Competition pThat) {
374         /* Check for equality and null competition */
375         if (equals(pThat)) {
376             return 0;
377         }
378         if (pThat == null) {
379             return -1;
380         }
381 
382         /* Access names */
383         String myName = getName();
384         String myOther = pThat.getName();
385 
386         /* Check for null names */
387         if (myName == null) {
388             return 1;
389         }
390         if (myOther == null) {
391             return -1;
392         }
393 
394         /* Compare names */
395         return myName.compareTo(myOther);
396     }
397 
398     /**
399      * Comparator class.
400      */
401     public static final class CompetitionComparator
402             implements Comparator<Competition> {
403         @Override
404         public int compare(final Competition pFirst,
405                            final Competition pSecond) {
406             return pFirst.compareTo(pSecond);
407         }
408     }
409 
410     /**
411      * Obtain the outstanding fixtures as of base date.
412      * @param pBase the base date
413      * @return the outstanding fixtures.
414      */
415     public ObservableList<Fixture> getOutstandingFixtures(final LocalDate pBase) {
416         /* Create a new list */
417         ObservableList<Fixture> myOutstanding = FXCollections.observableArrayList(p -> new Observable[]
418         { p.resultProperty() });
419 
420         /* Loop through the fixtureSets */
421         Iterator<FixtureSet> myIterator = fixtureIterator();
422         while (myIterator.hasNext()) {
423             FixtureSet myCurr = myIterator.next();
424 
425             /* Obtain fixtures */
426             myCurr.getFixtures(myOutstanding, pBase);
427         }
428 
429         /* return the list */
430         return myOutstanding;
431     }
432 
433     /**
434      * validate the competition.
435      * @return the status
436      */
437     protected PoolStatus validate() {
438         /* Access the name */
439         String myName = getName();
440         theStatus = ((myName == null)
441                      || (myName.length() == 0))
442                                                 ? PoolStatus.INVALID
443                                                 : PoolStatus.VALID;
444 
445         /* If we are valid */
446         if (theStatus.isValid()) {
447             /* Validate the participants */
448             theStatus = theParticipants.validate();
449         }
450 
451         /* If we are valid */
452         if (theStatus.isValid()) {
453             /* Set active status on participants */
454             theParticipants.setActive(Boolean.TRUE);
455 
456             /* validate the fixture list */
457             theStatus = theFixtures.validate(theParticipants);
458         }
459 
460         /* return the status */
461         return theStatus;
462     }
463 
464     /**
465      * adjust the players.
466      */
467     protected void adjustPlayers() {
468         /* re-sort the table */
469         theTable.sortTable();
470 
471         /* adjust the matrix */
472         theMatrix.adjustPlayers();
473     }
474 
475     /**
476      * process the fixtures.
477      */
478     public void processFixtures() {
479         /* build the table */
480         theTable.processFixtures(theFixtures);
481 
482         /* build the matrix */
483         theMatrix.processFixtures(theFixtures);
484     }
485 
486     /**
487      * Competition fields.
488      */
489     public enum CompetitionField {
490         /**
491          * Name.
492          */
493         NAME,
494 
495         /**
496          * StartDate.
497          */
498         STARTDATE,
499 
500         /**
501          * # of players.
502          */
503         PLAYERS,
504 
505         /**
506          * Active.
507          */
508         ACTIVE;
509 
510         /**
511          * The String name.
512          */
513         private String theName;
514 
515         @Override
516         public String toString() {
517             /* If we have not yet loaded the name */
518             if (theName == null) {
519                 /* Load the name */
520                 theName = DataResource.getKeyForCompetitionField(this).getValue();
521             }
522 
523             /* return the name */
524             return theName;
525         }
526     }
527 }