View Javadoc

1   /*
2    *   Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   * 
19   */
20  package net.sf.magicproject;
21  
22  import java.awt.Color;
23  import java.awt.Font;
24  import java.awt.Frame;
25  import java.awt.Toolkit;
26  import java.awt.event.ActionEvent;
27  import java.awt.event.MouseEvent;
28  import java.awt.event.WindowEvent;
29  import java.io.BufferedReader;
30  import java.io.File;
31  import java.io.FileFilter;
32  import java.io.InputStream;
33  import java.io.InputStreamReader;
34  import java.net.URL;
35  import java.util.ArrayList;
36  import java.util.Collections;
37  import java.util.LinkedList;
38  import java.util.List;
39  
40  import javax.swing.AbstractButton;
41  import javax.swing.ButtonGroup;
42  import javax.swing.JColorChooser;
43  import javax.swing.JDialog;
44  import javax.swing.JFrame;
45  import javax.swing.JOptionPane;
46  import javax.swing.JRadioButtonMenuItem;
47  import javax.swing.LookAndFeel;
48  import javax.swing.SwingUtilities;
49  import javax.swing.ToolTipManager;
50  import javax.swing.UIManager;
51  import javax.swing.UIManager.LookAndFeelInfo;
52  
53  import net.sf.magicproject.action.PayMana;
54  import net.sf.magicproject.clickable.targetable.card.CardFactory;
55  import net.sf.magicproject.clickable.targetable.player.Player;
56  import net.sf.magicproject.database.DatabaseFactory;
57  import net.sf.magicproject.deckbuilder.Deck;
58  import net.sf.magicproject.deckbuilder.DeckReader;
59  import net.sf.magicproject.deckbuilder.MdbLoader;
60  import net.sf.magicproject.network.Client;
61  import net.sf.magicproject.network.ConnectionManager;
62  import net.sf.magicproject.network.IdMessages;
63  import net.sf.magicproject.network.Server;
64  import net.sf.magicproject.stack.EventManager;
65  import net.sf.magicproject.stack.StackManager;
66  import net.sf.magicproject.token.IdConst;
67  import net.sf.magicproject.token.MCommonVars;
68  import net.sf.magicproject.tools.Configuration;
69  import net.sf.magicproject.tools.JavaVersion;
70  import net.sf.magicproject.tools.Log;
71  import net.sf.magicproject.tools.MToolKit;
72  import net.sf.magicproject.tools.Pair;
73  import net.sf.magicproject.tools.WebBrowser;
74  import net.sf.magicproject.ui.MUIManager;
75  import net.sf.magicproject.ui.MagicUIComponents;
76  import net.sf.magicproject.ui.SkinLF;
77  import net.sf.magicproject.ui.UIHelper;
78  import net.sf.magicproject.ui.component.LoaderConsole;
79  import net.sf.magicproject.ui.component.ProxyConfiguration;
80  import net.sf.magicproject.ui.component.SplashScreen;
81  import net.sf.magicproject.ui.i18n.LanguageManager;
82  import net.sf.magicproject.ui.wizard.About;
83  import net.sf.magicproject.ui.wizard.AboutMdb;
84  import net.sf.magicproject.ui.wizard.Bug;
85  import net.sf.magicproject.ui.wizard.Feature;
86  import net.sf.magicproject.ui.wizard.InputNumber;
87  import net.sf.magicproject.ui.wizard.Settings;
88  import net.sf.magicproject.ui.wizard.Wizard;
89  import net.sf.magicproject.xml.Oracle2Xml;
90  import net.sf.magicproject.xml.XmlConfiguration;
91  import net.sf.magicproject.xml.XmlParser;
92  import net.sf.magicproject.xml.XmlParser.Node;
93  import net.sf.magicproject.zone.ZoneManager;
94  
95  import org.apache.commons.io.IOUtils;
96  import org.apache.commons.lang.ArrayUtils;
97  
98  import com.l2fprod.util.ZipResourceLoader;
99  
100 /***
101  * @author Fabrice Daugan
102  * @version 0.54
103  * @since 0.54 All listeners are no more implemented as inner class
104  */
105 public final class Magic extends MagicUIComponents {
106 
107 	/***
108 	 * Creates new form Magic
109 	 */
110 	private Magic() {
111 		super();
112 		initComponents();
113 
114 		// list all installed Look&Feel
115 		UIListener uiListener = new UIListener();
116 		UIManager.LookAndFeelInfo[] uimTMP = UIManager.getInstalledLookAndFeels();
117 		final List<Pair<String, String>> lfList = new ArrayList<Pair<String, String>>();
118 		for (LookAndFeelInfo lookAndFeel : uimTMP) {
119 			Pair<String, String> info = new Pair<String, String>(lookAndFeel
120 					.getName(), lookAndFeel.getClassName());
121 			if (!lfList.contains(info)) {
122 				lfList.add(info);
123 			}
124 		}
125 
126 		// list all SkinLF themes
127 		final File[] themes = MToolKit.getFile("lib").listFiles(new FileFilter() {
128 			public boolean accept(File f) {
129 				return f != null && f.getName().endsWith(".zip");
130 			}
131 		});
132 
133 		int maxIndex = Configuration.getConfiguration().getMaxIndex(
134 				"themes.skinlf.caches.cache");
135 		List<Pair<String, String>> knownThemes = new ArrayList<Pair<String, String>>();
136 		for (int i = 0; i < maxIndex + 1; i++) {
137 			String file = Configuration.getConfiguration().getString(
138 					"themes.skinlf.caches.cache(" + i + ").[@file]");
139 			int index = ArrayUtils.indexOf(themes, new File(file));
140 			if (index >= 0) {
141 				themes[index] = null;
142 				Pair<String, String> skin = new Pair<String, String>(Configuration
143 						.getConfiguration().getString(
144 								"themes.skinlf.caches.cache(" + i + ").[@name]"), file);
145 				knownThemes.add(skin);
146 				lfList.add(skin);
147 			}
148 		}
149 
150 		for (File theme : themes) {
151 			if (theme != null) {
152 				// a new theme --> will be cached
153 				try {
154 					final List<Node> properties = new XmlParser().parse(
155 							new ZipResourceLoader(theme.toURI().toURL())
156 									.getResourceAsStream("skinlf-themepack.xml")).getNodes(
157 							"property");
158 					PROPERTIES: for (int j = 0; j < properties.size(); j++) {
159 						if ("skin.name".equals(properties.get(j).getAttribute("name"))) {
160 							// skin name found
161 							String relativePath = MToolKit.getRelativePath(theme
162 									.getCanonicalPath());
163 							Pair<String, String> skin = new Pair<String, String>(properties
164 									.get(j).getAttribute("value"), "zip:" + relativePath);
165 							lfList.add(skin);
166 							knownThemes.add(new Pair<String, String>(properties.get(j)
167 									.getAttribute("value"), relativePath));
168 							break PROPERTIES;
169 						}
170 					}
171 				} catch (Exception e) {
172 					Log.error("Error in " + theme, e);
173 				}
174 			}
175 		}
176 
177 		Configuration.getConfiguration().clearProperty("themes.skinlf.caches");
178 		for (int index = 0; index < knownThemes.size(); index++) {
179 			Pair<String, String> skin = knownThemes.get(index);
180 			Configuration.getConfiguration().setProperty(
181 					"themes.skinlf.caches.cache(" + index + ").[@name]", skin.key);
182 			Configuration.getConfiguration().setProperty(
183 					"themes.skinlf.caches.cache(" + index + ").[@file]", skin.value);
184 		}
185 
186 		// create l&f menu items
187 		Collections.sort(lfList);
188 		lookAndFeels = new JRadioButtonMenuItem[lfList.size() + 1];
189 		ButtonGroup group5 = new ButtonGroup();
190 		for (int i = 0; i < lfList.size(); i++) {
191 			final String lfName = lfList.get(i).key;
192 			final String lfClassName = lfList.get(i).value;
193 			lookAndFeels[i] = new JRadioButtonMenuItem(lfName);
194 			if (lookAndFeelName.equalsIgnoreCase(lfClassName)) {
195 				// this the current l&f
196 				lookAndFeels[i].setSelected(true);
197 			}
198 			if (!SkinLF.isSkinLF(lfClassName)) {
199 				lookAndFeels[i]
200 						.setEnabled(MToolKit.isAvailableLookAndFeel(lfClassName));
201 			}
202 			group5.add(lookAndFeels[i]);
203 			lookAndFeels[i].setActionCommand(lfClassName);
204 			themeMenu.add(lookAndFeels[i], i);
205 			lookAndFeels[i].addActionListener(uiListener);
206 		}
207 		lfList.clear();
208 
209 		initialdelayMenu.addActionListener(this);
210 		dismissdelayMenu.addActionListener(this);
211 
212 		ConnectionManager.enableConnectingTools(false);
213 
214 		// read auto mana option
215 		MCommonVars.autoMana = Configuration.getBoolean("automana", true);
216 		autoManaMenu.setSelected(MCommonVars.autoMana);
217 
218 		// Force to init the TBS settings
219 		MToolKit.tbsName = null;
220 		setMdb(Configuration.getString("lastTBS", IdConst.TBS_DEFAULT));
221 
222 		// set the autoStack mode
223 		MCommonVars.autoStack = Configuration.getBoolean("autostack", false);
224 		autoPlayMenu.setSelected(MCommonVars.autoStack);
225 
226 		// read maximum displayed colored mana in context
227 		PayMana.thresholdColored = Configuration.getInt("threshold-colored", 6);
228 
229 		ZoneManager.updateLookAndFeel();
230 
231 		// pack this frame
232 		pack();
233 
234 		// Maximize this frame
235 		setExtendedState(Frame.MAXIMIZED_BOTH);
236 
237 		if (batchMode != -1) {
238 
239 			final String deckFile = Configuration.getString(Configuration
240 					.getString("decks.deck(0)"));
241 			try {
242 				Deck batchDeck = DeckReader.getDeck(this, deckFile);
243 				switch (batchMode) {
244 				case BATCH_SERVER:
245 					ConnectionManager.server = new Server(batchDeck, null);
246 					ConnectionManager.server.start();
247 					break;
248 				case BATCH_CLIENT:
249 					ConnectionManager.client = new Client(batchDeck, null);
250 					ConnectionManager.client.start();
251 					break;
252 				default:
253 				}
254 			} catch (Throwable e) {
255 				throw new RuntimeException("Error in batch mode : ", e);
256 			}
257 		}
258 	}
259 
260 	/***
261 	 * invoked when player declines to response to an event.
262 	 * 
263 	 * @see net.sf.magicproject.stack.ActionManager#manualSkip()
264 	 */
265 	public void manualSkip() {
266 		// do the righ action : cancel or skip?
267 		if (StackManager.idHandedPlayer == 0) {
268 			Player.unsetHandedPlayer();
269 			sendManualSkip();
270 			// abort this spell/ability
271 			StackManager.actionManager.manualSkip();
272 		}
273 	}
274 
275 	/***
276 	 * Send the "manual skipped" action to opponent
277 	 */
278 	public static void sendManualSkip() {
279 		// we inform opponent that we abort this cast or skip phase/event
280 		net.sf.magicproject.tools.Log.debug("      ...-> manual skip");
281 		ConnectionManager.sendToOpponent(IdMessages.MSG_SKIP);
282 	}
283 
284 	/***
285 	 * Exit the Application
286 	 * 
287 	 * @param evt
288 	 *          is ignored
289 	 */
290 	private void exitForm(WindowEvent evt) {
291 		try {
292 			ConnectionManager.closeConnexions();
293 		} catch (Throwable t) {
294 			// ignore error
295 		}
296 		saveSettings();
297 		System.exit(0);
298 	}
299 
300 	/***
301 	 * Save the settings
302 	 */
303 	public static void saveSettings() {
304 		// save part of LF_SETTINGS_FILE
305 		try {
306 			// save your preferred lookandfeel
307 			if (lookAndFeelName.toUpperCase().startsWith(
308 					"ZIP:" + MToolKit.getRelativePath().toUpperCase())) {
309 				Configuration.setProperty("preferred", "zip:"
310 						+ MToolKit.getFile(
311 								lookAndFeelName.substring("zip:".length()
312 										+ MToolKit.getRelativePath().length() + 1)).toString()
313 								.replace('//', '/'));
314 			} else {
315 				Configuration.setProperty("preferred", lookAndFeelName);
316 			}
317 
318 			// save backcolors and wallpapers
319 			ZoneManager.saveSettings();
320 
321 			Configuration.setProperty("language", LanguageManager.getLanguage()
322 					.getKey());
323 			Configuration.setProperty("automana", MCommonVars.autoMana);
324 			Configuration.setProperty("autostack", MCommonVars.autoStack);
325 			Configuration.setProperty("lastTBS", MToolKit.tbsName);
326 
327 			// write proxy configuration
328 			Configuration.setProperty("logdisptime", logListing.isDispTime());
329 			Configuration.setProperty("loglocked", logListing.isLocked());
330 			Configuration.setProperty("chatdisptime", chatHistoryText.isDispTime());
331 			Configuration.setProperty("chatlocked", chatHistoryText.isLocked());
332 			Configuration.setProperty("threshold-colored", PayMana.thresholdColored);
333 			Configuration.setProperty("border-color",
334 					(CardFactory.borderColor == Color.BLACK ? "black"
335 							: CardFactory.borderColor == Color.WHITE ? "white" : "gold"));
336 
337 			targetTimer.saveSettings();
338 			CardFactory.saveSettings();
339 			DatabaseFactory.saveCache();
340 			Configuration.getConfiguration().save();
341 		} catch (Exception e) {
342 			JOptionPane.showMessageDialog(magicForm, LanguageManager
343 					.getString("savelfpb")
344 					+ " : " + e.getMessage(), LanguageManager.getString("error"),
345 					JOptionPane.WARNING_MESSAGE);
346 		}
347 
348 		// save the tbs settings
349 		MdbLoader.saveTBSSettings();
350 	}
351 
352 	/***
353 	 * Is the batch mode identifant.
354 	 */
355 	public static int batchMode = -1;
356 
357 	/***
358 	 * The SERVER batch mode.
359 	 */
360 	public static final int BATCH_SERVER = 0;
361 
362 	/***
363 	 * The CLIENT batch mode.
364 	 */
365 	public static final int BATCH_CLIENT = 1;
366 
367 	/***
368 	 * @param args
369 	 *          the command line arguments
370 	 * @throws Exception
371 	 */
372 	public static void main(String[] args) throws Exception {
373 		Log.debug("MP v" + IdConst.VERSION + ", jre:"
374 				+ System.getProperty("java.runtime.version") + ", jvm:"
375 				+ System.getProperty("java.vm.version") + ",os:"
376 				+ System.getProperty("os.name") + ", res:"
377 				+ Toolkit.getDefaultToolkit().getScreenSize().width + "x"
378 				+ Toolkit.getDefaultToolkit().getScreenSize().height);
379 
380 		System.setProperty("swing.aatext", "true");
381 		System.setProperty("substancelaf.configFile", "substancelaf.properties");
382 		try {
383 			Log.init();
384 			if (args.length > 0) {
385 				final String[] args2 = new String[args.length - 1];
386 				System.arraycopy(args, 1, args2, 0, args.length - 1);
387 				if ("-rebuild".equals(args[0])) {
388 					XmlConfiguration.main(args2);
389 				} else if ("-oracle2xml".equals(args[0])) {
390 					Oracle2Xml.main(args2);
391 				} else if ("-batch".equals(args[0])) {
392 					if ("-server".equals(args[1])) {
393 						batchMode = BATCH_SERVER;
394 					} else if ("-client".equals(args[1])) {
395 						batchMode = BATCH_CLIENT;
396 					}
397 				} else {
398 					Log
399 							.error("Unknown options '"
400 									+ args
401 									+ "'\nUsage : java -jar starter.jar <options>, where options are :\n"
402 									+ "\t-rebuild [-full[O]] <tbs name>\n"
403 									+ "\t-oracle2xml <oracle file> <output directory>");
404 				}
405 				System.exit(0);
406 				return;
407 			}
408 			if (batchMode == -1 && !"Mac OS X".equals(System.getProperty("os.name"))) {
409 				splash = new SplashScreen(MToolKit.getIconPath("splash.jpg"), null,
410 						2000);
411 			}
412 
413 			// language settings
414 			LanguageManager.initLanguageManager(Configuration.getString("language",
415 					"auto"));
416 		} catch (Throwable t) {
417 			Log.error("START-ERROR : \n\t" + t.getMessage());
418 			System.exit(1);
419 			return;
420 		}
421 		Log.debug("MP Language : " + LanguageManager.getLanguage().getName());
422 		speparateAvatar = Toolkit.getDefaultToolkit().getScreenSize().height > 768;
423 
424 		// verify the java version, minimal is 1.5
425 		if (new JavaVersion().compareTo(new JavaVersion(IdConst.MINIMAL_JRE)) == -1) {
426 			Log.error(LanguageManager.getString("wrongjava") + IdConst.MINIMAL_JRE);
427 		}
428 
429 		// load look and feel settings
430 		lookAndFeelName = Configuration.getString("preferred",
431 				MUIManager.LF_SUBSTANCE_CLASSNAME);
432 		MToolKit.defaultFont = new Font("Arial", 0, 11);
433 		// try {
434 		// FileInputStream in= new FileInputStream("MAGIC.TTF");
435 		// MToolKit.defaultFont= Font.createFont(Font.TRUETYPE_FONT, in);
436 		// in.close();
437 		// MToolKit.defaultFont= MToolKit.defaultFont.deriveFont(Font.BOLD, 11);
438 		// }
439 		// catch (FileNotFoundException e) {
440 		// System.out.println("editorfont.ttf not found, using default.");
441 		// }
442 		// catch (Exception ex) {
443 		// ex.printStackTrace();
444 		// }
445 
446 		// Read available L&F
447 		final LinkedList<Pair<String, String>> lfList = new LinkedList<Pair<String, String>>();
448 		try {
449 			BufferedReader buffReader = new BufferedReader(new InputStreamReader(
450 					MToolKit.getResourceAsStream(IdConst.FILE_THEME_SETTINGS)));
451 			String line;
452 			while ((line = buffReader.readLine()) != null) {
453 				line = line.trim();
454 				if (!line.startsWith("#")) {
455 					final int index = line.indexOf(';');
456 					if (index != -1) {
457 						lfList.add(new Pair<String, String>(line.substring(0, index), line
458 								.substring(index + 1)));
459 					}
460 				}
461 			}
462 			IOUtils.closeQuietly(buffReader);
463 		} catch (Throwable e) {
464 			// no place for resolve this problem
465 			Log.debug("Error reading L&F properties : " + e.getMessage());
466 		}
467 		for (Pair<String, String> pair : lfList) {
468 			UIManager.installLookAndFeel(pair.key, pair.value);
469 		}
470 
471 		// install L&F
472 		if (SkinLF.isSkinLF(lookAndFeelName)) {
473 			// is a SkinLF Look & Feel
474 			/*
475 			 * Make sure we have a nice window decoration.
476 			 */
477 			SkinLF.installSkinLF(lookAndFeelName);
478 		} else {
479 			// is Metal Look & Feel
480 			if (!MToolKit.isAvailableLookAndFeel(lookAndFeelName)) {
481 				// preferred look&feel is not available
482 				JOptionPane.showMessageDialog(magicForm, LanguageManager.getString(
483 						"preferredlfpb", lookAndFeelName), LanguageManager
484 						.getString("error"), JOptionPane.INFORMATION_MESSAGE);
485 				setDefaultUI();
486 			}
487 
488 			// Intall the preferred
489 			LookAndFeel newLAF = MToolKit.geLookAndFeel(lookAndFeelName);
490 			frameDecorated = newLAF.getSupportsWindowDecorations();
491 
492 			/*
493 			 * Make sure we have a nice window decoration.
494 			 */
495 			JFrame.setDefaultLookAndFeelDecorated(frameDecorated);
496 			JDialog.setDefaultLookAndFeelDecorated(frameDecorated);
497 			UIManager.setLookAndFeel(MToolKit.geLookAndFeel(lookAndFeelName));
498 		}
499 
500 		// Start main thread
501 		try {
502 			new Magic();
503 			SwingUtilities.invokeLater(SkinLF.REFRESH_RUNNER);
504 		} catch (Throwable e) {
505 			Log.fatal("In main thread, occurred exception : ", e);
506 			ConnectionManager.closeConnexions();
507 			return;
508 		}
509 	}
510 
511 	/***
512 	 * init panel, life, poison, stack, menu
513 	 */
514 	public void initGame() {
515 		StackManager.reset();
516 		Player.unsetHandedPlayer();
517 		MdbLoader.loadTBSSettings();
518 		ZoneManager.updateReversed();
519 		Player.init();
520 		LoaderConsole.endTask();
521 		setVisible(true);
522 		backgroundBtn.stopButton();
523 		StackManager.noReplayToken.take();
524 		try {
525 			EventManager.start();
526 		} catch (Throwable t) {
527 			t.printStackTrace();
528 		} finally {
529 			StackManager.noReplayToken.release();
530 		}
531 	}
532 
533 	public void actionPerformed(ActionEvent e) {
534 		final String command = e.getActionCommand();
535 		final Object obj = e.getSource();
536 		if (obj == sendButton) {
537 			if (sendTxt.getText().length() != 0) {
538 				chat.sendMessage(sendTxt.getText());
539 				sendTxt.setText("");
540 			}
541 		} else if (command != null && command.startsWith("border-")) {
542 			for (int i = cardBorderMenu.getComponentCount(); i-- > 0;) {
543 				((JRadioButtonMenuItem) cardBorderMenu.getComponent(i))
544 						.setSelected(false);
545 			}
546 			((JRadioButtonMenuItem) obj).setSelected(true);
547 			CardFactory.updateColor(command.substring("border-".length()));
548 			CardFactory.updateAllCardsUI();
549 			magicForm.repaint();
550 		} else if ("menu_help_mailing".equals(command)) {
551 			try {
552 				WebBrowser
553 						.launchBrowser("http://lists.sourceforge.net/lists/listinfo/magic-project-user");
554 			} catch (Exception e1) {
555 				JOptionPane.showOptionDialog(this, LanguageManager.getString("error")
556 						+ " : " + e1.getMessage(), LanguageManager.getString("web-pb"),
557 						JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE, UIHelper
558 								.getIcon("wiz_update_error.gif"), null, null);
559 			}
560 		} else if ("menu_options_settings".equals(command)) {
561 			// Setting panel
562 			final Wizard settingsPanel = new Settings();
563 			settingsPanel.setVisible(true);
564 		} else if ("menu_help_check-update".equals(command)) {
565 			try {
566 				final URL mainPage = new URL(
567 						"http://sourceforge.net/project/showfiles.php?group_id=92519");
568 				final BufferedReader br = new BufferedReader(new InputStreamReader(
569 						(InputStream) mainPage.openConnection().getContent(), "iso-8859-1"));
570 				String line = null;
571 				while ((line = br.readLine()) != null) {
572 					if (line
573 							.indexOf("/project/showfiles.php?group_id=92519&amp;package_id=97891&amp;") != -1) {
574 						String version = line.substring(line.lastIndexOf("\">") + 2);
575 						version = version.substring(0, version.indexOf("<")).trim();
576 						if (IdConst.VERSION_NAME.equals(version)) {
577 							// up-to-date version
578 							JOptionPane.showMessageDialog(this, LanguageManager
579 									.getString("menu_help_check-update.lastversiony"),
580 									LanguageManager.getString("version"),
581 									JOptionPane.INFORMATION_MESSAGE);
582 						} else {
583 							// newer version
584 							if (JOptionPane.YES_OPTION == JOptionPane.showOptionDialog(this,
585 									LanguageManager.getString(
586 											"menu_help_check-update.lastversionn", version),
587 									LanguageManager.getString("version"),
588 									JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
589 									UIHelper.getIcon("wiz_update.gif"), null, null)) {
590 								try {
591 									WebBrowser
592 											.launchBrowser("http://sourceforge.net/project/showfiles.php?group_id=92519&package_id=97891");
593 								} catch (Exception e1) {
594 									JOptionPane.showOptionDialog(this, LanguageManager
595 											.getString("error")
596 											+ " : " + e1.getMessage(), LanguageManager
597 											.getString("web-pb"), JOptionPane.OK_OPTION,
598 											JOptionPane.INFORMATION_MESSAGE, UIHelper
599 													.getIcon("wiz_update_error.gif"), null, null);
600 								}
601 							}
602 
603 						}
604 						return;
605 					}
606 				}
607 			} catch (Throwable e2) {
608 				// ignore error
609 			}
610 			// could not determine the available version
611 			JOptionPane.showMessageDialog(this, LanguageManager
612 					.getString("menu_help_check-updatelastversionu"), LanguageManager
613 					.getString("version"), JOptionPane.INFORMATION_MESSAGE);
614 		} else if ("menu_game_new_client".equals(command)) {
615 			new net.sf.magicproject.ui.wizard.Client().setVisible(true);
616 		} else if ("menu_game_new_server".equals(command)) {
617 			new net.sf.magicproject.ui.wizard.Server().setVisible(true);
618 		} else if ("menu_tools_log".equals(command)) {
619 			new net.sf.magicproject.ui.wizard.Log().setVisible(true);
620 		} else if ("menu_tools_featurerequest".equals(command)) {
621 			new Feature().setVisible(true);
622 		} else if ("menu_tools_bugreport".equals(command)) {
623 			new Bug().setVisible(true);
624 		} else if ("menu_game_skip".equals(command)) {
625 			if (ConnectionManager.isConnected() && skipButton.isEnabled()
626 					&& StackManager.idHandedPlayer == 0) {
627 				StackManager.noReplayToken.take();
628 				try {
629 					manualSkip();
630 				} catch (Throwable t) {
631 					t.printStackTrace();
632 				} finally {
633 					StackManager.noReplayToken.release();
634 				}
635 			}
636 		} else if ("menu_game_disconnect".equals(command)) {
637 			ConnectionManager.closeConnexions();
638 		} else if ("menu_tools_jdb".equals(command)) {
639 			DeckBuilder.loadFromMagic();
640 		} else if ("menu_game_exit".equals(command)) {
641 			exitForm(null);
642 		} else if (obj == autoManaMenu) {
643 			/*
644 			 * invoked you click directly on the "auto-mana option" of the menu
645 			 * "options". The opponent has to know that we are in "auto colorless mana
646 			 * use", since player will no longer click on the mana icon to define
647 			 * which colored mana active player has used as coloreless mana, then the
648 			 * opponent have not to wait for active player choice, but apply the sama
649 			 * algorythme calculating which colored manas are used as coloress manas.
650 			 * This information is not sent immediatly, but will be sent with the next
651 			 * action of active player.
652 			 */
653 			MCommonVars.autoMana = autoManaMenu.isSelected();
654 		} else if (obj == autoPlayMenu) {
655 			/*
656 			 * invoked you click directly on the "auto-play option" of the menu
657 			 * "options".
658 			 */
659 			MCommonVars.autoStack = autoPlayMenu.isSelected();
660 		} else if ("menu_tools_jcb".equals(command)) {
661 			// TODO cardBuilderMenu -> not yet implemented
662 			Log.info("cardBuilderMenu -> not yet implemented");
663 		} else if ("menu_game_proxy".equals(command)) {
664 			new ProxyConfiguration().setVisible(true);
665 		} else if ("menu_help_help".equals(command)) {
666 			/*
667 			 * Invoked you click directly on youLabel. Opponent will receive this
668 			 * information.
669 			 */
670 			try {
671 				WebBrowser
672 						.launchBrowser("http://prdownloads.sourceforge.net/magic-project/7e_rulebook_EN.pdf?download");
673 			} catch (Exception e1) {
674 				JOptionPane.showOptionDialog(this, LanguageManager.getString("error")
675 						+ " : " + e1.getMessage(), LanguageManager.getString("web-pb"),
676 						JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE, UIHelper
677 								.getIcon("wiz_update_error.gif"), null, null);
678 			}
679 		} else if ("menu_help_about".equals(command)) {
680 			new About(this).setVisible(true);
681 		} else if ("menu_help_about.tbs".equals(command)) {
682 			new AboutMdb(this).setVisible(true);
683 		} else if (obj == reverseArtCheck || obj == reverseSideCheck) {
684 			Configuration.setProperty("reverseArt", reverseArtCheck.isSelected());
685 			Configuration.setProperty("reverseSide", reverseSideCheck.isSelected());
686 			ZoneManager.updateReversed();
687 			StackManager.PLAYERS[1].updateReversed();
688 			repaint();
689 			SwingUtilities.invokeLater(SkinLF.REFRESH_RUNNER);
690 		} else if (obj == soundMenu) {
691 			Configuration.setProperty("sound", soundMenu.isSelected());
692 			soundMenu.setIcon(soundMenu.isSelected() ? UIHelper.getIcon("sound.gif")
693 					: UIHelper.getIcon("soundoff.gif"));
694 		} else if ("menu_lf_randomAngle".equals(command)) {
695 			Configuration.setProperty("randomAngle", ((AbstractButton) e.getSource())
696 					.isSelected());
697 			CardFactory.updateAllCardsUI();
698 		} else if ("menu_lf_powerToughnessColor".equals(command)) {
699 			final Color powerToughnessColor = JColorChooser.showDialog(this,
700 					LanguageManager.getString("menu_lf_powerToughnessColor"),
701 					CardFactory.powerToughnessColor);
702 			if (powerToughnessColor != null) {
703 				Configuration.setProperty("powerToughnessColor", powerToughnessColor
704 						.getRGB());
705 				CardFactory.updateColor(null);
706 				repaint();
707 			}
708 		} else if (obj == initialdelayMenu) {
709 			// TODO factor this code with the one of Magic.class
710 			final ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
711 			new InputNumber(LanguageManager.getString("initialdelay"),
712 					LanguageManager.getString("initialdelay.tooltip"), 0,
713 					Integer.MAX_VALUE, toolTipManager.getInitialDelay()).setVisible(true);
714 			if (Wizard.optionAnswer == JOptionPane.YES_OPTION) {
715 				toolTipManager.setEnabled(Wizard.indexAnswer != 0);
716 				toolTipManager.setInitialDelay(Wizard.indexAnswer);
717 				initialdelayMenu.setText(LanguageManager.getString("initialdelay")
718 						+ (toolTipManager.isEnabled() ? " : " + Wizard.indexAnswer + " ms"
719 								: "(disabled)"));
720 				Configuration.setProperty("initialdelay", Wizard.indexAnswer);
721 			}
722 		} else if (obj == dismissdelayMenu) {
723 			// TODO factor this code with the one of Magic.class
724 			final ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
725 			new InputNumber(LanguageManager.getString("dismissdelay"),
726 					LanguageManager.getString("dismissdelay.tooltip"), 0,
727 					Integer.MAX_VALUE, toolTipManager.getDismissDelay()).setVisible(true);
728 			if (Wizard.optionAnswer == JOptionPane.YES_OPTION) {
729 				toolTipManager.setDismissDelay(Wizard.indexAnswer);
730 				Configuration.setProperty("dismissdelay", Wizard.indexAnswer);
731 				dismissdelayMenu.setText(LanguageManager.getString("dismissdelay")
732 						+ Wizard.indexAnswer + " ms");
733 			}
734 		}
735 
736 	}
737 
738 	public void mouseClicked(MouseEvent e) {
739 		Object obj = e.getSource();
740 		if (obj == skipButton) {
741 			/***
742 			 * invoked by a click directly on the "skip/cancel" of the label".
743 			 * 
744 			 * @param evt
745 			 *          mouse event
746 			 * @see MEventManager#raiseEvent(int,boolean)
747 			 * @see MEventManager#getNextStop()
748 			 * @see MPhase#breakpoint
749 			 * @see MPhase#skipAll
750 			 * @see Magic#manuaSkip()
751 			 */
752 			// only if enabled and left mouse button pressed
753 			StackManager.noReplayToken.take();
754 			try {
755 				if (ConnectionManager.isConnected() && skipButton.isEnabled()
756 						&& e.getButton() == MouseEvent.BUTTON1) {
757 					manualSkip();
758 				}
759 			} catch (Throwable t) {
760 				t.printStackTrace();
761 			} finally {
762 				StackManager.noReplayToken.release();
763 			}
764 		}
765 	}
766 
767 	@Override
768 	public void windowClosing(WindowEvent e) {
769 		Object obj = e.getSource();
770 		if (obj == this) {
771 			exitForm(e);
772 		}
773 	}
774 
775 }