View Javadoc

1   /*
2    *   Firemox 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  package net.sf.firemox.ui;
20  
21  import java.awt.BorderLayout;
22  import java.awt.Color;
23  import java.awt.Dimension;
24  import java.awt.FlowLayout;
25  import java.awt.Toolkit;
26  import java.awt.event.ActionEvent;
27  import java.awt.event.ActionListener;
28  import java.awt.event.InputEvent;
29  import java.awt.event.KeyEvent;
30  import java.awt.event.MouseListener;
31  import java.awt.event.WindowListener;
32  import java.io.File;
33  import java.util.Locale;
34  
35  import javax.swing.BoxLayout;
36  import javax.swing.ButtonGroup;
37  import javax.swing.ImageIcon;
38  import javax.swing.JButton;
39  import javax.swing.JCheckBoxMenuItem;
40  import javax.swing.JDialog;
41  import javax.swing.JFrame;
42  import javax.swing.JLabel;
43  import javax.swing.JMenu;
44  import javax.swing.JMenuBar;
45  import javax.swing.JMenuItem;
46  import javax.swing.JOptionPane;
47  import javax.swing.JPanel;
48  import javax.swing.JRadioButtonMenuItem;
49  import javax.swing.JScrollPane;
50  import javax.swing.JSeparator;
51  import javax.swing.JTabbedPane;
52  import javax.swing.JTextField;
53  import javax.swing.JToggleButton;
54  import javax.swing.KeyStroke;
55  import javax.swing.ScrollPaneConstants;
56  import javax.swing.SwingConstants;
57  import javax.swing.Timer;
58  import javax.swing.ToolTipManager;
59  
60  import net.sf.firemox.AbstractMainForm;
61  import net.sf.firemox.Magic;
62  import net.sf.firemox.clickable.action.ChosenCostPanel;
63  import net.sf.firemox.clickable.mana.Mana;
64  import net.sf.firemox.clickable.target.TargetFactory;
65  import net.sf.firemox.clickable.target.card.CardFactory;
66  import net.sf.firemox.clickable.target.player.Player;
67  import net.sf.firemox.stack.EventManager;
68  import net.sf.firemox.token.IdConst;
69  import net.sf.firemox.tools.Configuration;
70  import net.sf.firemox.tools.MToolKit;
71  import net.sf.firemox.tools.Picture;
72  import net.sf.firemox.tools.TimerTarget;
73  import net.sf.firemox.tools.WebBrowser;
74  import net.sf.firemox.ui.component.CardPropertiesPanel;
75  import net.sf.firemox.ui.component.ChatArea;
76  import net.sf.firemox.ui.component.EditorPane;
77  import net.sf.firemox.ui.component.LogArea;
78  import net.sf.firemox.ui.component.MessageButton;
79  import net.sf.firemox.ui.component.SplashScreen;
80  import net.sf.firemox.ui.component.TableTop;
81  import net.sf.firemox.ui.i18n.Language;
82  import net.sf.firemox.ui.i18n.LanguageManager;
83  import net.sf.firemox.ui.layout.BorderLayout2;
84  import net.sf.firemox.zone.PopupManager;
85  import net.sf.firemox.zone.ZoneManager;
86  
87  /***
88   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
89   * @since 0.54.17
90   */
91  public abstract class MagicUIComponents extends AbstractMainForm implements
92  		MUIManager, ActionListener, MouseListener, WindowListener {
93  
94  	/***
95  	 * The timer panel.
96  	 */
97  	private TimerGlassPane timerPanel;
98  
99  	/***
100 	 * The timer target of Firemox
101 	 */
102 	public static TimerTarget targetTimer;
103 
104 	/***
105 	 * The timer of Firemox
106 	 */
107 	public static Timer timer;
108 
109 	/***
110 	 * Set the glass pane of the main form.
111 	 */
112 	public void updateTimerPanel() {
113 		setGlassPane(timerPanel);
114 	}
115 
116 	/***
117 	 * 
118 	 */
119 	public MagicUIComponents() {
120 		super("Firemox");
121 		magicForm = (Magic) this;
122 
123 		// Set the non-maximized size
124 		Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
125 		getRootPane().setPreferredSize(
126 				new Dimension(screenDim.width - 100, screenDim.height - 100));
127 		getRootPane().setMinimumSize(getRootPane().getPreferredSize());
128 		setUndecorated(frameDecorated);
129 		addWindowListener(this);
130 		timerPanel = new TimerGlassPane();
131 		timerPanel.setVisible(false);
132 		targetTimer = new TimerTarget(timerPanel);
133 		timer = new Timer(1000, targetTimer);
134 		updateTimerPanel();
135 	}
136 
137 	/***
138 	 * This method is called from within the constructor to initialize the form.
139 	 * WARNING: Do NOT modify this code. The content of this method is always
140 	 * regenerated by the Form Editor.
141 	 */
142 	protected void initComponents() {
143 		try {
144 			setIconImage(Picture.loadImage(IdConst.IMAGES_DIR + "mp.gif"));
145 		} catch (Exception e) {
146 			// IGNORING
147 		}
148 		MToolKit.tbsName = Configuration.getString("lastTBS", IdConst.TBS_DEFAULT);
149 		moreThemeMenu = new JMenuItem(LanguageManager.getString("morethemes"));
150 
151 		// Player status
152 		waitingLabel = new JLabel();
153 		waitingLabel.setHorizontalAlignment(SwingConstants.RIGHT);
154 
155 		turnsLbl = new JLabel();
156 		turnsLbl.setHorizontalTextPosition(SwingConstants.LEFT);
157 		turnsLbl.setMaximumSize(new Dimension(70, 16));
158 		turnsLbl.setPreferredSize(new Dimension(70, 16));
159 
160 		final JPanel infoPanel = new JPanel();
161 		infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.X_AXIS));
162 		infoPanel.setMaximumSize(new Dimension(2200, 20));
163 		infoPanel.add(turnsLbl);
164 
165 		backgroundBtn = new MessageButton(UIHelper.getIcon("smlquestion1.gif"),
166 				UIHelper.getIcon("smlquestion2.gif"));
167 		backgroundBtn.setVisible(false);
168 
169 		moreInfoLbl = new JLabel();
170 		moreInfoLbl.setHorizontalTextPosition(SwingConstants.RIGHT);
171 		moreInfoLbl.setMaximumSize(new Dimension(2200, 16));
172 		moreInfoLbl.setForeground(Color.BLUE);
173 		infoPanel.add(moreInfoLbl);
174 
175 		playerTabbedPanel = new JTabbedPane(SwingConstants.BOTTOM,
176 				JTabbedPane.SCROLL_TAB_LAYOUT);
177 
178 		// the card's "more info" tabbed panel containing the preview panel
179 		JTabbedPane previewTabbedPanel = null;
180 		previewPanel = new JPanel(new FlowLayout(0, 0, 0));
181 		previewPanel.setBackground(Color.black);
182 		chosenCostPanel = new ChosenCostPanel();
183 		databasePanel = new CardPropertiesPanel();
184 		if (speparateAvatar) {
185 			previewTabbedPanel = new JTabbedPane(SwingConstants.BOTTOM,
186 					JTabbedPane.SCROLL_TAB_LAYOUT);
187 			previewTabbedPanel.add(previewPanel, UIHelper.getIcon("zoom.gif"));
188 			previewTabbedPanel.add(chosenCostPanel, UIHelper
189 					.getIcon("chosenaction.gif"));
190 			previewTabbedPanel.add(databasePanel, UIHelper
191 					.getIcon("databasecard.gif"));
192 			previewTabbedPanel.setToolTipTextAt(previewTabbedPanel
193 					.indexOfComponent(previewPanel), "<html>"
194 					+ LanguageManager.getString("zoom.tooltip"));
195 			previewTabbedPanel.setToolTipTextAt(previewTabbedPanel
196 					.indexOfComponent(chosenCostPanel), "<html>"
197 					+ LanguageManager.getString("chosen.tooltip"));
198 			previewTabbedPanel.setToolTipTextAt(previewTabbedPanel
199 					.indexOfComponent(databasePanel), "<html>"
200 					+ LanguageManager.getString("database.tooltip"));
201 		} else {
202 			playerTabbedPanel.add(previewPanel, UIHelper.getIcon("zoom.gif"));
203 			playerTabbedPanel.add(chosenCostPanel, UIHelper
204 					.getIcon("chosenaction.gif"));
205 			playerTabbedPanel.setToolTipTextAt(playerTabbedPanel
206 					.indexOfComponent(previewPanel), "<html>"
207 					+ LanguageManager.getString("zoom.tooltip"));
208 			playerTabbedPanel.setToolTipTextAt(playerTabbedPanel
209 					.indexOfComponent(chosenCostPanel), "<html>"
210 					+ LanguageManager.getString("chosen.tooltip"));
211 			playerTabbedPanel
212 					.add(databasePanel, UIHelper.getIcon("databasecard.gif"));
213 			playerTabbedPanel.setToolTipTextAt(playerTabbedPanel
214 					.indexOfComponent(databasePanel), "<html>"
215 					+ LanguageManager.getString("database.tooltip"));
216 		}
217 
218 		// the chat
219 		chatPanel = new JPanel(new BorderLayout());
220 
221 		// the chat options
222 		final JPanel chatOptions = new JPanel();
223 		chatHistoryText = new ChatArea(new FlowLayout(FlowLayout.LEFT, 2, 0));
224 		final JButton clearChatButton = new JButton(UIHelper.getIcon("clear.gif"));
225 		clearChatButton.setActionCommand("clear");
226 		clearChatButton.addActionListener(chatHistoryText);
227 		clearChatButton.setPreferredSize(new Dimension(18, 18));
228 		clearChatButton.setFocusPainted(false);
229 		chatOptions.add(clearChatButton);
230 		final JToggleButton chatTimeButton = new JToggleButton(UIHelper
231 				.getIcon("time.gif"), Configuration.getBoolean("chatdisptime", false));
232 		chatTimeButton.setActionCommand("disptime");
233 		chatTimeButton.addActionListener(chatHistoryText);
234 		chatTimeButton.setPreferredSize(new Dimension(18, 18));
235 		chatTimeButton.setFocusPainted(false);
236 		chatOptions.add(chatTimeButton);
237 		final JToggleButton chatLockButton = new JToggleButton(UIHelper
238 				.getIcon("lock.gif"), Configuration.getBoolean("chatlocked", false));
239 		chatLockButton.setActionCommand("lock");
240 		chatLockButton.addActionListener(chatHistoryText);
241 		chatLockButton.setFocusPainted(false);
242 		chatLockButton.setPreferredSize(new Dimension(18, 18));
243 		chatOptions.add(chatLockButton);
244 		chatOptions.setMaximumSize(new Dimension(2000, 18));
245 		chatOptions.add(chatLockButton);
246 		chatPanel.add(chatOptions, BorderLayout.NORTH);
247 
248 		// the chat history
249 		final JScrollPane chatSPanel = new JScrollPane();
250 		chatHistoryText.setLocked(chatLockButton.isSelected());
251 		chatHistoryText.setDispTime(chatTimeButton.isSelected());
252 		chatSPanel
253 				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
254 		chatSPanel
255 				.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
256 		chatSPanel.setAutoscrolls(true);
257 		MToolKit.addOverlay(chatSPanel);
258 		chatSPanel.setViewportView(chatHistoryText);
259 		chatPanel.add(chatSPanel, BorderLayout.CENTER);
260 
261 		// the text filed
262 		sendTxt = new JTextField();
263 		final JPanel messagePanel = new JPanel(new BorderLayout());
264 		messagePanel.setMaximumSize(new Dimension(200, 18));
265 		messagePanel.add(sendTxt, BorderLayout.CENTER);
266 		sendButton = new JButton(UIHelper.getIcon("ok.gif"));
267 		sendButton.setBorderPainted(false);
268 		sendButton.setFocusPainted(false);
269 		sendButton.setPreferredSize(new Dimension(18, 18));
270 		sendButton.addActionListener(this);
271 		messagePanel.add(sendButton, BorderLayout.EAST);
272 		chatPanel.add(messagePanel, BorderLayout.SOUTH);
273 
274 		playerTabbedPanel.add(chatPanel, UIHelper.getIcon("chat-old.gif"));
275 		playerTabbedPanel.setToolTipTextAt(playerTabbedPanel
276 				.indexOfComponent(chatPanel), "<html>"
277 				+ LanguageManager.getString("chat.tooltip"));
278 
279 		// the game log panel : a JTextArea
280 		final JPanel logPanel = new JPanel(new BorderLayout());
281 
282 		// the log options
283 		final JPanel logOptions = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0));
284 		logListing = new LogArea();
285 		final JButton clearButton = new JButton(UIHelper.getIcon("clear.gif"));
286 		clearButton.setActionCommand("clear");
287 		clearButton.addActionListener(logListing);
288 		clearButton.setPreferredSize(new Dimension(18, 18));
289 		clearButton.setFocusPainted(false);
290 		logOptions.add(clearButton);
291 		final JToggleButton timeButton = new JToggleButton(UIHelper
292 				.getIcon("time.gif"), Configuration.getBoolean("logdisptime", false));
293 		timeButton.setActionCommand("disptime");
294 		timeButton.addActionListener(logListing);
295 		timeButton.setPreferredSize(new Dimension(18, 18));
296 		timeButton.setFocusPainted(false);
297 		logOptions.add(timeButton);
298 		final JToggleButton lockButton = new JToggleButton(UIHelper
299 				.getIcon("lock.gif"), Configuration.getBoolean("loglocked", false));
300 		lockButton.setActionCommand("lock");
301 		lockButton.addActionListener(logListing);
302 		lockButton.setPreferredSize(new Dimension(18, 18));
303 		lockButton.setFocusPainted(false);
304 		logOptions.add(lockButton);
305 		logPanel.add(logOptions, BorderLayout.NORTH);
306 
307 		// the log history
308 		final JScrollPane logSPanel = new JScrollPane(
309 				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
310 				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
311 		logListing.setLocked(lockButton.isSelected());
312 		logListing.setDispTime(timeButton.isSelected());
313 
314 		logOptions.setMaximumSize(new Dimension(2000, 18));
315 		logSPanel.setAutoscrolls(true);
316 		MToolKit.addOverlay(logSPanel);
317 		logSPanel.setViewportView(logListing);
318 		logPanel.add(logSPanel);
319 
320 		playerTabbedPanel.add(logPanel, UIHelper.getIcon("menu_tools_log.gif"));
321 		playerTabbedPanel.setToolTipTextAt(playerTabbedPanel
322 				.indexOfComponent(logPanel), "<html>"
323 				+ LanguageManager.getString("log.tooltip"));
324 
325 		// Main menubar
326 		JMenuBar magicMenu = new JMenuBar();
327 		JMenu gameMenu = UIHelper.buildMenu("menu_game", 'g');
328 		JMenu newGameMenu = UIHelper.buildMenu("menu_game_new", 'n');
329 
330 		// "Join" menu Item
331 		JMenuItem joinMenu = UIHelper.buildMenu("menu_game_new_client", 'j', this);
332 		joinMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
333 		newGameMenu.add(joinMenu);
334 
335 		// "Create" menu item
336 		JMenuItem createMenu = UIHelper
337 				.buildMenu("menu_game_new_server", 'c', this);
338 		createMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2,
339 				InputEvent.SHIFT_MASK));
340 		newGameMenu.add(createMenu);
341 
342 		gameMenu.add(newGameMenu);
343 
344 		// "Decline" button
345 		skipButton = UIHelper.buildButton("menu_game_skip", this);
346 		skipButton.setPreferredSize(new Dimension(Player.PLAYER_SIZE_HEIGHT,
347 				Player.PLAYER_SIZE_HEIGHT));
348 
349 		// "Decline" menu item
350 		skipMenu = UIHelper.buildMenu("menu_game_skip", 's', this);
351 		skipMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
352 				InputEvent.SHIFT_MASK));
353 		gameMenu.add(skipMenu);
354 
355 		gameMenu.add(UIHelper.buildMenu("menu_game_proposedraw", this));
356 		gameMenu.add(UIHelper.buildMenu("menu_game_disconnect", this));
357 		gameMenu.add(UIHelper.buildMenu("menu_game_proxy", this));
358 		gameMenu.add(new JSeparator());
359 
360 		// "Exit" menu item
361 		final JMenuItem exitMenu = UIHelper.buildMenu("menu_game_exit", 'q', this);
362 		exitMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
363 				InputEvent.ALT_MASK));
364 		gameMenu.add(exitMenu);
365 		magicMenu.add(gameMenu);
366 
367 		optionMenu = UIHelper.buildMenu("menu_options", 'o');
368 		final JMenu lookNFeelMenu = UIHelper.buildMenu("menu_lf");
369 
370 		// "Reverse opponent arts" option
371 		reverseArtCheck = new JCheckBoxMenuItem(LanguageManager
372 				.getString("reverseart"),
373 				Configuration.getBoolean("reverseArt", true) ? UIHelper
374 						.getIcon("reverse.gif") : UIHelper.getIcon("reverseoff.gif"),
375 				Configuration.getBoolean("reverseArt", true));
376 		reverseArtCheck.setToolTipText("<html>"
377 				+ LanguageManager.getString("reverseart.tooltip"));
378 		reverseSideCheck = new JCheckBoxMenuItem(LanguageManager
379 				.getString("reverseside"), Configuration.getBoolean("reverseSide",
380 				false) ? UIHelper.getIcon("reverseside.gif") : UIHelper
381 				.getIcon("reversesideoff.gif"), Configuration.getBoolean("reverseSide",
382 				false));
383 		reverseSideCheck.setToolTipText("<html>"
384 				+ LanguageManager.getString("reverseside.tooltip"));
385 		reverseArtCheck.addActionListener(this);
386 		reverseSideCheck.addActionListener(this);
387 		lookNFeelMenu.add(reverseArtCheck);
388 		lookNFeelMenu.add(reverseSideCheck);
389 
390 		// "Card border" option
391 		final String[] colors = { "black", "white", "gold", "auto" };
392 		final String currentColor = Configuration.getString("border-color",
393 				colors[3]);
394 		cardBorderMenu = new JMenu(LanguageManager.getString("border-color"));
395 		final ButtonGroup group4 = new ButtonGroup();
396 		boolean found = false;
397 		for (int i = 0; i < colors.length; i++) {
398 			String codeColor = "border-" + colors[i];
399 			JRadioButtonMenuItem colorItem = new JRadioButtonMenuItem(LanguageManager
400 					.getString(codeColor), UIHelper.getIcon(codeColor + ".gif"));
401 			colorItem.setActionCommand(codeColor);
402 			colorItem.addActionListener(this);
403 			if (!found && currentColor.equals(colors[i])) {
404 				colorItem.setSelected(true);
405 				found = true;
406 			}
407 			group4.add(colorItem);
408 			cardBorderMenu.add(colorItem);
409 		}
410 		if (!found) {
411 			((JRadioButtonMenuItem) cardBorderMenu.getComponent(0)).setSelected(true);
412 		}
413 		lookNFeelMenu.add(cardBorderMenu);
414 
415 		// Custom colors of Power/Toughness
416 		lookNFeelMenu.add(UIHelper.buildMenu("menu_lf_powerToughnessColor", this));
417 
418 		// Random angle option
419 		final JCheckBoxMenuItem randomAngleMenu = new JCheckBoxMenuItem(
420 				LanguageManager.getString("menu_lf_randomAngle"), UIHelper
421 						.getIcon("menu_lf_randomAngle.gif"), Configuration.getBoolean(
422 						"randomAngle", false));
423 		randomAngleMenu.addActionListener(this);
424 		lookNFeelMenu.add(randomAngleMenu);
425 
426 		// "Sound" option
427 		soundMenu = new JCheckBoxMenuItem(LanguageManager.getString("enablesound"),
428 				Configuration.getBoolean("sound", false) ? UIHelper
429 						.getIcon("sound.gif") : UIHelper.getIcon("soundoff.gif"),
430 				Configuration.getBoolean("sound", false));
431 		soundMenu.addActionListener(this);
432 		lookNFeelMenu.add(soundMenu);
433 
434 		// Tooltip delay
435 		// TODO factor this code with the one of Magic.class
436 		final ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
437 		final int delay = Configuration.getInt("initialdelay", 800);
438 		final int dismissDelay = Configuration.getInt("dismissdelay", 10000);
439 		if (delay == 0) {
440 			toolTipManager.setEnabled(false);
441 		} else {
442 			toolTipManager.setInitialDelay(delay);
443 		}
444 		toolTipManager.setDismissDelay(dismissDelay);
445 		initialdelayMenu = new JMenuItem(LanguageManager.getString("initialdelay")
446 				+ " : " + delay + " ms", UIHelper.getIcon("initialdelay.gif"));
447 		dismissdelayMenu = new JMenuItem(LanguageManager.getString("dismissdelay")
448 				+ " : " + dismissDelay + " ms", UIHelper.getIcon("initialdelay.gif"));
449 
450 		lookNFeelMenu.add(initialdelayMenu);
451 		lookNFeelMenu.add(dismissdelayMenu);
452 
453 		// "Themes" menu
454 		themeMenu = new JMenu(LanguageManager.getString("theme"));
455 		themeMenu.setIcon(UIHelper.getIcon("theme.gif"));
456 		themeMenu.add(new JSeparator());
457 		themeMenu.add(moreThemeMenu);
458 		lookNFeelMenu.add(themeMenu);
459 
460 		// "Language" menu
461 		languageMenu = new JMenu(LanguageManager.getString("menu_lf_language"));
462 
463 		// "Available languages" menu items
464 		final ButtonGroup group5 = new ButtonGroup();
465 		JRadioButtonMenuItem autoChck = null;
466 		for (Language language : LanguageManager.languages) {
467 			File flagFile = MToolKit.getFile(IdConst.FLAGS_DIR + language.getKey()
468 					+ IdConst.TYPE_PIC);
469 			boolean isDefault = language.getKey().equalsIgnoreCase(
470 					LanguageManager.getLanguage().getKey());
471 			JRadioButtonMenuItem itemChck = null;
472 			if (flagFile == null) {
473 				itemChck = new JRadioButtonMenuItem(language.getName(), isDefault);
474 			} else {
475 				itemChck = new JRadioButtonMenuItem(language.getName(), new ImageIcon(
476 						flagFile.getAbsolutePath()), isDefault);
477 
478 			}
479 			itemChck.addActionListener(langListener);
480 			itemChck.setActionCommand(language.getKey());
481 			if ("auto".equals(language.getKey())) {
482 				// Add the "auto" language detection
483 				itemChck.setToolTipText("<html><b>"
484 						+ LanguageManager.getString("menu_lf_language.auto.tooltip", Locale
485 								.getDefault().getLanguage()));
486 				autoChck = itemChck;
487 			} else {
488 				itemChck.setToolTipText("<html><b>"
489 						+ LanguageManager.getString("author") + "</b> : "
490 						+ language.getAuthor() + "<br><b>"
491 						+ LanguageManager.getString("contact") + "</b> : "
492 						+ language.getMoreInfo() + "<br><b>"
493 						+ LanguageManager.getString("version") + "</b> : "
494 						+ language.getVersion());
495 				languageMenu.add(itemChck);
496 			}
497 			group5.add(itemChck);
498 		}
499 		languageMenu.add(autoChck);
500 		languageMenu.add(new JSeparator());
501 
502 		// "More language" menu item
503 		languageMenu.add(UIHelper.buildMenu("menu_lf_language.more", langListener));
504 		lookNFeelMenu.add(languageMenu);
505 		magicMenu.add(lookNFeelMenu);
506 
507 		// "Auto mana" option
508 		autoManaMenu = new JCheckBoxMenuItem(LanguageManager.getString("automana"),
509 				UIHelper.getIcon("automana.gif"));
510 		autoManaMenu.setMnemonic('m');
511 		autoManaMenu.setToolTipText("<html>"
512 				+ LanguageManager.getString("automana.tooltip"));
513 		autoManaMenu.addActionListener(this);
514 		optionMenu.add(autoManaMenu);
515 
516 		// "Auto play" option
517 		autoPlayMenu = new JCheckBoxMenuItem(LanguageManager
518 				.getString("autoaction"), UIHelper.getIcon("fast.gif"));
519 		autoPlayMenu.setMnemonic('p');
520 		autoPlayMenu.setSelected(true);
521 		autoPlayMenu.setToolTipText("<html>"
522 				+ LanguageManager.getString("autoaction.tooltip") + "<br><br>"
523 				+ MagicUIComponents.HTML_ICON_TIP
524 				+ LanguageManager.getString("yourtbzTTtip2"));
525 		autoPlayMenu.addActionListener(this);
526 		optionMenu.add(autoPlayMenu);
527 
528 		JMenuItem settingsItem = UIHelper.buildMenu("menu_options_settings", this);
529 		settingsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0));
530 		optionMenu.add(settingsItem);
531 
532 		initAbstractMenu();
533 		magicMenu.add(optionMenu);
534 
535 		// "Tool" menu
536 		final JMenu toolMenu = UIHelper.buildMenu("tools", 't');
537 		toolMenu.add(UIHelper.buildMenu("menu_tools_log", this));
538 		toolMenu.add(UIHelper.buildMenu("menu_tools_bugreport", this));
539 		toolMenu.add(UIHelper.buildMenu("menu_tools_featurerequest", this));
540 		toolMenu.add(new JSeparator());
541 		toolMenu.add(UIHelper.buildMenu("menu_tools_jdb", 'd', this));
542 		JMenuItem cardBuilderMenu = UIHelper.buildMenu("menu_tools_jcb", 'c', this);
543 		cardBuilderMenu.setEnabled(false);
544 		toolMenu.add(cardBuilderMenu);
545 		magicMenu.add(toolMenu);
546 
547 		// "Help" menu
548 		JMenu questionMenu = UIHelper.buildMenu("menu_help", 'h');
549 		JMenuItem helpMenu = UIHelper.buildMenu("menu_help_help", 'h', this);
550 		helpMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
551 		questionMenu.add(helpMenu);
552 
553 		// "About M-P" menu item
554 		JMenuItem aboutMenu = UIHelper.buildMenu("menu_help_about", 'a', this);
555 		aboutMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,
556 				InputEvent.SHIFT_MASK));
557 		questionMenu.add(aboutMenu);
558 
559 		// "About TBS" menu item
560 		JMenuItem aboutMdbMenu = UIHelper.buildMenu("menu_help_about.tbs", 'm',
561 				null, this);
562 		aboutMdbMenu.setIcon(aboutMenu.getIcon());
563 		aboutMdbMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,
564 				InputEvent.ALT_MASK));
565 		questionMenu.add(aboutMdbMenu);
566 		questionMenu.add(new JSeparator());
567 
568 		// "Check for update" menu item
569 		final JMenuItem checkUpdateMenu = UIHelper.buildMenu(
570 				"menu_help_check-update", 'u', this);
571 		checkUpdateMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F10,
572 				InputEvent.SHIFT_MASK));
573 		questionMenu.add(checkUpdateMenu);
574 		questionMenu.add(UIHelper.buildMenu("menu_help_mailing", 'l', this));
575 		magicMenu.add(questionMenu);
576 
577 		// filler
578 		final JMenu disabledMenu = new JMenu();
579 		disabledMenu.setEnabled(false);
580 		disabledMenu
581 				.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
582 		magicMenu.add(disabledMenu);
583 
584 		// "Version" disabled menu item
585 		final JMenu menu = new JMenu(LanguageManager.getString("version")
586 				+ IdConst.VERSION);
587 		menu.setEnabled(false);
588 		// magicMenu.add(Box.createHorizontalGlue());
589 		magicMenu.add(menu);
590 		setJMenuBar(magicMenu);
591 
592 		// initialize the event manager and the spell stack
593 		EventManager.init();
594 		TargetFactory.initSettings();
595 		CardFactory.initSettings();
596 		PopupManager.init();
597 
598 		// The table top
599 		getContentPane().setLayout(new BorderLayout2());
600 		getContentPane().add(infoPanel, BorderLayout.SOUTH);
601 		TableTop.init(playerTabbedPanel, previewTabbedPanel);
602 		chatPanel.getRootPane().setDefaultButton(sendButton);
603 	}
604 
605 	/***
606 	 * An ActionListener that listens to the radio buttons menus
607 	 */
608 	protected static class UIListener implements ActionListener {
609 
610 		/***
611 		 * Creates a new instance of UIListener <br>
612 		 */
613 		public UIListener() {
614 			super();
615 		}
616 
617 		public void actionPerformed(ActionEvent e) {
618 			SkinLF.installLookAndFeel(e.getActionCommand(), e.getSource());
619 			ZoneManager.updateLookAndFeel();
620 		}
621 	}
622 
623 	/***
624 	 * Set the current UI as Metal
625 	 */
626 	protected static void setDefaultUI() {
627 		lookAndFeelName = MUIManager.LF_METAL_CLASSNAME;
628 		JFrame.setDefaultLookAndFeelDecorated(true);
629 		JDialog.setDefaultLookAndFeelDecorated(true);
630 		frameDecorated = true;
631 	}
632 
633 	/***
634 	 * Set the current TBS name. Calling this method cause the mana symbols to be
635 	 * downloaded if it's not yet done.
636 	 * 
637 	 * @param tbsName
638 	 *          the TBS to define as current.
639 	 */
640 	@Override
641 	public final void setMdb(String tbsName) {
642 		super.setMdb(tbsName);
643 		MagicUIComponents.previewPanel.removeAll();
644 		Mana.init(tbsName);
645 		Picture pic = CardFactory.initPreview();
646 		MagicUIComponents.previewPanel.add(pic);
647 		MagicUIComponents.previewPanel.setPreferredSize(new Dimension(pic
648 				.getPreferredSize().width + 2, pic.getPreferredSize().height + 2));
649 		chosenCostPanel.initialize();
650 	}
651 
652 	/***
653 	 * An ActionListener that listens to the radio buttons menus
654 	 */
655 	private final ActionListener langListener = new ActionListener() {
656 		/***
657 		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
658 		 */
659 		public void actionPerformed(ActionEvent e) {
660 			final String command = e.getActionCommand();
661 			if ("menu_lf_language.more".equals(command)) {
662 				// goto "more language" page
663 				try {
664 					WebBrowser
665 							.launchBrowser("http://sourceforge.net/project/showfiles.php?group_id="
666 									+ IdConst.PROJECT_ID + "&package_id=107882");
667 				} catch (Exception e1) {
668 					JOptionPane.showOptionDialog(magicForm, LanguageManager
669 							.getString("error"), LanguageManager.getString("web-pb"),
670 							JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE, UIHelper
671 									.getIcon("wiz_update_error.gif"), null, null);
672 				}
673 				return;
674 			}
675 			LanguageManager.setLanguage(e.getActionCommand());
676 			JOptionPane
677 					.showMessageDialog(MagicUIComponents.magicForm, LanguageManager
678 							.getString("menu_lf_language.restart"), LanguageManager
679 							.getString("restart"), JOptionPane.INFORMATION_MESSAGE);
680 		}
681 	};
682 
683 	/***
684 	 * Indicates the UI is loaded.
685 	 * 
686 	 * @return <code>true</code> if the UI is loaded.
687 	 */
688 	public static boolean isUILoaded() {
689 		return magicForm != null;
690 	}
691 
692 	/***
693 	 * all radioButtonMenu of each L&F available
694 	 */
695 	protected JRadioButtonMenuItem[] lookAndFeels;
696 
697 	/***
698 	 * Comment for <code>lookAndFeelName</code>
699 	 */
700 	public static String lookAndFeelName;
701 
702 	/***
703 	 * Comment for <code>magicForm</code>
704 	 */
705 	public static Magic magicForm;
706 
707 	/***
708 	 * Comment for <code>frameDecorated</code>
709 	 */
710 	public static boolean frameDecorated;
711 
712 	/***
713 	 * Comment for <code>autoManaMenu</code>
714 	 */
715 	public static JCheckBoxMenuItem autoManaMenu;
716 
717 	/***
718 	 * Comment for <code>autoPlayMenu</code>
719 	 */
720 	public static JCheckBoxMenuItem autoPlayMenu;
721 
722 	/***
723 	 * Comment for <code>chatPanel</code>
724 	 */
725 	public static JPanel chatPanel;
726 
727 	/***
728 	 * Comment for <code>historyText</code>
729 	 */
730 	public static EditorPane chatHistoryText;
731 
732 	/***
733 	 * Comment for <code>themeMenu</code>
734 	 */
735 	public static JMenu themeMenu;
736 
737 	/***
738 	 * Comment for <code>previewPanel</code>
739 	 */
740 	public static JPanel previewPanel;
741 
742 	/***
743 	 * Comment for <code>sendButton</code>
744 	 */
745 	public static JButton sendButton;
746 
747 	/***
748 	 * Comment for <code>sendTxt</code>
749 	 */
750 	public static JTextField sendTxt;
751 
752 	/***
753 	 * The button used to skip/decline to response to the current ability.
754 	 */
755 	public static JButton skipButton;
756 
757 	/***
758 	 * Comment for <code>skipMenu</code>
759 	 */
760 	public static JMenuItem skipMenu;
761 
762 	/***
763 	 * The label containing information about the active player
764 	 */
765 	public static JLabel waitingLabel;
766 
767 	/***
768 	 * 
769 	 */
770 	protected static JMenuItem reverseArtCheck;
771 
772 	/***
773 	 * 
774 	 */
775 	protected static JMenuItem reverseSideCheck;
776 
777 	/***
778 	 * 
779 	 */
780 	protected static JCheckBoxMenuItem soundMenu;
781 
782 	/***
783 	 * 
784 	 */
785 	protected static JMenuItem initialdelayMenu;
786 
787 	/***
788 	 * 
789 	 */
790 	protected static JMenuItem dismissdelayMenu;
791 
792 	private static JMenu languageMenu;
793 
794 	/***
795 	 * 
796 	 */
797 	protected static JMenuItem moreThemeMenu;
798 
799 	/***
800 	 * The main panel containing player stuffs.
801 	 */
802 	public static JTabbedPane playerTabbedPanel;
803 
804 	/***
805 	 * The logging editor pane.
806 	 */
807 	public static EditorPane logListing;
808 
809 	/***
810 	 * Is the main avatar picture is separated from the tabbed pane containing
811 	 * zones.
812 	 */
813 	public static boolean speparateAvatar = true;
814 
815 	/***
816 	 * The splash screen
817 	 */
818 	protected static SplashScreen splash;
819 
820 	/***
821 	 * 
822 	 */
823 	protected static JMenu cardBorderMenu;
824 
825 	/***
826 	 * The chosen cost panel
827 	 */
828 	public static ChosenCostPanel chosenCostPanel;
829 
830 	/***
831 	 * The tip picture.
832 	 */
833 	public static final String HTML_ICON_TIP = "<img src='file:///"
834 			+ MToolKit.getIconPath("tip.gif") + "'>&nbsp;";
835 
836 	/***
837 	 * The warning picture.
838 	 */
839 	public static final String HTML_ICON_WARNING = "<br><img src='file:///"
840 			+ MToolKit.getIconPath("warn.gif") + "'>&nbsp;";
841 
842 	/***
843 	 * The button restoring the current backgrounded wizard.
844 	 */
845 	public static MessageButton backgroundBtn;
846 
847 	/***
848 	 * Data base panel. Displayed in the <code>previewTabbedPanel</code>.
849 	 */
850 	public static CardPropertiesPanel databasePanel;
851 
852 	/***
853 	 * The turn label
854 	 */
855 	public JLabel turnsLbl;
856 
857 	/***
858 	 * The moreInfo label
859 	 */
860 	public JLabel moreInfoLbl;
861 }