package games.strategy.engine.framework.startup.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import games.strategy.engine.chat.IChatPanel;
import games.strategy.engine.framework.IGameLoader;
import games.strategy.engine.framework.startup.mc.ClientModel;
import games.strategy.engine.framework.startup.mc.IRemoteModelListener;
import games.strategy.engine.framework.ui.SaveGameFileChooser;
public class ClientSetupPanel extends SetupPanel {
private static final long serialVersionUID = 6942605803526295372L;
private final Insets BUTTON_INSETS = new Insets(0, 0, 0, 0);
private final ClientModel m_model;
private List<PlayerRow> m_playerRows = Collections.emptyList();
private final IRemoteModelListener m_listener = new IRemoteModelListener() {
@Override
public void playersTakenChanged() {}
@Override
public void playerListChanged() {
SwingUtilities.invokeLater(() -> internalPlayersChanged());
}
};
public ClientSetupPanel(final ClientModel model) {
m_model = model;
layoutComponents();
setupListeners();
setWidgetActivation();
}
private void internalPlayersChanged() {
final Map<String, String> players = m_model.getPlayerToNodesMapping();
final Map<String, Collection<String>> playerNamesAndAlliancesInTurnOrder =
m_model.getPlayerNamesAndAlliancesInTurnOrderLinkedHashMap();
final Map<String, Boolean> enabledPlayers = m_model.getPlayersEnabledListing();
final Collection<String> disableable = m_model.getPlayersAllowedToBeDisabled();
if (!m_model.getIsServerHeadlessCached()) {
// clients only get to change bot settings
disableable.clear();
}
m_playerRows = new ArrayList<>();
final Set<String> playerNames = playerNamesAndAlliancesInTurnOrder.keySet();
for (final String name : playerNames) {
final PlayerRow playerRow = new PlayerRow(name, playerNamesAndAlliancesInTurnOrder.get(name),
IGameLoader.CLIENT_PLAYER_TYPE, enabledPlayers.get(name));
m_playerRows.add(playerRow);
playerRow.update(players.get(name), disableable.contains(name));
}
layoutComponents();
}
private void layoutComponents() {
removeAll();
setLayout(new BorderLayout());
final JPanel info = new JPanel();
info.setLayout(new BoxLayout(info, BoxLayout.Y_AXIS));
info.add(new JLabel(" "));
add(info, BorderLayout.NORTH);
final JPanel players = new JPanel();
final GridBagLayout layout = new GridBagLayout();
players.setLayout(layout);
final Insets spacing = new Insets(3, 16, 0, 0);
final Insets lastSpacing = new Insets(3, 16, 0, 16);
int gridx = 0;
final GridBagConstraints enabledPlayerConstraints = new GridBagConstraints();
final boolean disableable = m_model.getPlayersAllowedToBeDisabled().isEmpty();
if (!disableable) {
enabledPlayerConstraints.anchor = GridBagConstraints.WEST;
enabledPlayerConstraints.gridx = gridx++;
enabledPlayerConstraints.insets = new Insets(3, 20, 0, -10);
}
final GridBagConstraints nameConstraints = new GridBagConstraints();
nameConstraints.anchor = GridBagConstraints.WEST;
nameConstraints.gridx = gridx++;
nameConstraints.insets = spacing;
gridx++;
final GridBagConstraints playerConstraints = new GridBagConstraints();
playerConstraints.anchor = GridBagConstraints.WEST;
playerConstraints.gridx = gridx++;
playerConstraints.insets = spacing;
final GridBagConstraints playConstraints = new GridBagConstraints();
playConstraints.anchor = GridBagConstraints.WEST;
playConstraints.gridx = gridx++;
playConstraints.insets = spacing;
final GridBagConstraints allianceConstraints = new GridBagConstraints();
allianceConstraints.anchor = GridBagConstraints.WEST;
allianceConstraints.gridx = gridx++;
allianceConstraints.insets = lastSpacing;
if (!disableable) {
final JLabel enableLabel = new JLabel("Use");
enableLabel.setForeground(Color.black);
layout.setConstraints(enableLabel, enabledPlayerConstraints);
players.add(enableLabel);
}
final JLabel nameLabel = new JLabel("Name");
nameLabel.setForeground(Color.black);
layout.setConstraints(nameLabel, nameConstraints);
players.add(nameLabel);
final JLabel playerLabel = new JLabel("Played By");
playerLabel.setForeground(Color.black);
layout.setConstraints(playerLabel, playerConstraints);
players.add(playerLabel);
final JLabel playedByLabel = new JLabel(" ");
layout.setConstraints(playedByLabel, playConstraints);
players.add(playedByLabel);
final JLabel allianceLabel = new JLabel("Alliance");
// allianceLabel.setForeground(Color.black);
layout.setConstraints(allianceLabel, allianceConstraints);
players.add(allianceLabel);
for (final PlayerRow row : m_playerRows) {
if (!disableable) {
layout.setConstraints(row.getEnabledPlayer(), enabledPlayerConstraints);
players.add(row.getEnabledPlayer());
}
layout.setConstraints(row.getName(), nameConstraints);
players.add(row.getName());
layout.setConstraints(row.getPlayer(), playerConstraints);
players.add(row.getPlayer());
layout.setConstraints(row.getPlayerComponent(), playConstraints);
players.add(row.getPlayerComponent());
layout.setConstraints(row.getAlliance(), allianceConstraints);
players.add(row.getAlliance());
}
add(players, BorderLayout.CENTER);
validate();
}
private void setupListeners() {
m_model.setRemoteModelListener(m_listener);
}
@Override
public void setWidgetActivation() {}
@Override
public void shutDown() {
m_model.shutDown();
}
@Override
public void cancel() {
m_model.cancel();
}
@Override
public boolean canGameStart() {
// our server must handle this
return false;
}
class PlayerRow {
private final JCheckBox m_enabledCheckBox;
private final JLabel m_playerNameLabel;
private final JLabel m_playerLabel;
private JComponent m_playerComponent;
private final String m_localPlayerType;
private JLabel m_alliance;
PlayerRow(final String playerName, final Collection<String> playerAlliances, final String localPlayerType,
final boolean enabled) {
m_playerNameLabel = new JLabel(playerName);
m_playerLabel = new JLabel("");
m_playerComponent = new JLabel("");
m_localPlayerType = localPlayerType;
m_enabledCheckBox = new JCheckBox();
m_enabledCheckBox.addActionListener(m_disablePlayerActionListener);
m_enabledCheckBox.setSelected(enabled);
if (playerAlliances.contains(playerName)) {
m_alliance = new JLabel();
} else {
m_alliance = new JLabel(playerAlliances.toString());
}
}
public JLabel getName() {
return m_playerNameLabel;
}
public JLabel getPlayer() {
return m_playerLabel;
}
public String getPlayerName() {
return m_playerNameLabel.getText();
}
public JLabel getAlliance() {
return m_alliance;
}
public JCheckBox getEnabledPlayer() {
return m_enabledCheckBox;
}
public void update(final String playerName, final boolean disableable) {
if (playerName == null) {
m_playerLabel.setText("-");
final JButton button = new JButton(m_takeAction);
button.setMargin(BUTTON_INSETS);
m_playerComponent = button;
} else {
m_playerLabel.setText(playerName);
if (playerName.equals(m_model.getMessenger().getLocalNode().getName())) {
final JButton button = new JButton(m_dontTakeAction);
button.setMargin(BUTTON_INSETS);
m_playerComponent = button;
} else {
m_playerComponent = new JLabel("");
}
}
setWidgetActivation(disableable);
}
private void setWidgetActivation(final boolean disableable) {
m_playerNameLabel.setEnabled(m_enabledCheckBox.isSelected());
m_playerLabel.setEnabled(m_enabledCheckBox.isSelected());
m_playerComponent.setEnabled(m_enabledCheckBox.isSelected());
m_alliance.setEnabled(m_enabledCheckBox.isSelected());
m_enabledCheckBox.setEnabled(disableable);
}
public boolean isPlaying() {
return m_playerLabel.getText().equals(m_model.getMessenger().getLocalNode().getName());
}
public JComponent getPlayerComponent() {
return m_playerComponent;
}
public String getLocalType() {
return m_localPlayerType;
}
private final Action m_takeAction = new AbstractAction("Play") {
private static final long serialVersionUID = 9086754428763609790L;
@Override
public void actionPerformed(final ActionEvent e) {
m_model.takePlayer(m_playerNameLabel.getText());
}
};
private final Action m_dontTakeAction = new AbstractAction("Dont Play") {
private static final long serialVersionUID = 8735891444454338978L;
@Override
public void actionPerformed(final ActionEvent e) {
m_model.releasePlayer(m_playerNameLabel.getText());
}
};
private final ActionListener m_disablePlayerActionListener = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (m_enabledCheckBox.isSelected()) {
m_model.enablePlayer(m_playerNameLabel.getText());
} else {
m_model.disablePlayer(m_playerNameLabel.getText());
}
setWidgetActivation(true);
}
};
}
@Override
public IChatPanel getChatPanel() {
return m_model.getChatPanel();
}
@Override
public List<Action> getUserActions() {
if (m_model == null) {
return new ArrayList<>();
}
final boolean isServerHeadless = m_model.getIsServerHeadlessCached();
if (!isServerHeadless) {
return new ArrayList<>();
}
final List<Action> rVal = new ArrayList<>();
rVal.add(m_model.getHostBotSetMapClientAction(this));
rVal.add(m_model.getHostBotChangeGameOptionsClientAction(this));
rVal.add(m_model.getHostBotChangeGameToSaveGameClientAction(this));
rVal.add(m_model.getHostBotChangeToAutosaveClientAction(this, SaveGameFileChooser.AUTOSAVE_TYPE.AUTOSAVE));
rVal.add(m_model.getHostBotChangeToAutosaveClientAction(this, SaveGameFileChooser.AUTOSAVE_TYPE.AUTOSAVE2));
rVal.add(m_model.getHostBotChangeToAutosaveClientAction(this, SaveGameFileChooser.AUTOSAVE_TYPE.AUTOSAVE_ODD));
rVal.add(m_model.getHostBotChangeToAutosaveClientAction(this, SaveGameFileChooser.AUTOSAVE_TYPE.AUTOSAVE_EVEN));
rVal.add(m_model.getHostBotGetGameSaveClientAction(this));
return rVal;
}
@Override
public boolean isMetaSetupPanelInstance() {
return false;
}
}