/** * 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.control; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.logging.Logger; import javax.swing.SwingUtilities; import net.sf.freecol.FreeCol; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.GUI; import net.sf.freecol.client.gui.i18n.Messages; import net.sf.freecol.client.gui.panel.MapEditorTransformPanel.MapTransform; import net.sf.freecol.common.FreeColException; import net.sf.freecol.common.io.FreeColDirectories; import net.sf.freecol.common.io.FreeColSavegameFile; import net.sf.freecol.common.io.FreeColTcFile; import net.sf.freecol.common.model.Game; import net.sf.freecol.common.model.Specification; import net.sf.freecol.common.model.Tile; import net.sf.freecol.common.networking.NoRouteToServerException; import net.sf.freecol.common.option.MapGeneratorOptions; import net.sf.freecol.common.option.OptionGroup; import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.generator.MapGenerator; /** * The map editor controller. */ public final class MapEditorController { @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(MapEditorController.class.getName()); /** * The main controller. */ private final FreeColClient freeColClient; /** * The transform that should be applied to a * <code>Tile</code> that is clicked on the map. */ private MapTransform currentMapTransform = null; private GUI gui; /** * Creates a new <code>MapEditorController</code>. * @param freeColClient The main controller. */ public MapEditorController(FreeColClient freeColClient, GUI gui) { this.freeColClient = freeColClient; this.gui = gui; } /** * Enters map editor modus. */ public void startMapEditor() { // TODO: fixme! Specification must be known in advance final String tc = "freecol"; try { FreeColTcFile tcData = new FreeColTcFile(tc); Specification specification = tcData.getSpecification(); freeColClient.setMapEditor(true); final FreeColServer freeColServer = new FreeColServer(specification, false, false, 0, null); freeColClient.setFreeColServer(freeColServer); freeColClient.setGame(freeColServer.getGame()); freeColClient.setMyPlayer(null); gui.playSound(null); gui.closeMainPanel(); gui.closeMenus(); freeColClient.setInGame(true); gui.startMapEditorGUI(); } catch (NoRouteToServerException e) { gui.errorMessage("server.noRouteToServer"); return; } catch (IOException e) { gui.errorMessage("server.couldNotStart"); return; } } /** * Sets the currently chosen <code>MapTransform</code>. * @param mt The transform that should be applied to a * <code>Tile</code> that is clicked on the map. */ public void setMapTransform(MapTransform mt) { currentMapTransform = mt; gui.updateMapControls(); } /** * Gets the current <code>MapTransform</code>. * @return The transform that should be applied to a * <code>Tile</code> that is clicked on the map. */ public MapTransform getMapTransform() { return currentMapTransform; } /** * Transforms the given <code>Tile</code> using the * {@link #getMapTransform() current <code>MapTransform</code>}. * * @param t The <code>Tile</code> to be modified. */ public void transform(Tile t) { if (currentMapTransform != null) { currentMapTransform.transform(t); } } /** * Creates a new map using a <code>MapGenerator</code>. A panel * with the <code>MapGeneratorOptions</code> is first displayed. * * @see MapGenerator * @see MapGeneratorOptions */ public void newMap() { final Game game = freeColClient.getGame(); final MapGenerator mapGenerator = freeColClient.getFreeColServer().getMapGenerator(); OptionGroup group = freeColClient.getGame().getMapGeneratorOptions(); group = gui.showMapGeneratorOptionsDialog(group, true, true); if (group == null) { return; } try { if (game.getSpecification().getDifficultyLevel() == null) { game.getSpecification().applyDifficultyLevel("model.difficulty.medium"); } mapGenerator.createMap(game); gui.setFocus(game.getMap().getTile(1,1)); freeColClient.updateActions(); gui.refresh(); } catch (FreeColException e) { gui.closeMenus(); gui.errorMessage( e.getMessage() ); } } /** * Opens a dialog where the user should specify the filename * and saves the game. */ public void saveGame() { String fileName = "my_map.fsg"; final File file = gui.showSaveDialog(FreeColDirectories.getSaveDirectory(), fileName); if (file != null) { saveGame(file); } } /** * Saves the game to the given file. * @param file The <code>File</code>. */ public void saveGame(final File file) { gui.showStatusPanel(Messages.message("status.savingGame")); Thread t = new Thread(FreeCol.CLIENT_THREAD+"Saving Map") { @Override public void run() { try { BufferedImage scaledImage = gui.createMiniMapThumbNail(); freeColClient.getFreeColServer().saveGame(file, "mapEditor", null, scaledImage); SwingUtilities.invokeLater(new Runnable() { public void run() { gui.closeStatusPanel(); gui.requestFocusInWindow(); } }); } catch (IOException e) { SwingUtilities.invokeLater(new Runnable() { public void run() { gui.errorMessage("couldNotSaveGame"); } }); } } }; t.start(); } /** * Opens a dialog where the user should specify the filename and loads the * game. */ public void loadGame() { File file = gui.showLoadDialog(FreeColDirectories.getSaveDirectory()); if (file == null) { return; } if (!file.isFile()) { gui.errorMessage("fileNotFound"); return; } loadGame(file); } /** * Loads a game from the given file. * @param file The <code>File</code>. */ public void loadGame(File file) { final File theFile = file; freeColClient.setMapEditor(true); class ErrorJob implements Runnable { private final String message; ErrorJob( String message ) { this.message = message; } public void run() { gui.closeMenus(); gui.errorMessage( message ); } } gui.showStatusPanel(Messages.message("status.loadingGame")); Runnable loadGameJob = new Runnable() { public void run() { FreeColServer freeColServer = null; try { freeColServer = new FreeColServer(new FreeColSavegameFile(theFile), 0, "MapEditor"); freeColClient.setFreeColServer(freeColServer); freeColClient.setGame(freeColServer.getGame()); SwingUtilities.invokeLater( new Runnable() { public void run() { gui.closeStatusPanel(); gui.setFocus(freeColClient.getGame().getMap().getTile(1,1)); freeColClient.updateActions(); gui.refresh(); } } ); } catch (NoRouteToServerException e) { reloadMainPanel(); SwingUtilities.invokeLater( new ErrorJob("server.noRouteToServer") ); } catch (FileNotFoundException e) { reloadMainPanel(); SwingUtilities.invokeLater( new ErrorJob("fileNotFound") ); } catch (IOException e) { reloadMainPanel(); SwingUtilities.invokeLater( new ErrorJob("server.couldNotStart") ); } catch (FreeColException e) { reloadMainPanel(); SwingUtilities.invokeLater( new ErrorJob(e.getMessage()) ); } } }; freeColClient.worker.schedule( loadGameJob ); } private void reloadMainPanel () { SwingUtilities.invokeLater(new Runnable() { public void run() { gui.closeMainPanel(); gui.showMainPanel(); gui.playSound("sound.intro.general"); } }); } }