View Javadoc
1   /******************************************************************************
2    * Document - Primary document in an MVC model 
3    * $Id$
4    * 
5    * BuckoFIBS - Backgammon by BuckoSoft
6    * Copyright© 2009,2010 - Dick Balaska - BuckoSoft, Corp.
7    * 
8    * $Log$
9    * Revision 1.4  2011/06/02 12:36:46  dick
10   * Javadoc.
11   *
12   */
13  
14  /* 
15   * This program is free software: you can redistribute it and/or modify
16   * it under the terms of the GNU General Public License as published by
17   * the Free Software Foundation, either version 3 of the License, or
18   * (at your option) any later version.
19   *
20   * This program is distributed in the hope that it will be useful,
21   * but WITHOUT ANY WARRANTY; without even the implied warranty of
22   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   * GNU General Public License for more details.
24   *
25   * You should have received a copy of the GNU General Public License
26   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27   *
28   * The Original Code is BuckoFIBS, <http://www.buckosoft.com/BuckoFIBS/>.
29   * The Initial Developer of the Original Code is Dick Balaska and BuckoSoft, Corp.
30   * 
31   */
32  package com.buckosoft.fibs.document;
33  
34  import java.util.LinkedList;
35  
36  import com.buckosoft.fibs.domain.Board;
37  import com.buckosoft.fibs.domain.SavedMatch;
38  
39  /** Primary document in an MVC model 
40   * @author Dick Balaska
41   * @since 2011/03/14
42   * @version $Revision$ <br> $Date$
43   * @see <a href="http://cvs.buckosoft.com/Projects/BuckoFIBS/BuckoFIBS/src/main/java/com/buckosoft/fibs/document/Document.java">cvs Document.java</a>
44   * @see <a href="http://www.fibs.com/fibs_interface.html#board_state" target="_top">FIBS Client Protocol Detailed Specification</a>
45   */
46  public class Document {
47  	//private final static boolean DEBUG = false;
48  
49  	// These are user settings 
50  	// They are game settings.
51  	private	String	name = "?";
52  	private boolean allowPip;
53  	private	boolean autoBoard;
54  	private	boolean autoDouble;
55  	private boolean autoMove;
56  	private	boolean	away;
57  	private	boolean bell;
58  	private boolean crawford;
59  	private	boolean	askDouble;
60  	private	int		experience;
61  	private	boolean greedy;
62  	private	boolean moreBoards;
63  	private	boolean moves;
64  	private	boolean notify;
65  	private	double	rating;
66  	private	boolean ratings;
67  	private	boolean ready;
68  	private	int		redoubles;
69  	private	boolean	report;
70  	private	boolean	silent;
71  	private	String	timezone;
72  	
73  	private	Board	board = new Board();
74  	private	LinkedList<SavedMatch>	savedMatches = new LinkedList<SavedMatch>();
75  	// Reuse SavedMatch Object
76  	private	LinkedList<SavedMatch>	missManners = new LinkedList<SavedMatch>();
77  
78  	
79  	/** Get the Board.  This is the latest board we have received from FIBS
80  	 * @return the board
81  	 */
82  	public Board getBoard() {
83  		return board;
84  	}
85  
86  	/**
87  	 * @param board the board to set
88  	 */
89  	public void setBoard(Board board) {
90  		this.board = board;
91  	}
92  
93  	/** Called at the beginning of a game, resets game user attributes
94  	 */
95  	public void resetGame() {
96  		this.greedy = false;
97  		this.askDouble = true;
98  	//	this.wasDoubled[0] = false;
99  	//	this.wasDoubled[1] = false;
100 		this.board.setYourTurnToRollOrDouble(false);
101 	}
102 
103 	/** Set and clear the state where You push a double to Your opponent.
104 	 * @param doubleFlag true = you have doubled
105 	 */ 
106 	public void setYouDouble(boolean doubleFlag) {
107 		this.board.setYourTurnToRollOrDouble(false);
108 	//	this.wasDoubled[0] = doubleFlag;
109 	}
110 
111 	/** Return the userid that this player logged in as.
112 	 * @return the name
113 	 */
114 	public String getName() {
115 		return name;
116 	}
117 
118 	/**
119 	 * @return the allowPip
120 	 */
121 	public boolean isAllowPip() {
122 		return allowPip;
123 	}
124 
125 	/**
126 	 * @return the autoBoard
127 	 */
128 	public boolean isAutoBoard() {
129 		return autoBoard;
130 	}
131 
132 	/**
133 	 * @param autoBoard the autoBoard to set
134 	 */
135 	public void setAutoBoard(boolean autoBoard) {
136 		this.autoBoard = autoBoard;
137 	}
138 
139 	/**
140 	 * @return the autoDouble
141 	 */
142 	public boolean isAutoDouble() {
143 		return autoDouble;
144 	}
145 
146 	/**
147 	 * @return the autoMove
148 	 */
149 	public boolean isAutoMove() {
150 		return autoMove;
151 	}
152 
153 	/** Have You tagged yourself as away?
154 	 * @return true if You are not accepting invitations
155 	 */
156 	public boolean isAway() {
157 		return away;
158 	}
159 
160 	/** Like, totally ignored.
161 	 * @return the bell
162 	 */
163 	public boolean isBell() {
164 		return bell;
165 	}
166 
167 	/** Is this a crawford game?
168 	 * @return the crawford
169 	 */
170 	public boolean isCrawford() {
171 		return crawford;
172 	}
173 
174 	/** Does the server push dice at you or wait to see if you want to roll or double
175 	 * @return the askDouble
176 	 */
177 	public boolean isAskDouble() {
178 		return this.askDouble;
179 	}
180 
181 	public void setAskDouble(boolean askDoubles) {
182 		this.askDouble = askDoubles;
183 	}
184 
185 	/** How many games have You played?
186 	 * @return the experience
187 	 */
188 	public int getExperience() {
189 		return experience;
190 	}
191 
192 	/** Are You using greedy bearoffs?
193 	 * @return the greedy
194 	 */
195 	public boolean isGreedy() {
196 		return greedy;
197 	}
198 
199 	public void setGreedy(boolean greedy) {
200 		this.greedy = greedy;
201 	}
202 
203 	/** This is pretty darn useful for client programs, so if you see it toggled off you probably want to toggle it back on.
204 	 * @return the moreBoards
205 	 */
206 	public boolean isMoreBoards() {
207 		return moreBoards;
208 	}
209 
210 	/**
211 	 * @return the moves
212 	 */
213 	public boolean isMoves() {
214 		return moves;
215 	}
216 
217 	/** Are we being notified when new users log on and off?
218 	 * @return the notify
219 	 */
220 	public boolean isNotify() {
221 		return notify;
222 	}
223 
224 	/** What is Your FIBS rating?
225 	 * @return the rating
226 	 */
227 	public double getRating() {
228 		return rating;
229 	}
230 
231 	/**
232 	 * @return the ratings
233 	 */
234 	public boolean isRatings() {
235 		return ratings;
236 	}
237 
238 	/** Are you ready to play?
239 	 * @return the ready
240 	 */
241 	public boolean isReady() {
242 		return ready;
243 	}
244 
245 	/** Set whether we are ready to play
246 	 * @param ready the ready to set
247 	 */
248 	public void setReady(boolean ready) {
249 		this.ready = ready;
250 	}
251 
252 	/** Je ne comprends pas
253 	 * @return the redoubles
254 	 */
255 	public int getRedoubles() {
256 		return redoubles;
257 	}
258 
259 	/** Are we being notified about the starting and ending of other matches? 
260 	 * @return the report
261 	 */
262 	public boolean isReport() {
263 		return report;
264 	}
265 
266 	/** Do we receive the shout messages (general chat)?<br>
267 	 * Note that BuckoFIBS always receives the shouts and filters them from display.
268 	 * @return the silent
269 	 */
270 	public boolean isSilent() {
271 		return silent;
272 	}
273 
274 	/** Get your timezone.
275 	 * @return the timezone
276 	 */
277 	public String getTimezone() {
278 		return timezone;
279 	}
280 
281 
282 	/** If you have a saved match against this player, this is a tooltip string describing it.
283 	 * @param playerName The player to check for saved matches.
284 	 * @return A tooltip String or null if no saved match found
285 	 */ 
286 	public String	getSavedMatchString(String playerName) {
287 		for (SavedMatch sm : savedMatches) {
288 			if (sm.getOpponentName().equals(playerName)) {
289 				StringBuffer sb = new StringBuffer();
290 				sb.append("Saved Match. Length: ");
291 				sb.append(sm.getMatchLength());
292 				sb.append(" Score: (you) ");
293 				sb.append(sm.getYourScore());
294 				sb.append(" - (");
295 				sb.append(sm.getOpponentName());
296 				sb.append(") ");
297 				sb.append(sm.getOpponentScore());
298 				return(sb.toString());
299 			}
300 		}
301 		return(null);
302 	}
303 
304 	/** Parse a saved match line from FIBS.
305 	 * Store the match in our local list and return it
306 	 * @param s The string
307 	 * @return The parsed SavedMatch
308 	 */
309 	public SavedMatch parseSavedMatch(String s) {
310 		try {
311 			String[] ss = s.split(" +");
312 			SavedMatch sm = new SavedMatch();
313 			if (ss[0].startsWith("**")) {
314 				sm.setOpponentName(ss[0].substring(2));
315 				sm.setMatchLength(Integer.parseInt(ss[1]));
316 				sm.setYourScore(Integer.parseInt(ss[2]));
317 				sm.setOpponentScore(Integer.parseInt(ss[4]));				
318 			} else if (ss[1].startsWith("*")){
319 				sm.setOpponentName(ss[1].substring(1));
320 				sm.setMatchLength(Integer.parseInt(ss[2]));
321 				sm.setYourScore(Integer.parseInt(ss[3]));
322 				sm.setOpponentScore(Integer.parseInt(ss[5]));
323 			} else {
324 				sm.setOpponentName(ss[1]);
325 				sm.setMatchLength(Integer.parseInt(ss[2]));
326 				sm.setYourScore(Integer.parseInt(ss[3]));
327 				sm.setOpponentScore(Integer.parseInt(ss[5]));
328 			}
329 			this.savedMatches.add(sm);
330 			return(sm);
331 		} catch (Exception ex) {
332 			throw new RuntimeException("Failed to parseSavedMatch '" + s + "'", ex);
333 		}
334 	}
335 
336 
337 	/** Remove a player from the savedMatches list.
338 	 * Call this after completing any match.
339 	 * @param playerName The name of the player you just finished a match with.
340 	 */
341 	public void removeSavedMatch(String playerName) {
342 		for (SavedMatch sm : savedMatches) {
343 			if (sm.getOpponentName().equals(playerName)) {
344 				savedMatches.remove(sm);
345 				break;
346 			}	
347 		}
348 	}
349 
350 	/** If MissManners issued a warning about a player, this is a tooltip string describing it.
351 	 * @param playerName The player to check for a MissManners warning.
352 	 * @return A tooltip String or null if no warning found
353 	 */
354 	public String	getMissMannersString(String playerName) {
355 		for (SavedMatch sm : missManners) {
356 			if (sm.getOpponentName().equals(playerName)) {
357 				StringBuffer sb = new StringBuffer();
358 				sb.append("MissManners warns: ");
359 				sb.append(playerName);
360 				sb.append(" has ");
361 				sb.append(sm.getMatchLength());
362 				sb.append(" saved games");
363 				return(sb.toString());
364 			}
365 		}
366 		return(null);
367 	}
368 
369 	/** Parse a MissManners warning line from FIBS.
370 	 * Store the warning in our local list and return it
371 	 * @param s The string
372 	 * @return The parsed SavedMatch
373 	 */
374 	public SavedMatch parseMissManners(String s) {
375 		try {
376 			String[] ss = s.split(" +");
377 			if (!ss[1].equals("MissManners"))
378 				return(null);
379 			SavedMatch sm = new SavedMatch();
380 			sm.setOpponentName(ss[4]);
381 			sm.setMatchLength(Integer.parseInt(ss[6]));
382 			this.missManners.add(sm);
383 			return(sm);
384 		} catch (Exception ex) {
385 			throw new RuntimeException("Failed to parseMissManners '" + s + "'", ex);
386 		}
387 	}
388 	
389 	/** Parse the Own Info command from FIBS.
390 	 * @param s The Own Info line received from FIBS
391 	 * @see <a href="http://www.fibs.com/fibs_interface.html#clip_own_info" target="_top">FIBS Client Protocol Detailed Specification</a>
392 	 * <pre>
393 	 * 0 1    2        3         4          5        6    7    8        9      10         11     12         13    14     15     16      17    18        19     20     21
394 	 * 2 name allowpip autoboard autodouble automove away bell crawford double experience greedy moreboards moves notify rating ratings ready redoubles report silent timezone
395 	 * 2 myself 1 1 0 0 0 0 1 1 2396 0 1 0 1 3457.85 0 0 0 0 0 Australia/Melbourne
396 	 * </pre>
397 	 */
398 	public void parseOwnInfo(String s) {
399 		String[] t = s.split(" ");
400 		this.name		= t[1];
401 		this.allowPip	= Integer.parseInt(t[2]) == 1 ? true : false;
402 		this.autoBoard	= Integer.parseInt(t[3]) == 1 ? true : false;
403 		this.autoDouble	= Integer.parseInt(t[4]) == 1 ? true : false;
404 		this.autoMove	= Integer.parseInt(t[5]) == 1 ? true : false;
405 		this.away		= Integer.parseInt(t[6]) == 1 ? true : false;
406 		this.bell		= Integer.parseInt(t[7]) == 1 ? true : false;
407 		this.crawford	= Integer.parseInt(t[8]) == 1 ? true : false;
408 		this.askDouble	= Integer.parseInt(t[9]) == 1 ? true : false;
409 		this.experience = Integer.parseInt(t[10]);
410 		this.greedy		= Integer.parseInt(t[11]) == 1 ? true : false;
411 		this.moreBoards	= Integer.parseInt(t[12]) == 1 ? true : false;
412 		this.moves		= Integer.parseInt(t[13]) == 1 ? true : false;
413 		this.notify		= Integer.parseInt(t[14]) == 1 ? true : false;
414 		this.rating		= Double.parseDouble(t[15]);
415 		this.ratings	= Integer.parseInt(t[16]) == 1 ? true : false;
416 		this.ready		= Integer.parseInt(t[17]) == 1 ? true : false;
417 		this.redoubles	= t[18].equals("unlimited") ? -1 : Integer.parseInt(t[19]);
418 		this.report		= Integer.parseInt(t[19]) == 1 ? true : false;
419 		this.silent		= Integer.parseInt(t[20]) == 1 ? true : false;
420 		this.timezone	= t[21];
421 	}
422 
423 }