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.util.HashMap;
20  import java.util.Iterator;
21  import java.util.Map;
22  
23  import javafx.beans.Observable;
24  import javafx.collections.FXCollections;
25  import javafx.collections.ObservableList;
26  import net.sourceforge.jhunters.pool.PoolStatus;
27  
28  /**
29   * Player List.
30   */
31  public class PlayerList {
32      /**
33       * Player List Name.
34       */
35      protected static final String LIST_NAME = DataResource.PLAYER_LIST.getValue();
36  
37      /**
38       * The list of Players.
39       */
40      private final ObservableList<Player> thePlayers;
41  
42      /**
43       * The status of the list.
44       */
45      private PoolStatus theStatus;
46  
47      /**
48       * The nextId.
49       */
50      private int theNextId = 1;
51  
52      /**
53       * Constructor.
54       */
55      protected PlayerList() {
56          /* Create the player list with an extractor to allow SortedList to work */
57          thePlayers = FXCollections.observableArrayList(p -> new Observable[] { p.nameProperty(), p.contactProperty(), p.selectedProperty() });
58      }
59  
60      /**
61       * Obtain player list.
62       * @return the player list
63       */
64      public ObservableList<Player> getPlayers() {
65          return thePlayers;
66      }
67  
68      /**
69       * Obtain number of players.
70       * @return # of players
71       */
72      public int size() {
73          return thePlayers.size();
74      }
75  
76      /**
77       * Is the list of players empty?
78       * @return true/false
79       */
80      public boolean isEmpty() {
81          return thePlayers.isEmpty();
82      }
83  
84      /**
85       * Obtain the status.
86       * @return the status.
87       */
88      public PoolStatus getStatus() {
89          return theStatus;
90      }
91  
92      /**
93       * Obtain player iterator.
94       * @return the iterator list
95       */
96      public Iterator<Player> playerIterator() {
97          return thePlayers.iterator();
98      }
99  
100     /**
101      * Obtain named player from list.
102      * @param pName the player name.
103      * @return the player (or null if not found)
104      */
105     public Player getNamedPlayer(final String pName) {
106         /* Loop through the list */
107         Iterator<Player> myIterator = thePlayers.iterator();
108         while (myIterator.hasNext()) {
109             Player myPlayer = myIterator.next();
110 
111             /* Return if we have found the player */
112             if (pName.equals(myPlayer.getName())) {
113                 return myPlayer;
114             }
115         }
116 
117         /* Not found */
118         return null;
119     }
120 
121     /**
122      * Create unique player.
123      * @return the unique player
124      */
125     public Player createUniquePlayer() {
126         /* Create the builder */
127         StringBuilder myBuilder = new StringBuilder();
128         myBuilder.append("Player");
129         int myLen = myBuilder.length();
130 
131         /* Loop through the list */
132         int myIndex = 0;
133         Player myPlayer;
134         String myName;
135 
136         /* Loop to find a unique name */
137         do {
138             /* Reset the buffer and adjust index */
139             myBuilder.setLength(myLen);
140             myIndex++;
141 
142             /* Create name */
143             myBuilder.append(myIndex);
144             myName = myBuilder.toString();
145             myPlayer = getNamedPlayer(myName);
146 
147             /* ReLoop if already exists */
148         } while (myPlayer != null);
149 
150         /* Create the player */
151         myPlayer = new Player();
152         myPlayer.setName(myName);
153 
154         /* Create a unique id */
155         setUniqueId(myPlayer);
156 
157         /* Add the name to the list and return it */
158         thePlayers.add(myPlayer);
159         return myPlayer;
160     }
161 
162     /**
163      * Set active status.
164      * @param pValue the active status
165      */
166     protected void setActive(final Boolean pValue) {
167         /* Loop through the list */
168         Iterator<Player> myIterator = thePlayers.iterator();
169         while (myIterator.hasNext()) {
170             Player myPlayer = myIterator.next();
171 
172             /* set active status */
173             myPlayer.setActive(pValue);
174         }
175     }
176 
177     /**
178      * Add a player to the list.
179      * @param pPlayer the player.
180      */
181     public void addPlayer(final Player pPlayer) {
182         /* If player does not already exist */
183         if ((pPlayer != null)
184                 && (getNamedPlayer(pPlayer.getName()) == null)) {
185             /* If the id is not set */
186             Integer myId = pPlayer.getId();
187             if (myId == 0) {
188                 /* Create a unique id */
189                 setUniqueId(pPlayer);
190 
191                 /* else adjust next id */
192             } else if (myId >= theNextId) {
193                 theNextId = myId + 1;
194             }
195 
196             /* Add the player */
197             thePlayers.add(pPlayer);
198         }
199     }
200 
201     /**
202      * Set unique id.
203      * @param pPlayer the player to set
204      */
205     private synchronized void setUniqueId(final Player pPlayer) {
206         /* Determine next available id */
207         Integer myNext = theNextId++;
208         pPlayer.setId(myNext);
209     }
210 
211     /**
212      * Remove a player from the list.
213      * @param pPlayer the player.
214      */
215     public void removePlayer(final Player pPlayer) {
216         thePlayers.remove(pPlayer);
217     }
218 
219     /**
220      * Set players.
221      * @param pSource the source players.
222      */
223     protected void setPlayers(final Iterator<Player> pSource) {
224         /* reset the player list */
225         thePlayers.clear();
226 
227         /* Loop through the source list */
228         while (pSource.hasNext()) {
229             Player myPlayer = pSource.next();
230 
231             /* Add the player */
232             thePlayers.add(myPlayer);
233 
234             /* Adjust next if necessary */
235             Integer myId = myPlayer.getId();
236             if (myId >= theNextId) {
237                 theNextId = myId + 1;
238             }
239         }
240     }
241 
242     @Override
243     public boolean equals(final Object pThat) {
244         /* Handle trivial cases */
245         if (this == pThat) {
246             return true;
247         }
248         if (pThat == null) {
249             return false;
250         }
251 
252         /* Handle wrong class */
253         if (!(pThat instanceof PlayerList)) {
254             return false;
255         }
256 
257         /* Access as player list */
258         PlayerList myThat = (PlayerList) pThat;
259 
260         /* Test only on player list */
261         return thePlayers.equals(myThat.getPlayers());
262     }
263 
264     @Override
265     public int hashCode() {
266         return thePlayers.hashCode();
267     }
268 
269     /**
270      * Validate players.
271      * @return the status
272      */
273     public PoolStatus validate() {
274         /* Create id and name maps */
275         Map<String, PoolStatus> myNameMap = new HashMap<String, PoolStatus>();
276         Map<Integer, PoolStatus> myIdMap = new HashMap<Integer, PoolStatus>();
277         theStatus = PoolStatus.VALID;
278 
279         /* Loop through the players */
280         Iterator<Player> myIterator = playerIterator();
281         while (myIterator.hasNext()) {
282             Player myPlayer = myIterator.next();
283 
284             /* Validate the player */
285             PoolStatus myStatus = myPlayer.validate();
286             if (!myStatus.isValid()) {
287                 theStatus = PoolStatus.INVALID;
288             } else {
289                 /* Check for preExistence of name */
290                 String myName = myPlayer.getName();
291                 PoolStatus myExisting = myNameMap.get(myName);
292                 myNameMap.put(myName, myExisting == null
293                                                         ? PoolStatus.VALID
294                                                         : PoolStatus.DUPLICATE);
295 
296                 /* Check for preExistence of id */
297                 Integer myId = myPlayer.getId();
298                 myExisting = myIdMap.get(myId);
299                 myIdMap.put(myId, myExisting == null
300                                                     ? PoolStatus.VALID
301                                                     : PoolStatus.DUPLICATE);
302             }
303         }
304 
305         /* If we are valid */
306         if (theStatus.isValid()) {
307             /* Loop through the players */
308             myIterator = playerIterator();
309             while (myIterator.hasNext()) {
310                 Player myPlayer = myIterator.next();
311 
312                 /* Ignore invalid players */
313                 if (!myPlayer.getStatus().isValid()) {
314                     continue;
315                 }
316 
317                 /* If the name is duplicate */
318                 String myName = myPlayer.getName();
319                 PoolStatus myStatus = myNameMap.get(myName);
320                 if (!myStatus.isValid()) {
321                     /* Set as duplicate */
322                     theStatus = PoolStatus.DUPLICATE;
323                     myPlayer.setStatus(theStatus);
324                 }
325 
326                 /* If the id is duplicate */
327                 Integer myId = myPlayer.getId();
328                 myStatus = myIdMap.get(myId);
329                 if (!myStatus.isValid()) {
330                     /* Set as duplicate */
331                     theStatus = PoolStatus.DUPLICATE;
332                     myPlayer.setStatus(theStatus);
333                 }
334             }
335         }
336 
337         /* return the status */
338         return theStatus;
339     }
340 }