/**
* Copyright (C) 2002-2012 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.client.gui.panel;
import java.util.ArrayList;
import java.util.logging.Logger;
import org.freecolandroid.repackaged.java.awt.Color;
import org.freecolandroid.repackaged.java.awt.Component;
import org.freecolandroid.repackaged.java.awt.event.ActionEvent;
import org.freecolandroid.repackaged.java.awt.event.ActionListener;
import org.freecolandroid.repackaged.javax.swing.ButtonGroup;
import org.freecolandroid.repackaged.javax.swing.JButton;
import org.freecolandroid.repackaged.javax.swing.JCheckBox;
import org.freecolandroid.repackaged.javax.swing.JComboBox;
import org.freecolandroid.repackaged.javax.swing.JLabel;
import org.freecolandroid.repackaged.javax.swing.JRadioButton;
import org.freecolandroid.repackaged.javax.swing.JSeparator;
import org.freecolandroid.repackaged.javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import net.sf.freecol.FreeCol;
import net.sf.freecol.client.FreeColClient;
import net.sf.freecol.client.control.ConnectController;
import net.sf.freecol.client.gui.GUI;
import net.sf.freecol.client.gui.i18n.Messages;
import net.sf.freecol.client.gui.plaf.FreeColComboBoxRenderer;
import net.sf.freecol.common.ServerInfo;
import net.sf.freecol.common.io.FreeColModFile;
import net.sf.freecol.common.io.FreeColTcFile;
import net.sf.freecol.common.io.Mods;
import net.sf.freecol.common.model.NationOptions.Advantages;
import net.sf.freecol.common.model.Specification;
import net.sf.freecol.common.option.OptionGroup;
/**
* This dialog allows the user to start a single player or multiplayer
* game, to join a running game and to fetch a list of games from the
* meta-server.
*/
public final class NewPanel extends FreeColPanel implements ActionListener {
private static final Logger logger = Logger.getLogger(NewPanel.class.getName());
private static enum NewPanelAction {
OK,
CANCEL,
SINGLE,
JOIN,
START,
META_SERVER
};
private final JLabel ipLabel = localizedLabel("host");
private final JLabel port1Label = localizedLabel("port");
private final JLabel port2Label = localizedLabel("startServerOnPort");
private final JLabel advantageLabel = localizedLabel("playerOptions.nationalAdvantages");
private final JLabel rulesLabel = localizedLabel("rules");
private final JCheckBox publicServer = new JCheckBox(Messages.message("publicServer"));
private final JTextField name = new JTextField(System.getProperty("user.name",
Messages.message("defaultPlayerName")), 20);
private final JTextField server = new JTextField("127.0.0.1");
private final JTextField port1 = new JTextField(Integer.toString(FreeCol.getDefaultPort()));
private final JTextField port2 = new JTextField(Integer.toString(FreeCol.getDefaultPort()));
private final JRadioButton single = new JRadioButton(Messages.message("singlePlayerGame"), true);
private final JRadioButton join = new JRadioButton(Messages.message("joinMultiPlayerGame"), false);
private final JRadioButton start = new JRadioButton(Messages.message("startMultiplayerGame"), false);
private final JRadioButton meta = new JRadioButton( Messages.message("getServerList")
+ " (" + FreeCol.META_SERVER_ADDRESS + ")", false);
private final Advantages[] choices = new Advantages[] {
Advantages.SELECTABLE,
Advantages.FIXED,
Advantages.NONE
};
private final JComboBox nationalAdvantages = new JComboBox(choices);
private final JComboBox specificationBox = new JComboBox();
private final Component[] joinComponents = new Component[] {
ipLabel, server, port1Label, port1
};
private final Component[] serverComponents = new Component[] {
publicServer, port2Label, port2
};
private final Component[] gameComponents = new Component[] {
advantageLabel, nationalAdvantages,
rulesLabel, specificationBox
};
private final ButtonGroup group = new ButtonGroup();
private final ConnectController connectController;
/**
* The specification to use for the new game.
*/
private Specification specification;
/**
* The constructor that will add the items to this panel.
*
* @param parent The parent of this panel.
*/
public NewPanel(FreeColClient freeColClient, GUI gui) {
this(freeColClient, gui, null);
}
/**
* The constructor that will add the items to this panel.
*
* @param parent The parent of this panel.
* @param specification a <code>Specification</code> value, may be null
*/
public NewPanel(FreeColClient freeColClient, GUI gui, Specification specification) {
super(freeColClient, gui);
this.specification = specification;
this.connectController = getFreeColClient().getConnectController();
for (FreeColTcFile tc : Mods.getRuleSets()) {
specificationBox.addItem(tc);
if ((specification == null && FreeCol.DEFAULT_TC.equals(tc.getId()))
|| (specification != null && specification.getId().equals(tc.getId()))) {
specificationBox.setSelectedItem(tc);
}
}
specificationBox.setRenderer(new FreeColModFileRenderer());
JButton cancel = new JButton( Messages.message("cancel") );
JLabel nameLabel = localizedLabel("name");
setCancelComponent(cancel);
nationalAdvantages.setRenderer(new AdvantageRenderer());
group.add(single);
group.add(join);
group.add(start);
group.add(meta);
setLayout(new MigLayout("", "[15]", ""));
add(single, "span 3");
add(new JSeparator(JSeparator.VERTICAL), "spany 7, grow");
add(nameLabel, "span, split 2");
add(name, "growx");
add(start, "newline, span 3");
add(advantageLabel);
add(nationalAdvantages, "growx");
add(port2Label, "newline, skip");
add(port2, "width 60:");
add(rulesLabel);
add(specificationBox, "growx");
add(publicServer, "newline, skip, span 2");
add(meta, "newline, span 3");
add(join, "newline, span 3");
add(ipLabel, "newline, skip, split 2");
add(server, "width 80:");
add(port1Label, "split 2");
add(port1, "width 60:");
add(okButton, "newline, span, split 2, tag ok");
add(cancel, "tag cancel");
okButton.setActionCommand(String.valueOf(NewPanelAction.OK));
cancel.setActionCommand(String.valueOf(NewPanelAction.CANCEL));
single.setActionCommand(String.valueOf(NewPanelAction.SINGLE));
join.setActionCommand(String.valueOf(NewPanelAction.JOIN));
start.setActionCommand(String.valueOf(NewPanelAction.START));
meta.setActionCommand(String.valueOf(NewPanelAction.META_SERVER));
cancel.addActionListener(this);
single.addActionListener(this);
join.addActionListener(this);
start.addActionListener(this);
meta.addActionListener(this);
single.setSelected(true);
enableComponents();
setSize(getPreferredSize());
}
/**
* Get the <code>Specification</code> value.
*
* @return a <code>Specification</code> value
*/
@Override
public Specification getSpecification() {
if (specification == null) {
try {
String tc = ((FreeColModFile) specificationBox.getSelectedItem()).getId();
FreeColTcFile tcData = new FreeColTcFile(tc);
specification = tcData.getSpecification();
} catch(Exception e) {
logger.warning(e.toString());
}
}
return specification;
}
/**
* Set the <code>Specification</code> value.
*
* @param newSpecification The new Specification value.
*/
public void setSpecification(final Specification newSpecification) {
this.specification = newSpecification;
}
private void enableComponents(Component[] components, boolean enable) {
for (Component c : components) {
c.setEnabled(enable);
}
}
private void enableComponents() {
NewPanelAction action = Enum.valueOf(NewPanelAction.class,
group.getSelection().getActionCommand());
switch(action) {
case SINGLE:
enableComponents(joinComponents, false);
enableComponents(serverComponents, false);
enableComponents(gameComponents, true);
specificationBox.setEnabled(specification == null);
break;
case JOIN:
enableComponents(joinComponents, true);
enableComponents(serverComponents, false);
enableComponents(gameComponents, false);
break;
case START:
enableComponents(joinComponents, false);
enableComponents(serverComponents, true);
enableComponents(gameComponents, true);
specificationBox.setEnabled(specification == null);
break;
case META_SERVER:
enableComponents(joinComponents, false);
enableComponents(serverComponents, false);
enableComponents(gameComponents, false);
break;
}
}
/**
* This function analyses an event and calls the right methods to take
* care of the user's requests.
* @param event The incoming ActionEvent.
*/
@Override
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
try {
switch (Enum.valueOf(NewPanelAction.class, command)) {
case OK:
NewPanelAction action = Enum.valueOf(NewPanelAction.class,
group.getSelection().getActionCommand());
switch(action) {
case SINGLE:
OptionGroup level = getGUI()
.showDifficultyDialog(getSpecification());
Advantages advantages;
if (level != null) {
getSpecification().applyDifficultyLevel(level);
advantages = (Advantages) nationalAdvantages.getSelectedItem();
connectController.startSingleplayerGame(getSpecification(), name.getText(), advantages);
}
break;
case JOIN:
try {
int port = Integer.valueOf(port1.getText()).intValue();
// tell Canvas to launch client
connectController.joinMultiplayerGame(name.getText(), server.getText(), port);
} catch (NumberFormatException e) {
port1Label.setForeground(Color.red);
}
break;
case START:
try {
int port = Integer.valueOf(port2.getText()).intValue();
level = getGUI()
.showDifficultyDialog(getSpecification());
getSpecification().applyDifficultyLevel(level);
advantages = (Advantages) nationalAdvantages.getSelectedItem();
connectController.startMultiplayerGame(getSpecification(), publicServer.isSelected(),
name.getText(), port, advantages, level);
} catch (NumberFormatException e) {
port2Label.setForeground(Color.red);
}
break;
case META_SERVER:
ArrayList<ServerInfo> serverList = connectController.getServerList();
if (serverList != null) {
getGUI().showServerListPanel(name.getText(), serverList);
}
}
break;
case CANCEL:
getGUI().removeFromCanvas(this);
getGUI().showMainPanel();
break;
case SINGLE:
case JOIN:
case START:
case META_SERVER:
enableComponents();
break;
default:
logger.warning("Invalid Action command: " + command);
}
} catch (Exception e) {
logger.warning(e.toString());
e.printStackTrace();
}
}
private class AdvantageRenderer extends FreeColComboBoxRenderer {
@Override
public void setLabelValues(JLabel label, Object value) {
label.setText(Messages.message("playerOptions." + value.toString()));
}
}
private class FreeColModFileRenderer extends FreeColComboBoxRenderer {
@Override
public void setLabelValues(JLabel label, Object value) {
FreeColModFile mod = (FreeColModFile) value;
label.setText(Messages.message("mod." + mod.getId() + ".name"));
}
}
}