package tools.map.xml.creator;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.TreeSet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import games.strategy.ui.SwingAction;
public class GameSettingsPanel extends DynamicRowsPanel {
static final String allSettings = "mapName, notes, Neutral Flyover Allowed, More Constructions with Factory, "
+ "Unlimited Constructions, Move existing fighters to new carriers, More Constructions without Factory, "
+ "Produce new fighters on old carriers, MaxFactoriesPerTerritory, Multiple AA Per Territory, "
+ "Land existing fighters on new carriers, Kamikaze Airplanes, Multiply PUs, Submersible Subs, "
+ "Units Repair Hits Start Turn, Battleships repair at end of round, Choose AA Casualties, WW2V2, Low Luck, "
+ "Low Luck for AntiAircraft, Low Luck for Technology, Low Luck for Bombing and Territory Damage, Use Triggers, "
+ "neutralCharge, maxFactoriesPerTerritory, Always on AA, Produce fighters on carriers, "
+ "LHTR Carrier production rules, Two hit battleship, 4th Edition, Partial Amphibious Retreat, Total Victory, "
+ "Honorable Surrender, Projection of Power, All Rockets Attack, Neutrals Are Impassable, "
+ "Neutrals Are Blitzable, Rockets Can Violate Neutrality, Rockets Can Fly Over Impassables, Pacific Edition, "
+ "Anniversary Edition, No Economic Victory, Anniversary Edition Land Production, Anniversary Edition Air Naval, "
+ "Placement Restricted By Factory, Selectable Tech Roll, AA50 Tech Model, Tech Development, "
+ "Transport Restricted Unload, Random AA Casualties, Roll AA Individually, "
+ "Limit SBR Damage To Factory Production, Limit SBR Damage To Factory Production, Limit SBR Damage Per Turn, "
+ "Limit Rocket Damage Per Turn, Territory Turn Limit, SBR Victory Points, Rocket Attack Per Factory Restricted, "
+ "Allied Air Dependents, Defending Subs Sneak Attack, Attacker Retreat Planes, Surviving Air Move To Land, "
+ "Naval Bombard Casualties Return Fire, Blitz Through Factories And AA Restricted, "
+ "Unit Placement In Enemy Seas, Sub Control Sea Zone Restricted, Transport Control Sea Zone, "
+ "Production Per X Territories Restricted, Production Per Valued Territory Restricted, Place in Any Territory, "
+ "Unit Placement Per Territory Restricted, Movement By Territory Restricted, Transport Casualties Restricted, "
+ "Ignore Transport In Movement, Ignore Sub In Movement, Hari-Kari Units, Occupied Territories, "
+ "Unplaced units live when not placed, Air Attack Sub Restricted, Sub Retreat Before Battle, "
+ "Sub Retreat DD Restricted, Shore Bombard Per Ground Unit Restricted, "
+ "Damage From Bombing Done To Units Instead Of Territories, AA Territory Restricted, National Objectives, "
+ "Continuous Research";
public static enum SETTING_TYPE {
NORMAL, PER_PLAYER, PER_ALLY
}
public static SETTING_TYPE getSettingType(final String setting) {
if (setting.endsWith(" bid")) {
return SETTING_TYPE.PER_PLAYER;
} else if (setting.endsWith(" Honorable Victory VCs")) {
return SETTING_TYPE.PER_ALLY;
} else {
return SETTING_TYPE.NORMAL;
}
}
public static boolean isBoolean(final String setting) {
return (getSettingType(setting).equals(SETTING_TYPE.NORMAL) || setting.equals("MaxFactoriesPerTerritory"));
// TODO: maybe list is incomplete!
}
private final TreeSet<String> settingNames = new TreeSet<>();
public GameSettingsPanel(final JPanel stepActionPanel) {
super(stepActionPanel);
}
public static void layout(final MapXmlCreator mapXmlCreator) {
if (!DynamicRowsPanel.me.isPresent() || !(me.get() instanceof GameSettingsPanel)) {
me = Optional.of(new GameSettingsPanel(mapXmlCreator.getStepActionPanel()));
}
DynamicRowsPanel.layout(mapXmlCreator);
}
@Override
protected ActionListener getAutoFillAction() {
return null;
}
@Override
protected void layoutComponents() {
final JLabel labelSettingName = new JLabel("Setting Name");
Dimension dimension = labelSettingName.getPreferredSize();
labelSettingName.setPreferredSize(dimension);
final JLabel labelValue = new JLabel("Value");
dimension = (Dimension) dimension.clone();
dimension.width = DynamicRow.INPUT_FIELD_SIZE_SMALL;
labelValue.setPreferredSize(dimension);
final JLabel labelEditable = new JLabel("Editable");
dimension = (Dimension) dimension.clone();
dimension.width = DynamicRow.INPUT_FIELD_SIZE_SMALL;
labelEditable.setPreferredSize(dimension);
final JLabel labelMinNumber = new JLabel("Min. N.");
dimension = (Dimension) dimension.clone();
labelMinNumber.setPreferredSize(dimension);
final JLabel labelMaxNumber = new JLabel("Max. N.");
dimension = (Dimension) dimension.clone();
labelMaxNumber.setPreferredSize(dimension);
// <1> Set panel layout
final GridBagLayout gbl_stepActionPanel = new GridBagLayout();
setColumns(gbl_stepActionPanel);
setRows(gbl_stepActionPanel, MapXmlHelper.getGameSettingsMap().size());
getOwnPanel().setLayout(gbl_stepActionPanel);
// <2> Add Row Labels: Setting Name, Alliance Name, Buy Quantity
final GridBagConstraints gridBadConstLabelSettingName = new GridBagConstraints();
gridBadConstLabelSettingName.insets = new Insets(0, 0, 5, 5);
gridBadConstLabelSettingName.gridy = 0;
gridBadConstLabelSettingName.gridx = 0;
gridBadConstLabelSettingName.anchor = GridBagConstraints.WEST;
getOwnPanel().add(labelSettingName, gridBadConstLabelSettingName);
final GridBagConstraints gridBadConstLabelValue = (GridBagConstraints) gridBadConstLabelSettingName.clone();
gridBadConstLabelValue.gridx = 1;
getOwnPanel().add(labelValue, gridBadConstLabelValue);
final GridBagConstraints gridBadConstLabelEditable = (GridBagConstraints) gridBadConstLabelSettingName.clone();
gridBadConstLabelEditable.gridx = 2;
getOwnPanel().add(labelEditable, gridBadConstLabelEditable);
final GridBagConstraints gridBadConstLabelMinNumber = (GridBagConstraints) gridBadConstLabelSettingName.clone();
gridBadConstLabelMinNumber.gridx = 3;
getOwnPanel().add(labelMinNumber, gridBadConstLabelMinNumber);
final GridBagConstraints gridBadConstLabelMaxNumber = (GridBagConstraints) gridBadConstLabelSettingName.clone();
gridBadConstLabelMaxNumber.gridx = 4;
getOwnPanel().add(labelMaxNumber, gridBadConstLabelMaxNumber);
// <3> Add Main Input Rows
int rowIndex = 1;
final String[] settingNamesArray = settingNames.toArray(new String[settingNames.size()]);
for (final Entry<String, List<String>> settingEntry : MapXmlHelper.getGameSettingsMap().entrySet()) {
final GridBagConstraints gbc_tValue = (GridBagConstraints) gridBadConstLabelSettingName.clone();
gbc_tValue.gridx = 0;
gridBadConstLabelValue.gridy = rowIndex;
final List<String> settingValue = settingEntry.getValue();
int minValueInteger;
int maxValueInteger;
try {
minValueInteger = Integer.parseInt(settingValue.get(2));
maxValueInteger = Integer.parseInt(settingValue.get(3));
} catch (final NumberFormatException nfe) {
minValueInteger = 0;
maxValueInteger = 0;
}
final GameSettingsRow newRow = new GameSettingsRow(this, getOwnPanel(), settingEntry.getKey(), settingNamesArray,
settingValue.get(0), settingValue.get(1), minValueInteger, maxValueInteger);
newRow.addToParentComponentWithGbc(getOwnPanel(), rowIndex, gbc_tValue);
rows.add(newRow);
++rowIndex;
}
// <4> Add Final Button Row
final JButton buttonAddValue = new JButton("Add Game Setting");
buttonAddValue.setFont(MapXmlUIHelper.defaultMapXMLCreatorFont);
buttonAddValue.addActionListener(SwingAction.of("Add Game Setting", e -> {
final String suggestedSettingName = (String) JOptionPane.showInputDialog(getOwnPanel(),
"Which game setting should be added?", "Choose Game Setting", JOptionPane.QUESTION_MESSAGE, null,
settingNames.toArray(new String[settingNames.size()]), // Array of choices
settingNames.iterator().next()); // Initial choice
if (suggestedSettingName == null || suggestedSettingName.isEmpty()) {
return;
}
final ArrayList<String> newSettingValue = new ArrayList<>();
final boolean settingIsBoolean = isBoolean(suggestedSettingName);
final String newValue = settingIsBoolean ? "true" : "0";
newSettingValue.add(newValue);
newSettingValue.add("true");
newSettingValue.add("0");
newSettingValue.add("0");
MapXmlHelper.putGameSettings(suggestedSettingName, newSettingValue);
// UI Update
setRows((GridBagLayout) getOwnPanel().getLayout(), MapXmlHelper.getGameSettingsMap().size());
addRowWith(suggestedSettingName, newValue, "true", 0, 0);
SwingUtilities.invokeLater(() -> {
getOwnPanel().revalidate();
getOwnPanel().repaint();
});
}));
addButton(buttonAddValue);
final GridBagConstraints gridBadConstButtonAddUnit = (GridBagConstraints) gridBadConstLabelSettingName.clone();
gridBadConstButtonAddUnit.gridx = 0;
gridBadConstButtonAddUnit.gridy = rowIndex;
addFinalButtonRow(gridBadConstButtonAddUnit);
}
private DynamicRow addRowWith(final String settingName, final String newValue, final String editable,
final int minNumber, final int maxNumber) {
final GameSettingsRow newRow = new GameSettingsRow(this, getOwnPanel(), settingName,
settingNames.toArray(new String[settingNames.size()]), newValue, editable, minNumber, maxNumber);
addRow(newRow);
return newRow;
}
@Override
protected void initializeSpecifics() {
settingNames.clear();
settingNames.addAll(Arrays.asList(allSettings.split(", ")));
for (final String player : MapXmlHelper.getPlayerNames()) {
settingNames.add(player + " bid");
}
for (final String ally : MapXmlHelper.getPlayerAllianceMap().values()) {
settingNames.add(ally + " Honorable Victory VCs");
}
}
@Override
protected void setColumns(final GridBagLayout gblPanel) {
gblPanel.columnWidths = new int[] {60, 30, 30, 30, 30, 30};
gblPanel.columnWeights = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
}
}