package com.drakulo.games.ais.ui.state;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;
import com.drakulo.games.ais.AloneInSpace;
import com.drakulo.games.ais.core.Colony;
import com.drakulo.games.ais.core.GameData;
import com.drakulo.games.ais.core.GameEngine;
import com.drakulo.games.ais.core.Resource;
import com.drakulo.games.ais.core.ResourceHelper;
import com.drakulo.games.ais.core.Settings;
import com.drakulo.games.ais.core.delayed.HexagonMapAction;
import com.drakulo.games.ais.ui.FontHelper;
import com.drakulo.games.ais.ui.I18n;
import com.drakulo.games.ais.ui.ImageManager;
import com.drakulo.games.ais.ui.UIHelper;
import com.drakulo.games.ais.ui.component.ActionHandler;
import com.drakulo.games.ais.ui.component.ColonySelector;
import com.drakulo.games.ais.ui.component.HexagonMap;
import com.drakulo.games.ais.ui.component.ResourceDisplay;
import com.drakulo.games.ais.ui.component.TransferWindow;
import com.drakulo.games.ais.ui.component.button.ImageButton;
import com.drakulo.games.ais.ui.component.button.TextButton;
import de.matthiasmann.twl.EditField;
import de.matthiasmann.twl.model.SimpleChangableListModel;
public class PlanetState extends GameState {
private static final int PADDING = 5;
private static final int SIDEBAR_WIDTH = ColonySelector.WIDTH + PADDING * 2;
/** The colony selectors */
private List<ColonySelector> colonies;
/** Selected colony */
private Colony selectedColony;
/** The planet exploration map */
private HexagonMap map;
/** The image background */
private Image background;
/** Exploration button */
private ImageButton exploreButton;
/** The access button : jump to the colony */
private ImageButton viewButton;
/** The colonize button */
private ImageButton colonizeButton;
/** The transfer button */
private ImageButton transferButton;
/** The selecting mode flag */
private boolean selecting;
/** Exploration selection */
private boolean explorationSelection;
/** Colonization selecting */
private boolean colonizationSelection;
/** The colony creation window */
private boolean showNewColonyWindow;
/** The button validating colony creation */
private TextButton createColonyButton;
/** The button canceling colony creation */
private TextButton cancelColonyButton;
/** The colony name field */
private EditField colonyNameField;
/** The resource display component */
private ResourceDisplay resources;
/** The transfer window */
private TransferWindow transferWindow;
/** The last colony count */
private int lastColonyCount;
public PlanetState(int id) {
super(id);
}
@Override
public void initState() throws SlickException {
this.colonies = new ArrayList<ColonySelector>();
for (Colony c : GameData.getColonies()) {
this.colonies.add(new ColonySelector(c, getRootPane()));
}
this.map = new HexagonMap(4, 5, 64);
int x = SIDEBAR_WIDTH + (Settings.WIDTH - SIDEBAR_WIDTH) / 2
- this.map.getWidth() / 2;
this.map.setOX(x);
this.map.setOY(Settings.HEIGHT / 2 - this.map.getHeight() / 2);
int i = 0;
for (Colony c : GameData.getColonies()) {
this.map.addColonyAt(c, i);
i++;
}
this.background = ImageManager.getGfx("space_background");
this.exploreButton = new ImageButton("exploration");
this.exploreButton.setTitle(I18n.get("planet.explore_sector"));
this.exploreButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
if (PlanetState.this.selectedColony == null) {
// TODO play error sound
} else {
startZoneSelectionForExploration();
}
}
});
exploreButton.setHoverHandler(new ActionHandler() {
@Override
public void run() {
// Exploration = 2500 Gas
Map<Resource, BigDecimal> costMap = new HashMap<Resource, BigDecimal>();
costMap.put(Resource.GAS, BigDecimal.valueOf(2500));
resources.setMap(costMap);
resources.show();
}
});
add(this.exploreButton);
this.viewButton = new ImageButton("home");
this.viewButton.setTitle(I18n.get("planet.go_to_colony"));
this.viewButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
if (PlanetState.this.selectedColony == null) {
// TODO play error sound
} else {
GameData.setSelectedColony(PlanetState.this.selectedColony);
GameData.getGame().enterState(AloneInSpace.SECTOR_STATE);
}
}
});
add(this.viewButton);
this.colonizeButton = new ImageButton("top_right_expand");
this.colonizeButton.setTitle(I18n.get("planet.colonize"));
this.colonizeButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
if (PlanetState.this.selectedColony == null) {
// TODO play error sound
} else {
// TODO Externalize
Map<Resource, BigDecimal> costMap = new HashMap<Resource, BigDecimal>();
for (Resource r : Resource.values()) {
costMap.put(r, BigDecimal.valueOf(10000));
}
if (ResourceHelper.enoughResourcesFor(costMap)) {
startZoneSelectionForColonization();
} else {
// TODO Play error sound
}
}
}
});
this.colonizeButton.setHoverHandler(new ActionHandler() {
@Override
public void run() {
// Colonization = 10.000 each
Map<Resource, BigDecimal> costMap = new HashMap<Resource, BigDecimal>();
for (Resource r : Resource.values()) {
costMap.put(r, BigDecimal.valueOf(10000));
}
resources.setMap(costMap);
resources.show();
}
});
add(this.colonizeButton);
transferButton = new ImageButton("transfer");
transferButton.setTitle(I18n.get("planet.transfer"));
transferButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
transferWindow.show();
}
});
add(transferButton);
this.showNewColonyWindow = false;
this.createColonyButton = new TextButton(I18n.get("global.ok"));
this.createColonyButton.setWidth(80);
this.createColonyButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
final Colony c = new Colony();
c.setName(PlanetState.this.colonyNameField.getText());
PlanetState.this.colonyNameField.setText("");
try {
c.setMap(new TiledMap("data/testmap.tmx"));
} catch (SlickException e) {
// TODO Handle TiledMap loading in a manager
e.printStackTrace();
}
c.setResource(Resource.CRISTAL, BigDecimal.valueOf(1000));
c.setResource(Resource.ENERGY, BigDecimal.valueOf(1000));
c.setResource(Resource.FOOD, BigDecimal.valueOf(1000));
c.setResource(Resource.GAS, BigDecimal.valueOf(1000));
final int selectedIndex = PlanetState.this.map
.getSelectedZone();
final HexagonMapAction a = new HexagonMapAction(2,
PlanetState.this.map, PlanetState.this.map
.getSelectedZone());
a.setExploration(false);
a.setCallback(new Runnable() {
@Override
public void run() {
GameData.putInPool(c);
PlanetState.this.map.addColonyAt(c, selectedIndex);
// Create the new selector
PlanetState.this.colonies.add(new ColonySelector(c,
getRootPane()));
}
});
GameData.addHexagonMapAction(a);
stopZoneSelection();
PlanetState.this.showNewColonyWindow = false;
}
});
createColonyButton.hide();
add(createColonyButton);
this.cancelColonyButton = new TextButton(I18n.get("global.cancel"));
this.cancelColonyButton.setWidth(80);
this.cancelColonyButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
PlanetState.this.showNewColonyWindow = false;
PlanetState.this.colonizationSelection = false;
}
});
cancelColonyButton.hide();
add(cancelColonyButton);
this.colonyNameField = new EditField();
this.colonyNameField.setVisible(false);
this.getRootPane().add(this.colonyNameField);
if (GameData.getSelectedColony() != null) {
this.selectedColony = GameData.getSelectedColony();
}
// TODO Beaurk! Do this better inside of HexagonMap!
x = map.getOX() + map.getWidth() + 10 + 1;
int y = map.getOY() - 10;
resources = new ResourceDisplay(getRootPane(), x, y);
resources.hide();
transferWindow = new TransferWindow(getRootPane());
lastColonyCount = GameData.getColonies().size();
}
@Override
public void renderState(Graphics g) throws SlickException {
// The background (stars)
g.drawImage(this.background, 0, 0);
// Render UI
UIHelper.drawDarkBox(g, 0, GameState.TOP_BAR_HEIGHT + 1, SIDEBAR_WIDTH,
Settings.HEIGHT - 1 - GameState.TOP_BAR_HEIGHT);
// Render the colony selectors
int y = GameState.TOP_BAR_HEIGHT + PADDING * 2 + 10;
for (ColonySelector cs : this.colonies) {
if (cs == null) {
UIHelper.drawBox(g, PADDING, y, ColonySelector.WIDTH,
ColonySelector.HEIGHT);
continue;
}
final boolean selected = cs.getColony().equals(this.selectedColony);
cs.select(selected);
cs.setOX(PADDING);
cs.setOY(y);
cs.render(g);
y += ColonySelector.HEIGHT + PADDING;
}
// Action buttons background
int width = PADDING * 5 + 4 * ImageButton.IB_DEFAULT_SIZE;
int height = PADDING * 2 + ImageButton.IB_DEFAULT_SIZE;
int x = SIDEBAR_WIDTH + (Settings.WIDTH - SIDEBAR_WIDTH) / 2 - width
/ 2;
y = Settings.HEIGHT / 2 - this.map.getHeight() / 2 - PADDING * 4
- height;
UIHelper.drawBox(g, x, y, width, height);
// Buttons
y += PADDING;
this.viewButton.setPosition(x += PADDING, y);
this.exploreButton.setPosition(x += ImageButton.IB_DEFAULT_SIZE
+ PADDING, y);
this.colonizeButton.setPosition(x += ImageButton.IB_DEFAULT_SIZE
+ PADDING, y);
transferButton.setPosition(x += ImageButton.IB_DEFAULT_SIZE
+ PADDING, y);
this.map.render(g);
if (this.showNewColonyWindow) {
// The colony creation is engaged. The player has to choose a name
// for his new colony
int w = 200;
int h = 95;
x = Settings.WIDTH / 2 - w / 2;
y = Settings.HEIGHT / 2 - h / 2;
UIHelper.drawWindow(g, x, y, w, h, 5);
// The info label
Font font = FontHelper.getFont(FontHelper.HEMI_HEAD, Color.white,
16);
font.drawString(x + 15, y + 15,
FontHelper.firstToUpper(I18n.get("colony.create_label"))
+ " :");
this.cancelColonyButton.setPosition(x + 10, y + 65);
this.createColonyButton.setPosition(x + w - 10
- this.createColonyButton.getWidth(), y + 65);
this.colonyNameField.setVisible(true);
this.colonyNameField.setSize(w - 20, 20);
this.colonyNameField.setPosition(x + 10, y + 35);
} else {
this.colonyNameField.setVisible(false);
}
resources.render(g);
transferWindow.render(g);
}
@Override
public void updateState(Input input, int time) throws SlickException {
// Colony selectors update
for (ColonySelector cs : this.colonies) {
cs.update(input);
}
// Update hovered colony
final int mx = input.getMouseX();
if (mx < SIDEBAR_WIDTH) {
// The mouse is in the sidebar, search for hover
for (ColonySelector cs : this.colonies) {
cs.update(input);
if (cs.isHovered()) {
if (input.isMousePressed(Input.MOUSE_LEFT_BUTTON)) {
// Selected
this.selectedColony = cs.getColony();
}
}
}
}
int colonies = GameData.getColonies().size();
List<HexagonMapAction> actions = GameData.getHexagonMapActions();
for (HexagonMapAction a : actions) {
if (!a.isExploration()) {
colonies++;
}
}
if (colonies == 6) {
// Maximum of 6 colonies per planet (for now)
this.colonizeButton.disable();
}
// The hexamap
this.map.update(input);
if (this.selecting && !showNewColonyWindow) {
// Cancel selecting
if (input.isKeyDown(Input.KEY_ESCAPE)
|| input.isMousePressed(Input.MOUSE_RIGHT_BUTTON)) {
stopZoneSelection();
}
if (this.map.getSelectedZone() != -1) {
if (this.explorationSelection) {
// A zone was selected
// TODO Externalize values
Map<Resource, BigDecimal> costMap = new HashMap<Resource, BigDecimal>();
costMap.put(Resource.GAS, BigDecimal.valueOf(2500));
if (!ResourceHelper.enoughResourcesFor(costMap)) {
// Not enought resources
// TODO Play error sound
} else {
GameData.getSelectedColony().updateResource(
Resource.GAS, BigDecimal.valueOf(-2500));
HexagonMapAction a = new HexagonMapAction(10, this.map,
this.map.getSelectedZone());
GameData.addHexagonMapAction(a);
stopZoneSelection();
}
} else if (this.colonizationSelection) {
this.showNewColonyWindow = true;
}
}
}
if (this.showNewColonyWindow) {
createColonyButton.show();
cancelColonyButton.show();
} else {
createColonyButton.hide();
cancelColonyButton.hide();
}
resources.update(input);
resources.hide();
if(lastColonyCount != GameData.getColonies().size()){
// New colonies were created, the lists must be updated
lastColonyCount = GameData.getColonies().size();
transferWindow.reloadList();
}
transferWindow.update(input);
// Game logic update
GameEngine.run(time);
}
private void startZoneSelectionForExploration() {
this.selecting = true;
this.explorationSelection = true;
this.colonizationSelection = false;
this.map.setSelectingMode(true, false);
}
private void startZoneSelectionForColonization() {
this.selecting = true;
this.colonizationSelection = true;
this.explorationSelection = false;
this.map.setSelectingMode(true, true);
}
private void stopZoneSelection() {
this.selecting = false;
this.explorationSelection = true;
this.colonizationSelection = false;
this.map.setSelectingMode(false, false);
}
}