package nl.tudelft.bw4t.scenariogui.editor.controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.xml.bind.JAXBException;
import nl.tudelft.bw4t.scenariogui.BW4TClientConfig;
import nl.tudelft.bw4t.scenariogui.DefaultConfigurationValues;
import nl.tudelft.bw4t.scenariogui.ScenarioEditor;
import nl.tudelft.bw4t.scenariogui.editor.gui.ConfigurationPanel;
import nl.tudelft.bw4t.scenariogui.editor.gui.EntityPanel;
import nl.tudelft.bw4t.scenariogui.editor.gui.MainPanel;
import nl.tudelft.bw4t.scenariogui.editor.gui.MenuBar;
import nl.tudelft.bw4t.scenariogui.util.FileFilters;
import nl.tudelft.bw4t.scenariogui.util.MapSpec;
/**
* Handles the event of the menu.
*/
public abstract class AbstractMenuOption implements ActionListener {
private MenuBar view;
private BW4TClientConfig model;
private ScenarioEditorController controller;
// made a variable for this so we can call it during testing
private JFileChooser currentFileChooser;
private boolean fileChooserApprove = false;
/**
* Constructs a menu option object.
*
* @param newView
* The new view.
* @param mainView
* The main view controllers.
* @param model
* The model.
*/
public AbstractMenuOption(final MenuBar newView,
final ScenarioEditorController mainView, BW4TClientConfig model) {
this.view = newView;
this.setController(mainView);
this.model = model;
/*
* Set the intial file chooser and option prompt, can eventually be
* changed when tests need to be ran.
*/
setCurrentFileChooser(new JFileChooser());
}
public JFileChooser getCurrentFileChooser() {
return currentFileChooser;
}
public void setCurrentFileChooser(final JFileChooser newFileChooser) {
currentFileChooser = newFileChooser;
}
/**
* Saves a file.
*/
public void saveFile() {
saveFile(!view.hasLastFileLocation());
}
/**
* Saves the configuration to XML. When the configuration hasn't been saved
* before an file chooser is opened.
*
* @param saveAs
* Whether or not to open a file chooser.
*/
public void saveFile(final boolean saveAs) {
if (validateBotCount() && verifyMapSelected()) {
String path = view.getLastFileLocation();
// Check if the previous save location exists.
if (wasPreviousSaveRemoved(path)) {
view.setLastFileLocation(null);
currentFileChooser.setCurrentDirectory(new File("."));
}
if (saveAs || !view.hasLastFileLocation()) {
path = getPathToSaveFromUser();
if (path == null) {
return;
}
}
saveConfigAsXMLFile(path);
}
}
private boolean wasPreviousSaveRemoved(String path) {
return view.hasLastFileLocation() && !new File(path).exists();
}
public void setFileChooserApprove() {
currentFileChooser = getCurrentFileChooser();
/** Adds an xml filter for the file chooser: */
currentFileChooser.setFileFilter(FileFilters.xmlFilter());
fileChooserApprove = currentFileChooser
.showDialog(getController().getMainView(), "Save Scenario") == JFileChooser.APPROVE_OPTION;
}
public boolean getFileChooserApprove() {
return fileChooserApprove;
}
private String getPathToSaveFromUser() {
String path = null;
setFileChooserApprove();
if (fileChooserApprove) {
File file = currentFileChooser.getSelectedFile();
path = file.getAbsolutePath();
String extension = ".xml";
if (!path.endsWith(extension)) {
path += extension;
file = new File(path);
}
controller.getMainView().setWindowTitle(file.getName());
}
return path;
}
private boolean validateBotCount() {
ScenarioEditor se = controller.getMainView();
MainPanel mp = se.getMainPanel();
ConfigurationPanel cp = mp.getConfigurationPanel();
MapSpec map = cp.getMapSpecifications();
int botCount = getModel().getAmountBot();
if (map.isSet() && botCount > map.getEntitiesAllowedInMap()) {
ScenarioEditor.getOptionPrompt().showMessageDialog(
view,
"The selected map can only hold "
+ map.getEntitiesAllowedInMap()
+ " bots. Please delete some first.");
return false;
}
return true;
}
private boolean verifyMapSelected() {
ScenarioEditor se = controller.getMainView();
MainPanel mp = se.getMainPanel();
ConfigurationPanel cp = mp.getConfigurationPanel();
String map = cp.getMapFile();
if(map.trim().isEmpty()) {
int response = ScenarioEditor.getOptionPrompt().showConfirmDialog(getController().getMainView(),
"Warning: No map file has been selected. Press OK to continue.",
"",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
return response == JOptionPane.OK_OPTION;
}
return true;
}
/**
* Saves the config at the path specified as an XML file.
* @param destination The path.
*/
public void saveConfigAsXMLFile(String destination) {
try {
BW4TClientConfig configuration = getModel();
configuration.setFileLocation(destination);
configuration.setUseGoal(DefaultConfigurationValues.USE_GOAL.getBooleanValue());
configuration.toXML();
view.setLastFileLocation(destination);
} catch (JAXBException e) {
ScenarioEditor.handleException(e,
"Error: Saving to XML has failed.");
} catch (FileNotFoundException e) {
ScenarioEditor.handleException(e, "Error: No file has been found.");
}
}
/**
* Update the model with the new bot and epartners, and update the counts in the view.
*/
public void updateModelAndView() {
ScenarioEditor se = controller.getMainView();
MainPanel mp = se.getMainPanel();
ConfigurationPanel cp = mp.getConfigurationPanel();
cp.updateOldValues();
getModel().updateOldBotConfigs();
EntityPanel ep = mp.getEntityPanel();
ep.updateEPartnerCount(getModel().getAmountEPartner());
getModel().updateOldEpartnerConfigs();
}
public MenuBar getMenuView() {
return this.view;
}
/**
* Gets called when the button associated with this action is pressed.
*
* @param e The action event.
*/
public abstract void actionPerformed(ActionEvent e);
public ScenarioEditorController getController() {
return controller;
}
public void setController(final ScenarioEditorController newController) {
controller = newController;
}
public BW4TClientConfig getModel() {
return model;
}
}