package pdp.scrabble.ihm;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import java.util.Deque;
import java.util.ArrayDeque;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Enumeration;
import pdp.scrabble.game.SearchStrategy;
import pdp.scrabble.utility.Tool;
import pdp.scrabble.game.SearchLevel;
import pdp.scrabble.utility.Display;
import static pdp.scrabble.Language.getGameLang;
/** New game selection dialog handler.
*/
public class NewGameSelection extends JDialog {
private static final long serialVersionUID = 1L;
/** Solo based game index. */
private static final int SOLO_BASED_GAME = 0;
/** Turn based game index. */
private static final int TURN_BASED_GAME = 1;
/** Multiplayer based game index. */
private static final int MULTI_BASED_GAME = 2;
/** Multiplayer based game index. */
private static final int AI_BATTLE_GAME = 3;
/** List of games type (name, description). */
public static final String[][] GAMES_TYPE = {
{"Solo training",
"Start a new solo game. Player can improve his skills by playing on its own."},
{"Turn based game",
"Start a new game with 1-4 players on the same computer."},
{"Multiplayer",
"Allows to play with other player on the internet."},
{"Simulation",
"Solve a simulation with two AI."}
};
/** Main frame reference. */
private MainFrame mainFrame = null;
/** New game choice reference. */
private ButtonGroup choice = null;
/** Game selection index. */
private int selection = 0;
/** Create a new game selection.
* @param mainFrame main frame reference.
*/
public NewGameSelection(MainFrame mainFrame) {
super(mainFrame);
mainFrame.setEnabled(false);
this.mainFrame = mainFrame;
this.setTitle(getGameLang("New Game"));
this.setResizable(false);
this.setLayout(new GridLayout(2, 0));
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
/** Initialize selection. */
public void create() {
// Choices
JPanel choices = new JPanel();
this.choice = new ButtonGroup();
// Create radio buttons
for (int i = 0; i < GAMES_TYPE.length; i++) {
if (i == 0) { // Select first button as default
this.addRadioButton(
choices, this.choice,
GAMES_TYPE[i][0], GAMES_TYPE[i][1]).setSelected(true);
}
else {
this.addRadioButton(
choices, this.choice,
GAMES_TYPE[i][0], GAMES_TYPE[i][1]);
}
}
// Confirm button
JPanel buttons = new JPanel();
JButton button = new JButton(getGameLang("Select"));
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
select();
}
});
buttons.add(button);
// Cancel button
button = new JButton(getGameLang("Cancel"));
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cancel();
}
});
buttons.add(button);
this.add(choices);
this.add(buttons);
// Show dialog and block main frame
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
/** Confirm new game selection. */
private void select() {
Enumeration<AbstractButton> en = this.choice.getElements();
int index = -1;
while (en.hasMoreElements()) {
AbstractButton button = en.nextElement();
index++;
if (button.isSelected()) {
break;
}
}
// Update index selection
this.selection = index;
// Update game type for stats panel
this.mainFrame.getStatsPanel().setGameType(GAMES_TYPE[this.selection][0]);
this.mainFrame.getMultiplayerPanel().setVisible(false);
this.mainFrame.getPlayerPanel().unlock();
this.mainFrame.game().reset();
this.mainFrame.game().setIsLoading(false);
// Detect game type selection
if (this.selection == SOLO_BASED_GAME) {
this.createSoloBasedGame();
}
else if (this.selection == TURN_BASED_GAME) {
this.createTurnBasedGame();
}
else if (this.selection == MULTI_BASED_GAME) {
this.createMultiplayerBasedGame();
}
else if (this.selection == AI_BATTLE_GAME) {
this.createAIBattleGame();
}
}
/** Cancel new game selection. */
private void cancel() {
this.selection = 0;
this.terminate();
}
/** Terminate dialog, and restore focus on main frame. */
private void terminate() {
this.dispose();
this.mainFrame.setEnabled(true);
this.mainFrame.repaint();
this.mainFrame.requestFocus();
}
/** Enable or disable autosave. */
private void autosave() {
if (this.mainFrame.game().isAutoSave() == false) {
this.mainFrame.game().setAutoSave(true);
}
else {
this.mainFrame.game().setAutoSave(false);
}
}
/** Create a solo based game. */
private void createSoloBasedGame() {
final JDialog dialog = this.createDialog("Player name");
// Field
final JTextField name = new JTextField(getGameLang("default"));
final JCheckBox autosave = new JCheckBox(getGameLang("Autosave"), false);
autosave.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
autosave();
}
});
dialog.add(name);
dialog.add(autosave);
name.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
Pattern pattern = Pattern.compile("\\w{3,15}");
Matcher matcher = pattern.matcher(name.getText());
if (!matcher.matches()) {
Display.error("Nickname",
"Use character and numbers. Length : 3-15");
return;
}
dialog.dispose();
terminate();
mainFrame.createSoloBasedGame(name.getText());
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
// Done button
JButton button = new JButton(getGameLang("Done"));
dialog.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Pattern pattern = Pattern.compile("\\w{3,15}");
Matcher matcher = pattern.matcher(name.getText());
if (!matcher.matches()) {
Display.error("Nickname",
"Use character and numbers. Length : 3-15");
return;
}
dialog.dispose();
terminate();
mainFrame.createSoloBasedGame(name.getText());
}
});
this.startDialog(dialog);
}
/** Create a turn based game, with player or AI on the same computer. */
private void createTurnBasedGame() {
final JDialog dialog = this.createDialog("Players [1-4]");
// Fields
final List<JTextField> names = new ArrayList<JTextField>(4);
final List<JCheckBox> AIs = new ArrayList<JCheckBox>(4);
final List<JCheckBox> AItime = new ArrayList<JCheckBox>(4);
final List<JCheckBox> debug = new ArrayList<JCheckBox>(4);
final List<JComboBox> levels = new ArrayList<JComboBox>(4);
final List<JComboBox> strategies = new ArrayList<JComboBox>(4);
final List<Container> playerData = new ArrayList<Container>(4);
final Deque<Integer> number = new ArrayDeque<Integer>(1);
SearchLevel[] lvls = SearchLevel.values();
String[] vLevels = new String[lvls.length];
for (int i = 0; i < lvls.length; i++) {
vLevels[i] = Tool.capitalize(lvls[i].name());
}
SearchStrategy[] strategys = SearchStrategy.values();
String[] vStrategies = new String[strategys.length];
for (int i = 0; i < strategys.length; i++) {
vStrategies[i] = Tool.capitalize(strategys[i].name());
}
for (int i = 0; i < 4; i++) {
names.add(new JTextField("player" + i));
AIs.add(new JCheckBox(getGameLang("Is AI"), false));
AItime.add(new JCheckBox(getGameLang("Fast Solve"), false));
debug.add(new JCheckBox(getGameLang("Show debug"), false));
levels.add(new JComboBox(vLevels));
strategies.add(new JComboBox(vStrategies));
levels.get(i).setSelectedIndex(1);
strategies.get(i).setSelectedIndex(2);
Container container = new Container();
container.setLayout(new GridLayout(0, 6));
container.add(names.get(i));
container.add(AIs.get(i));
container.add(AItime.get(i));
container.add(debug.get(i));
container.add(levels.get(i));
container.add(strategies.get(i));
playerData.add(container);
}
final JTextField playerNum = new JTextField("2");
final JCheckBox autosave = new JCheckBox(getGameLang("Autosave"), false);
autosave.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
autosave();
}
});
dialog.add(playerNum);
dialog.add(autosave);
// Buttons
final JButton next = new JButton(getGameLang("Next"));
final JButton done = new JButton(getGameLang("Done"));
final JButton back = new JButton(getGameLang("Back"));
// Next action
dialog.add(next);
next.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int num = 0;
// Get number of players
try {
num = Integer.parseInt(playerNum.getText());
}
catch (NumberFormatException ex) {
num = 0;
}
// Check number value
if (num < 1 || num > 4) {
Display.error("Player number",
"Number of player not valid: [1-4]");
return;
}
// Players name
for (int i = 0; i < num; i++) {
names.get(i).setText(getGameLang("player") + (i + 1));
AIs.get(i).setSelected(false);
AItime.get(i).setSelected(false);
debug.get(i).setSelected(false);
levels.get(i).setSelectedIndex(1);
strategies.get(i).setSelectedIndex(2);
}
// Disable previous buttons
playerNum.setEnabled(false);
autosave.setEnabled(false);
next.setEnabled(false);
// Enable new buttons
dialog.add(next);
for (int i = 0; i < num; i++) {
dialog.add(playerData.get(i));
}
number.push(num);
dialog.add(back);
dialog.add(done);
updateDialog(dialog);
}
});
// Back action
back.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
playerNum.setEnabled(true);
autosave.setEnabled(true);
next.setEnabled(true);
for (int i = 0; i < names.size(); i++) {
dialog.remove(playerData.get(i));
}
number.pop();
dialog.remove(back);
dialog.remove(done);
updateDialog(dialog);
}
});
// Done action
done.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
playerData.clear();
dialog.dispose();
terminate();
mainFrame.createTurnBasedGame(
number.pop(), names, AIs, AItime,
debug, levels, strategies);
}
});
this.startDialog(dialog);
}
/** Create a multiplayer based game, to play on the internet. */
private void createMultiplayerBasedGame() {
final JDialog dialog = this.createDialog("Player name");
// Field
final JTextField name = new JTextField(getGameLang("default"));
dialog.add(name);
name.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
Pattern pattern = Pattern.compile("\\w{3,15}");
Matcher matcher = pattern.matcher(name.getText());
if (!matcher.matches()) {
Display.error("Nickname",
"Use character and numbers. Length : 3-15");
return;
}
dialog.dispose();
terminate();
mainFrame.createMultiplayerBasedGame(name.getText());
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
// Done button
JButton button = new JButton(getGameLang("Done"));
dialog.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Pattern pattern = Pattern.compile("\\w{3,15}");
Matcher matcher = pattern.matcher(name.getText());
if (!matcher.matches()) {
Display.error("Nickname",
"Use character and numbers. Length : 3-15");
return;
}
dialog.dispose();
terminate();
mainFrame.createMultiplayerBasedGame(name.getText());
}
});
this.mainFrame.getMultiplayerPanel().setVisible(true);
this.startDialog(dialog);
}
private void createAIBattleGame() {
final JDialog dialog = this.createDialog("AI Battle");
final JComboBox[] levels = new JComboBox[2];
// Field
final JTextField itrs = new JTextField(
getGameLang("simulations [1-10000]"));
dialog.setLayout(new GridLayout(0, 1));
dialog.add(itrs);
for (int i = 0; i < 2; i++) {
levels[i] = new JComboBox(SearchLevel.values());
levels[i].setSelectedIndex(2);
dialog.add(levels[i]);
}
// Done button
JButton button = new JButton(getGameLang("Done"));
dialog.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int num = 0;
// Get number of players
try {
num = Integer.parseInt(itrs.getText());
}
catch (NumberFormatException ex) {
num = 0;
}
// Check number value
if (num < 1 || num > 10000) {
Display.error("Number of simulation",
"Number not valid: [1-10000]");
return;
}
dialog.dispose();
terminate();
mainFrame.createAIBattleGame(num, levels);
}
});
this.startDialog(dialog);
}
/** Add a radio button.
* @param container container.
* @param bg button group.
* @param name radio button name.
* @param toolTip tool tip text.
* @return return created radio button.
*/
private JRadioButton addRadioButton(
Container container, ButtonGroup bg, String name, String toolTip) {
JRadioButton radio = new JRadioButton(getGameLang(name));
radio.setToolTipText(getGameLang(toolTip));
container.add(radio);
bg.add(radio);
return radio;
}
/** Create a dialog.
* @param title dialog title.
* @return created dialog.
*/
private JDialog createDialog(String title) {
JDialog dialog = new JDialog(this.mainFrame, getGameLang(title));
dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
dialog.setResizable(false);
dialog.setLayout(new GridLayout(0, 1));
dialog.setMinimumSize(new Dimension(160, 64));
return dialog;
}
/** Start dialog and show it.
* @param dialog dialog to start.
*/
private void startDialog(JDialog dialog) {
this.updateDialog(dialog);
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
this.setEnabled(false);
}
/** Update dialog frame in case of changes.
* @param dialog dialog to update.
*/
private void updateDialog(JDialog dialog) {
dialog.pack();
dialog.validate();
dialog.repaint();
dialog.setLocationRelativeTo(null);
}
}