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.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  
28  import javafx.collections.FXCollections;
29  import javafx.collections.ObservableList;
30  import net.sourceforge.jhunters.pool.data.CompetitionFixtures.FixtureComparator;
31  import net.sourceforge.jhunters.pool.data.CompetitionFixtures.FixtureRecord;
32  import net.sourceforge.jhunters.pool.data.Player.PlayerComparator;
33  
34  /**
35   * Competition matrix.
36   */
37  public class CompetitionMatrix {
38      /**
39       * The list of competition fixtures.
40       */
41      private final ObservableList<CompetitionFixtures> theFixtures;
42  
43      /**
44       * The map of entries.
45       */
46      private final Map<Integer, CompetitionFixtures> theFixtureMap;
47  
48      /**
49       * The comparator.
50       */
51      private final Comparator<CompetitionFixtures> theComparator;
52  
53      /**
54       * Constructor.
55       */
56      protected CompetitionMatrix() {
57          theFixtures = FXCollections.observableArrayList();
58          theFixtureMap = new HashMap<Integer, CompetitionFixtures>();
59          theComparator = new FixtureComparator();
60      }
61  
62      /**
63       * Set players.
64       * @param pPlayers the list of players
65       */
66      protected void setPlayers(final List<Player> pPlayers) {
67          /* Obtain a copy of the players and sort the list */
68          List<Player> myList = new ArrayList<Player>(pPlayers);
69          Collections.sort(myList, new PlayerComparator());
70  
71          /* Initialise counter and list size */
72          int i = 0;
73          int mySize = pPlayers.size();
74  
75          /* Loop through the players */
76          Iterator<Player> myIterator = myList.iterator();
77          while (myIterator.hasNext()) {
78              Player myPlayer = myIterator.next();
79  
80              /* Create the fixtures */
81              CompetitionFixtures myFixtures = new CompetitionFixtures(myPlayer, mySize);
82              myFixtures.setIndex(i++);
83              theFixtures.add(myFixtures);
84              theFixtureMap.put(myPlayer.getId(), myFixtures);
85          }
86      }
87  
88      /**
89       * Reset players.
90       */
91      protected void adjustPlayers() {
92          /* Determine any re-map required */
93          RemapMatrix myMapping = new RemapMatrix();
94  
95          /* If we need to reMap indices */
96          if (myMapping.isReMapRequired()) {
97              /* Adjust the fixtures */
98              myMapping.adjustFixtures();
99  
100             /* Set new indices */
101             myMapping.setNewIndices();
102         }
103     }
104 
105     /**
106      * Obtain the matrix.
107      * @return the matrix
108      */
109     public ObservableList<CompetitionFixtures> getMatrix() {
110         return theFixtures;
111     }
112 
113     /**
114      * Obtain fixtures for player.
115      * @param pPlayer the player
116      * @return the fixtures
117      */
118     private CompetitionFixtures getFixtures(final Player pPlayer) {
119         return theFixtureMap.get(pPlayer.getId());
120     }
121 
122     /**
123      * Process fixtures.
124      * @param pFixtures the fixtures
125      */
126     protected void processFixtures(final FixtureList pFixtures) {
127         /* Reset the outlook cache */
128         resetOutlook();
129 
130         /* Loop through the fixture sets */
131         Iterator<FixtureSet> myIterator = pFixtures.fixtureIterator();
132         while (myIterator.hasNext()) {
133             FixtureSet mySet = myIterator.next();
134 
135             /* Process fixture set */
136             processFixtureSet(mySet);
137         }
138 
139         /* determine the outlook */
140         determineOutlook();
141     }
142 
143     /**
144      * Process fixtureSet.
145      * @param pSet the fixture Set
146      */
147     private void processFixtureSet(final FixtureSet pSet) {
148         /* Loop through the fixtures */
149         Iterator<Fixture> myIterator = pSet.fixtureIterator();
150         while (myIterator.hasNext()) {
151             Fixture myFixture = myIterator.next();
152 
153             /* Ignore byes */
154             if (myFixture.isBye()) {
155                 continue;
156             }
157 
158             /* Process fixture */
159             processFixture(myFixture);
160         }
161     }
162 
163     /**
164      * Process fixture.
165      * @param pFixture the fixture
166      */
167     protected void processFixture(final Fixture pFixture) {
168         /* Access player details */
169         CompetitionFixtures myHome = getFixtures(pFixture.getHomePlayer());
170         CompetitionFixtures myAway = getFixtures(pFixture.getAwayPlayer());
171 
172         /* Obtain result details */
173         Result myResult = pFixture.getResult();
174         if (myResult != null) {
175             /* Set results */
176             myHome.setResult(myResult, myAway);
177             myAway.setResult(myResult.reverse(), myHome);
178 
179             /* else not played yet */
180         } else {
181             LocalDate myDate = pFixture.getPlannedDate();
182 
183             /* Set date */
184             myHome.setOutlook(myDate, myAway);
185             myAway.setOutlook(myDate, myHome);
186         }
187     }
188 
189     /**
190      * reset outlook.
191      */
192     private void resetOutlook() {
193         /* Loop through the fixtures */
194         Iterator<CompetitionFixtures> myIterator = theFixtures.iterator();
195         while (myIterator.hasNext()) {
196             CompetitionFixtures myFixtures = myIterator.next();
197 
198             /* determine outlook */
199             myFixtures.resetOutlook();
200         }
201     }
202 
203     /**
204      * determine outlook.
205      */
206     private void determineOutlook() {
207         /* Loop through the fixtures */
208         Iterator<CompetitionFixtures> myIterator = theFixtures.iterator();
209         while (myIterator.hasNext()) {
210             CompetitionFixtures myFixtures = myIterator.next();
211 
212             /* determine outlook */
213             myFixtures.determineOutlook();
214         }
215     }
216 
217     /**
218      * ReMapping definition.
219      */
220     private final class RemapMatrix {
221         /**
222          * ReMap definition.
223          */
224         private final List<Integer[]> theMap;
225 
226         /**
227          * Constructor.
228          */
229         private RemapMatrix() {
230             /* Create the map */
231             theMap = new ArrayList<Integer[]>();
232 
233             /* ReSort the fixture list */
234             FXCollections.sort(theFixtures, theComparator);
235 
236             /* Loop through the fixtures */
237             int myIndex = 0;
238             Iterator<CompetitionFixtures> myIterator = theFixtures.iterator();
239             while (myIterator.hasNext()) {
240                 CompetitionFixtures myFixtures = myIterator.next();
241 
242                 /* If re-mapping is required */
243                 int myCurIndex = myFixtures.getIndex();
244                 if (myIndex != myCurIndex) {
245                     /* Create the map and record it */
246                     Integer[] myMap = new Integer[]
247                     { myCurIndex, myIndex };
248                     theMap.add(myMap);
249                 }
250 
251                 /* Increment index */
252                 myIndex++;
253             }
254         }
255 
256         /**
257          * Is reMap required?
258          * @return true/false
259          */
260         private boolean isReMapRequired() {
261             return !theMap.isEmpty();
262         }
263 
264         /**
265          * Adjust fixtures.
266          */
267         private void adjustFixtures() {
268             /* Loop through the fixtures */
269             Iterator<CompetitionFixtures> myIterator = theFixtures.iterator();
270             while (myIterator.hasNext()) {
271                 CompetitionFixtures myFixtures = myIterator.next();
272 
273                 /* Adjust the fixtures */
274                 adjustFixtures(myFixtures);
275             }
276         }
277 
278         /**
279          * Obtain values.
280          * @param pFixtures the fixtures
281          */
282         private void adjustFixtures(final CompetitionFixtures pFixtures) {
283             /* Create cache of values to be moved */
284             FixtureRecord[] myCache = new FixtureRecord[theMap.size()];
285 
286             /* Loop through the maps */
287             int i = 0;
288             Iterator<Integer[]> myIterator = theMap.iterator();
289             while (myIterator.hasNext()) {
290                 Integer[] myMapping = myIterator.next();
291 
292                 /* Obtain the value */
293                 myCache[i++] = pFixtures.fixtureProperty(myMapping[0]).getValue();
294             }
295 
296             /* Perform second loop */
297             i = 0;
298             myIterator = theMap.iterator();
299             while (myIterator.hasNext()) {
300                 Integer[] myMapping = myIterator.next();
301 
302                 /* Set the value */
303                 pFixtures.fixtureProperty(myMapping[1]).setValue(myCache[i++]);
304             }
305         }
306 
307         /**
308          * Set new indices.
309          */
310         private void setNewIndices() {
311             /* Loop through the fixtures */
312             int myIndex = 0;
313             Iterator<CompetitionFixtures> myIterator = theFixtures.iterator();
314             while (myIterator.hasNext()) {
315                 CompetitionFixtures myFixtures = myIterator.next();
316 
317                 /* Adjust the index */
318                 myFixtures.setIndex(myIndex++);
319             }
320         }
321     }
322 }