package games.strategy.triplea.ui.menubar;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import games.strategy.engine.data.GameData;
import games.strategy.engine.data.properties.PropertiesUI;
import games.strategy.engine.framework.ClientGame;
import games.strategy.engine.framework.IGame;
import games.strategy.engine.random.IRandomStats;
import games.strategy.engine.random.RandomStatsDetails;
import games.strategy.sound.SoundOptions;
import games.strategy.triplea.oddsCalculator.ta.OddsCalculatorDialog;
import games.strategy.triplea.settings.SettingsWindow;
import games.strategy.triplea.ui.IUIContext;
import games.strategy.triplea.ui.PoliticalStateOverview;
import games.strategy.triplea.ui.TripleAFrame;
import games.strategy.triplea.ui.VerifiedRandomNumbersDialog;
import games.strategy.ui.IntTextField;
import games.strategy.ui.SwingAction;
import games.strategy.ui.SwingComponents;
public class GameMenu {
private final TripleAFrame frame;
private final IUIContext iuiContext;
private final GameData gameData;
private final IGame game;
public GameMenu(final TripleAMenuBar menuBar, final TripleAFrame frame) {
this.frame = frame;
game = frame.getGame();
gameData = frame.getGame().getData();
iuiContext = frame.getUIContext();
menuBar.add(createGameMenu());
}
private JMenu createGameMenu() {
final JMenu menuGame = SwingComponents.newJMenu("Game", SwingComponents.KeyboardCode.G);
addEditMode(menuGame);
menuGame.addSeparator();
menuGame.add(SwingAction.of("Engine Settings", e -> SettingsWindow.showWindow()));
SoundOptions.addGlobalSoundSwitchMenu(menuGame);
SoundOptions.addToMenu(menuGame);
menuGame.addSeparator();
menuGame.add(frame.getShowGameAction()).setMnemonic(KeyEvent.VK_G);
menuGame.add(frame.getShowHistoryAction()).setMnemonic(KeyEvent.VK_H);
menuGame.add(frame.getShowMapOnlyAction()).setMnemonic(KeyEvent.VK_M);
menuGame.addSeparator();
addGameOptionsMenu(menuGame);
addShowVerifiedDice(menuGame);
addPoliticsMenu(menuGame);
addNotificationSettings(menuGame);
addShowDiceStats(menuGame);
addRollDice(menuGame);
addBattleCalculatorMenu(menuGame);
return menuGame;
}
private void addEditMode(final JMenu parentMenu) {
final JCheckBoxMenuItem editMode = new JCheckBoxMenuItem("Enable Edit Mode");
editMode.setModel(frame.getEditModeButtonModel());
parentMenu.add(editMode).setMnemonic(KeyEvent.VK_E);
}
private void addShowVerifiedDice(final JMenu parentMenu) {
final Action showVerifiedDice = SwingAction.of("Show Verified Dice",
e -> new VerifiedRandomNumbersDialog(frame.getRootPane()).setVisible(true));
if (game instanceof ClientGame) {
parentMenu.add(showVerifiedDice).setMnemonic(KeyEvent.VK_V);
}
}
protected void addGameOptionsMenu(final JMenu menuGame) {
if (!gameData.getProperties().getEditableProperties().isEmpty()) {
final AbstractAction optionsAction = SwingAction.of("Map Options", e -> {
final PropertiesUI ui = new PropertiesUI(gameData.getProperties().getEditableProperties(), false);
JOptionPane.showMessageDialog(frame, ui, "Map Options", JOptionPane.PLAIN_MESSAGE);
});
menuGame.add(optionsAction).setMnemonic(KeyEvent.VK_O);
}
}
/**
* Add a Politics Panel button to the game menu, this panel will show the
* current political landscape as a reference, no actions on this panel.
*/
private void addPoliticsMenu(final JMenu menuGame) {
final AbstractAction politicsAction = SwingAction.of("Show Politics Panel", e -> {
final PoliticalStateOverview ui = new PoliticalStateOverview(gameData, iuiContext, false);
final JScrollPane scroll = new JScrollPane(ui);
scroll.setBorder(BorderFactory.createEmptyBorder());
final Dimension screenResolution = Toolkit.getDefaultToolkit().getScreenSize();
// not only do we have a start bar, but we also have the message dialog to account for
final int availHeight = screenResolution.height - 120;
// just the scroll bars plus the window sides
final int availWidth = screenResolution.width - 40;
scroll.setPreferredSize(
new Dimension((scroll.getPreferredSize().width > availWidth ? availWidth : scroll.getPreferredSize().width),
(scroll.getPreferredSize().height > availHeight ? availHeight : scroll.getPreferredSize().height)));
JOptionPane.showMessageDialog(frame, scroll, "Politics Panel", JOptionPane.PLAIN_MESSAGE);
});
menuGame.add(politicsAction).setMnemonic(KeyEvent.VK_P);
}
private void addNotificationSettings(final JMenu parentMenu) {
final JMenu notificationMenu = new JMenu();
notificationMenu.setMnemonic(KeyEvent.VK_U);
notificationMenu.setText("User Notifications");
final JCheckBoxMenuItem showEndOfTurnReport = new JCheckBoxMenuItem("Show End of Turn Report");
showEndOfTurnReport.setMnemonic(KeyEvent.VK_R);
final JCheckBoxMenuItem showTriggeredNotifications = new JCheckBoxMenuItem("Show Triggered Notifications");
showTriggeredNotifications.setMnemonic(KeyEvent.VK_T);
final JCheckBoxMenuItem showTriggerChanceSuccessful =
new JCheckBoxMenuItem("Show Trigger/Condition Chance Roll Successful");
showTriggerChanceSuccessful.setMnemonic(KeyEvent.VK_S);
final JCheckBoxMenuItem showTriggerChanceFailure =
new JCheckBoxMenuItem("Show Trigger/Condition Chance Roll Failure");
showTriggerChanceFailure.setMnemonic(KeyEvent.VK_F);
notificationMenu.addMenuListener(new MenuListener() {
@Override
public void menuSelected(final MenuEvent e) {
showEndOfTurnReport.setSelected(iuiContext.getShowEndOfTurnReport());
showTriggeredNotifications.setSelected(iuiContext.getShowTriggeredNotifications());
showTriggerChanceSuccessful.setSelected(iuiContext.getShowTriggerChanceSuccessful());
showTriggerChanceFailure.setSelected(iuiContext.getShowTriggerChanceFailure());
}
@Override
public void menuDeselected(final MenuEvent e) {}
@Override
public void menuCanceled(final MenuEvent e) {}
});
showEndOfTurnReport.addActionListener(e -> iuiContext.setShowEndOfTurnReport(showEndOfTurnReport.isSelected()));
showTriggeredNotifications.addActionListener(
e -> iuiContext.setShowTriggeredNotifications(showTriggeredNotifications.isSelected()));
showTriggerChanceSuccessful.addActionListener(
e -> iuiContext.setShowTriggerChanceSuccessful(showTriggerChanceSuccessful.isSelected()));
showTriggerChanceFailure.addActionListener(
e -> iuiContext.setShowTriggerChanceFailure(showTriggerChanceFailure.isSelected()));
notificationMenu.add(showEndOfTurnReport);
notificationMenu.add(showTriggeredNotifications);
notificationMenu.add(showTriggerChanceSuccessful);
notificationMenu.add(showTriggerChanceFailure);
parentMenu.add(notificationMenu);
}
private void addShowDiceStats(final JMenu parentMenu) {
final Action showDiceStats = SwingAction.of("Show Dice Stats", e -> {
final IRandomStats randomStats =
(IRandomStats) game.getRemoteMessenger().getRemote(IRandomStats.RANDOM_STATS_REMOTE_NAME);
final RandomStatsDetails stats = randomStats.getRandomStats(gameData.getDiceSides());
JOptionPane.showMessageDialog(frame, new JScrollPane(stats.getAllStats()), "Random Stats",
JOptionPane.INFORMATION_MESSAGE);
});
parentMenu.add(showDiceStats).setMnemonic(KeyEvent.VK_D);
}
private void addRollDice(final JMenu parentMenu) {
final JMenuItem RollDiceBox = new JMenuItem("Roll Dice");
RollDiceBox.setMnemonic(KeyEvent.VK_R);
RollDiceBox.addActionListener(e -> {
final IntTextField numberOfText = new IntTextField(0, 100);
final IntTextField diceSidesText = new IntTextField(1, 200);
numberOfText.setText(String.valueOf(0));
diceSidesText.setText(String.valueOf(gameData.getDiceSides()));
final JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.add(new JLabel("Number of Dice to Roll: "), new GridBagConstraints(0, 0, 1, 1, 0, 0,
GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 20), 0, 0));
panel.add(new JLabel("Sides on the Dice: "), new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 20, 0, 10), 0, 0));
panel.add(numberOfText, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 0, 0, 20), 0, 0));
panel.add(diceSidesText, new GridBagConstraints(2, 1, 1, 1, 0, 0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(0, 20, 0, 10), 0, 0));
JOptionPane.showOptionDialog(JOptionPane.getFrameForComponent(parentMenu), panel, "Roll Dice",
JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE, null, new String[] {"OK"}, "OK");
try {
final int numberOfDice = Integer.parseInt(numberOfText.getText());
if (numberOfDice > 0) {
final int diceSides = Integer.parseInt(diceSidesText.getText());
final int[] dice =
game.getRandomSource().getRandom(diceSides, numberOfDice, "Rolling Dice, no effect on game.");
final JPanel panelDice = new JPanel();
final BoxLayout layout = new BoxLayout(panelDice, BoxLayout.Y_AXIS);
panelDice.setLayout(layout);
final JLabel label = new JLabel("Rolls (no effect on game): ");
panelDice.add(label);
String diceString = "";
for (int i = 0; i < dice.length; i++) {
diceString += String.valueOf(dice[i] + 1) + ((i == dice.length - 1) ? "" : ", ");
}
final JTextField diceList = new JTextField(diceString);
diceList.setEditable(false);
panelDice.add(diceList);
JOptionPane.showMessageDialog(frame, panelDice, "Dice Rolled", JOptionPane.INFORMATION_MESSAGE);
}
} catch (final Exception ex) {
// ignore malformed input
}
});
parentMenu.add(RollDiceBox);
}
private void addBattleCalculatorMenu(final JMenu menuGame) {
final Action showBattleMenu = SwingAction.of("Battle Calculator", e -> OddsCalculatorDialog.show(frame, null));
final JMenuItem showBattleMenuItem = menuGame.add(showBattleMenu);
showBattleMenuItem.setMnemonic(KeyEvent.VK_B);
showBattleMenuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_B, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
}
}