package vooga.towerdefense.gameeditor.gamemaker.editorscreens.mapeditor;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import vooga.towerdefense.gameeditor.controller.GameEditorController;
import vooga.towerdefense.gameeditor.gamemaker.editorscreens.GameEditorScreen;
import vooga.towerdefense.model.tiles.factories.TileFactory;
import vooga.towerdefense.util.Pixmap;
/**
* The MapEditorScreen is responsible for helping
* the game developer make maps. It contains three components: a JTextArea where
* the game developer specifies the size of each tile; a panel with the different
* types of tiles that the developer can drag into the map area; and a panel where
* the developer actually places their map on.
*
* @author Angelica Schwartz
* @author Leonard K. Ng'eno
*/
public class MapEditorScreen extends GameEditorScreen {
private static final long serialVersionUID = 1L;
private static final String NEXT_SCREEN_NAME = "PlayerEditorScreen";
private static final String TITLE_NAME = "MAP ";
private static final String TILE_IMAGES_CLASS_PATH = "vooga/towerdefense/images/map";
private static final String TILE_PACKAGE_PATH = "vooga.towerdefense.model.tiles.factories";
private static final Dimension TILE_PANEL_SIZE = new Dimension(500, 100);
private static final String USER_DIR = "user.dir";
private static final String DEFAULT_TILE_SIZE = "50";
private MapMakerScreen myMapMakerBox;
private Dimension myMapMakerSize;
private JTextField myTileSizeTextField;
private JTextField myMapNameTextField;
private final int FIELD_SIZE = 10;
private ActionListener myActionListener;
private MouseAdapter myMouseListener;
private int myTileSize;
private TilePanel myTilePainter;
private TileFactory myTileFactoryToBuild;
private List<String> myBackgroundImages;
private List<TileFactory> myTileFactories;
private String myBackgroundImageName;
private String myMapName;
private JButton myBackgroundImageButton;
private JFileChooser myChooser;
private JButton myMapNameButton;
private TileFactoryLoader myLoader;
/**
* Constructor.
*
* @param size size of the map editor screen
* @param controller the game editor controller
*/
public MapEditorScreen (Dimension size, GameEditorController controller) {
super(size, controller, TITLE_NAME, NEXT_SCREEN_NAME);
makeListeners();
initVariables();
addComponentsToScreen();
addMouseListener(myMouseListener);
myBackgroundImageButton.addMouseListener(myMouseListener);
myMapNameButton.addMouseListener(myMouseListener);
setVisible(true);
}
/**
* initialize variables used
*/
private void initVariables () {
myTileSize = 50;
myMapMakerSize = getController().getMapSize();
myBackgroundImages = new ArrayList<String>();
myBackgroundImageButton = new JButton("BACKGROUND IMAGE");
myMapNameButton = new JButton("ENTER NAME");
myChooser = new JFileChooser(System.getProperties().getProperty(USER_DIR));
myLoader = new TileFactoryLoader(getController());
}
/**
* adds various components to screen and aligns them
*/
private void addComponentsToScreen () {
add(makeMapBox(myMapMakerSize), BorderLayout.CENTER);
add(makeLabelText("TILE SIZE"), BorderLayout.WEST);
add(makeTileTextField(), BorderLayout.WEST);
add(myMapNameButton, BorderLayout.EAST);
add(makeMapNameTextField(), BorderLayout.WEST);
add(makePathTilePainter(), BorderLayout.SOUTH);
add(myBackgroundImageButton, BorderLayout.SOUTH);
}
/**
* Creates a text field for inputting the name of the game
*
* @return JTextField
*/
private JComponent makeMapNameTextField () {
myMapNameTextField = new JTextField(FIELD_SIZE);
myMapNameTextField.addActionListener(myActionListener);
myMapNameTextField.setVisible(true);
return myMapNameTextField;
}
/**
* Creates a JPanel where the map is built
*
* @param size size of the map
* @return JPanel that the map is built on
*/
private JPanel makeMapBox (Dimension size) {
myMapMakerBox = new MapMakerScreen(size);
return myMapMakerBox;
}
/**
* Creates a JTextField for changing the tile size
*
* @return text field area
*/
private JTextField makeTileTextField () {
myTileSizeTextField = new JTextField(FIELD_SIZE);
myTileSizeTextField.setText(DEFAULT_TILE_SIZE);
myTileSizeTextField.addActionListener(myActionListener);
myTileSizeTextField.setVisible(true);
return myTileSizeTextField;
}
private void makeListeners () {
myActionListener = new ActionListener() {
@Override
public void actionPerformed (ActionEvent e) {
if (e.getSource().equals(myMapNameTextField)) {
setMapName();
}
else if (e.getSource().equals(myTileSizeTextField)) {
resetTileSize();
}
}
};
myMouseListener = new MouseAdapter() {
@Override
public void mouseClicked (MouseEvent e) {
if (e.getSource().equals(myBackgroundImageButton)) {
int response = myChooser.showOpenDialog(null);
if (response == JFileChooser.APPROVE_OPTION) {
File file = myChooser.getSelectedFile();
String path = file.getName();
myBackgroundImageName = path;
myMapMakerBox.setBackgroundImage(myBackgroundImageName);
}
}
else if (e.getSource().equals(myMapNameButton)) {
setMapName();
}
}
};
}
private void setMapName () {
myMapName = myMapNameTextField.getText();
if (myMapName.isEmpty()) {
JOptionPane.showMessageDialog(null, "NAME MUST BE AT LEAST ONE CHARACTER!");
}
else {
myMapNameTextField.setText("");
}
}
private JLabel makeLabelText (String text) {
return new JLabel(text);
}
private void resetTileSize () {
myTileSize = Integer.parseInt(myTileSizeTextField.getText());
myMapMakerBox.setTileSizes(myTileSize);
myTileSizeTextField.setText("");
}
/**
* override the default Java Graphics paintComponent method
*/
@Override
public void paintComponent (Graphics pen) {
super.paintComponent(pen);
}
/**
* adds this map to the game.
*/
@Override
public void addElementToGame () {
getController().addMapToGame(getMapName(), getBackgroundImagePath(),
myMapMakerBox.getMapWidth(), myMapMakerBox.getMapHeight(),
getTileSize(), myMapMakerBox.getMapString());
}
private JPanel makePathTilePainter () {
File[] images = myLoader.getImages(TILE_IMAGES_CLASS_PATH);
List<Pixmap> myImages = new ArrayList<Pixmap>();
myImages = makeTileImages(images);
myTileFactories = myLoader.initTileFactories(TILE_PACKAGE_PATH);
myTilePainter = new TilePanel(TILE_PANEL_SIZE, myImages, this);
return myTilePainter;
}
/**
* Method called by the TilePanel with the type of the tile that the developer has
* clicked on.
*
* @param s string representing the tile that the developer clicked on.
*/
public void makeTileInstances (String s) {
for (TileFactory tile : myTileFactories) {
if (tile.getName().equals(s)) {
myTileFactoryToBuild = tile;
}
}
myMapMakerBox.setTile(myTileFactoryToBuild);
}
private List<Pixmap> makeTileImages (File[] file) {
List<Pixmap> images = new ArrayList<Pixmap>();
for (File f : file) {
images.add(new Pixmap("/" + TILE_IMAGES_CLASS_PATH + "/" + f.getName()));
myBackgroundImages.add("/" + TILE_IMAGES_CLASS_PATH + "/" + f.getName());
}
return images;
}
@Override
public void addAdditionalMouseBehavior (MouseEvent e) {
}
/**
* get the name of the map
*
* @return name of the map
*/
public String getMapName () {
return myMapName;
}
/**
* get the path of the background image
*
* @return string representing the path of the background image
*/
public String getBackgroundImagePath () {
return myMapMakerBox.getBackgroundImageName();
}
/**
*
* @return the size of each tile in the map
*/
public String getTileSize () {
return Integer.toString(myTileSize);
}
}