/** * 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.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.logging.Logger; import org.freecolandroid.repackaged.java.awt.Graphics2D; import org.freecolandroid.repackaged.java.awt.image.BufferedImage; import org.freecolandroid.repackaged.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.action.MapControlsAction; import net.sf.freecol.client.gui.i18n.Messages; import net.sf.freecol.client.gui.panel.MapEditorTransformPanel.MapTransform; import net.sf.freecol.client.gui.panel.MiniMap; import net.sf.freecol.common.FreeColException; 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; MapControlsAction mca = (MapControlsAction) freeColClient.getActionManager() .getFreeColAction(MapControlsAction.id); if (mca.getMapControls() != null) { mca.getMapControls().update(mt); } } /** * 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.getActionManager().update(); 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(FreeCol.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"), true); Thread t = new Thread(FreeCol.CLIENT_THREAD+"Saving Map") { @Override public void run() { try { // create thumbnail MiniMap miniMap = new MiniMap(freeColClient, gui); miniMap.setTileSize(MiniMap.MAX_TILE_SIZE); int width = freeColClient.getGame().getMap().getWidth() * MiniMap.MAX_TILE_SIZE + MiniMap.MAX_TILE_SIZE/2; int height = freeColClient.getGame().getMap().getHeight() * MiniMap.MAX_TILE_SIZE / 4; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = image.createGraphics(); miniMap.paintMap(g2d, width, height); // TODO: this can probably done more efficiently // by applying a suitable AffineTransform to the // Graphics2D double scaledWidth = Math.min((64 * width) / height, 128); BufferedImage scaledImage = new BufferedImage((int) scaledWidth, 64, BufferedImage.TYPE_INT_ARGB); scaledImage.createGraphics().drawImage(image, 0, 0, (int) scaledWidth, 64, null); 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(FreeCol.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"), true); 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.getActionManager().update(); 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"); } }); } }