package com.drakulo.games.ais.ui.component.window;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import com.drakulo.games.ais.core.GameData;
import com.drakulo.games.ais.core.Resource;
import com.drakulo.games.ais.core.building.BuildingCategory;
import com.drakulo.games.ais.core.building.BuildingHelper;
import com.drakulo.games.ais.core.building.BuildingLevelData;
import com.drakulo.games.ais.core.building.BuildingType;
import com.drakulo.games.ais.core.delayed.BuildingAction;
import com.drakulo.games.ais.core.delayed.PreparationAction;
import com.drakulo.games.ais.core.io.BuildingIO;
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.MultilineLabel;
import com.drakulo.games.ais.ui.component.UIComponent;
import com.drakulo.games.ais.ui.component.button.Button;
import com.drakulo.games.ais.ui.component.button.ImageButton;
import com.drakulo.games.ais.ui.state.SectorState;
import de.matthiasmann.twl.Label;
public class BuildWindow extends UIComponent {
/** Basic padding used in the window */
private static final int PADDING = 5;
/** Industrial buildings buttons */
private List<Button> buttons;
/** Special handling for the command center button */
private Button cmButton;
/** The play state */
private SectorState parent;
/** Flag indicating if the command center is built */
private boolean commandCenterBuilt;
/** The building description label */
private MultilineLabel descLabel;
/** Hover flag to trigger data zone cleaning */
private boolean hoverFlag;
/** Resource costs */
Map<Resource, BigDecimal> costMap;
Map<Resource, BigDecimal> earnMap;
/** The resource labels */
private Map<Resource, Label> costLabels;
private Map<Resource, Label> earnLabels;
/** Cost title */
private Label costLabel;
/** Income title */
private Label earnLabel;
/**
* Constructor
*
* @param parent
* - the parent GameState
* @param width
* - the window width
* @param height
* - the window height
* @param ox
* - the window w coordinate
* @param oy
* - the window y coordinate
*/
public BuildWindow(SectorState parent, int width, int height, int ox, int oy) {
this.setOX(ox);
this.setOY(oy);
this.setWidth(width);
this.setHeight(height);
this.parent = parent;
this.buttons = new ArrayList<Button>();
// Creating buttons
final int pitch = ImageButton.IB_DEFAULT_SIZE + 2;
final int initialX = getOX() + 10;
final int initialY = getOY() + 10;
int x = initialX;
int y = initialY;
// Industrial buildings
x = initialX;
List<BuildingType> types = BuildingType
.values(BuildingCategory.INDUSTRIAL);
for (BuildingType type : types) {
Button button = createBuildingButton(type);
button.setPosition(x, y);
buttons.add(button);
x += pitch;
}
// Civil buildings
x = initialX;
y += ImageButton.IB_DEFAULT_SIZE + 15;
types = BuildingType.values(BuildingCategory.CIVIL);
for (BuildingType type : types) {
Button button = createBuildingButton(type);
button.setPosition(x, y);
if (BuildingType.COMMAND_CENTER.equals(type)) {
cmButton = button;
cmButton.enable();
if (GameData.getSelectedColony().isCommandCenterBuilt()) {
// Only 1 command center
button.disable();
}
} else if (BuildingType.RESEARCH_CENTER.equals(type)
&& GameData.getSelectedColony().isResearchCenterBuilt()) {
// Only 1 research center
button.disable();
}
buttons.add(button);
x += pitch;
}
// Terrabot
ImageButton terrabotButton = new ImageButton("terrabot", x, y);
terrabotButton.setTitle(I18n.get("terrabot"));
terrabotButton.disable();
terrabotButton.setActionHandler(new ActionHandler() {
@Override
public void run() {
PreparationAction pa = BuildingHelper.create(GameData
.getSelectedColony());
BuildWindow.this.parent.setSelectedAction(pa);
hide();
}
});
terrabotButton.setHoverHandler(new ActionHandler() {
@Override
public void run() {
String desc = I18n.get("terrabot.desc");
Map<Resource, BigDecimal> costMap = new HashMap<Resource, BigDecimal>();
// TODO Externalize this
costMap.put(Resource.ENERGY, BigDecimal.valueOf(25));
displayBuildingData(desc, costMap);
hoverFlag = true;
}
});
parent.add(terrabotButton);
buttons.add(terrabotButton);
y += ImageButton.IB_DEFAULT_SIZE + 25;
x = getOX() + PADDING * 2;
descLabel = new MultilineLabel("");
descLabel.hide();
descLabel.setPosition(x, y);
descLabel.setSize(getWidth() - 4 * PADDING, 50);
parent.add(descLabel);
costLabels = new HashMap<Resource, Label>();
earnLabels = new HashMap<Resource, Label>();
for (Resource r : Resource.values()) {
Label lc = new Label();
lc.setTheme("resourceLabel");
lc.setSize(80, 15);
parent.add(lc);
costLabels.put(r, lc);
Label le = new Label();
le.setTheme("resourceLabel");
le.setSize(80, 15);
parent.add(le);
earnLabels.put(r, le);
}
costLabel = new Label(I18n.get("global.cost"));
costLabel.setSize(width / 2, 20);
costLabel.setVisible(false);
costLabel.setTheme("resourceLabel");
parent.add(costLabel);
earnLabel = new Label(I18n.get("global.income"));
earnLabel.setVisible(false);
earnLabel.setSize(width / 2, 20);
earnLabel.setTheme("resourceLabel");
parent.add(earnLabel);
}
/**
* Create a generic building button for the given building type
*
* @param type
* - the building type
* @return the created button
*/
private Button createBuildingButton(final BuildingType type) {
// Load the building cost
BuildingLevelData data = BuildingIO.getBuildingData(type).getLevelData(
0);
final Map<Resource, BigDecimal> costMap = data.getUpgradeCost();
// Create the button
ImageButton button = new ImageButton(type.toString());
button.setTitle(I18n.get(type.getI18n()));
// Set the build action
button.setActionHandler(new ActionHandler() {
@Override
public void run() {
BuildingAction ba = BuildingHelper.createAction(
GameData.getSelectedColony(), type, costMap);
parent.setSelectedAction(ba);
hide();
}
});
// Set the hover action
button.setHoverHandler(new ActionHandler() {
@Override
public void run() {
final String desc = I18n.get(type.getDescI18n());
displayBuildingData(desc, costMap);
hoverFlag = true;
BuildingLevelData data = BuildingIO.getBuildingData(type)
.getLevelData(0);
BuildWindow.this.costMap = data.getUpgradeCost();
earnMap = data.getProduction();
}
});
button.disable();
button.hide();
parent.add(button);
return button;
}
/**
* Displays a building type data in the data zone. Called on hover for all
* action buttons
*
* @param name
* - the building name
* @param desc
* - the building description
* @param costMap
* - the build action cost map
*/
private void displayBuildingData(String desc,
Map<Resource, BigDecimal> costMap) {
descLabel.setText(desc);
// TODO
}
/**
* Handle command center construction flag
*
* @param built
* - the command center construction flag
*/
public void setCommandCenterBuilt(boolean built) {
if (commandCenterBuilt == built) {
return;
}
commandCenterBuilt = built;
for (Button b : buttons) {
if (built) {
b.enable();
} else {
b.disable();
}
}
if (built) {
cmButton.disable();
} else {
cmButton.enable();
}
}
@Override
public void render(Graphics g) throws SlickException {
if (!isShown()) {
return;
}
final int btnZoneHeight = ImageButton.IB_DEFAULT_SIZE + 2 * PADDING;
int x = getOX();
int y = getOY();
// The background for buttons
UIHelper.drawBox(g, x, y, getWidth(), getHeight());
// First zone : Industrial buildings
UIHelper.drawDarkBox(g, x += PADDING, y += PADDING, getWidth() - 2
* PADDING, btnZoneHeight);
// Second zone : Civil / Robots
y += btnZoneHeight + PADDING;
UIHelper.drawDarkBox(g, x, y, getWidth() - 2 * PADDING, btnZoneHeight);
// The rendering of the buttons is handled by the GameState
// Render of data zone
y += btnZoneHeight + PADDING;
int height = getHeight() - (y - getOY()) - PADDING;
UIHelper.drawDarkBox(g, x, y, getWidth() - 2 * PADDING, height);
// The resources cost / earn
Resource[] resources = Resource.values();
Image img;
y += btnZoneHeight + 25;
final int sx = getOX() + getWidth() / 2 - 100;
x = sx;
costLabel.setPosition(getOX() - 25, y - 25);
earnLabel.setPosition(getOX() + costLabel.getWidth() - 25, y - 25);
for (Resource r : resources) {
UIHelper.drawDarkBox(g, x, y += 3, 24, 20);
img = ImageManager.getGfx(r.getGfxBase() + "-small");
img.draw(x + 3, y, r.getColor());
String costValue = "";
if (costMap != null) {
costValue = costMap.get(r).toString();
}
Label lbl = this.costLabels.get(r);
final int zoneHeight = 15;
UIHelper.drawDarkBox(g, x + 24, y, lbl.getWidth() + 4, zoneHeight);
lbl.setPosition(x + 24, y);
lbl.setText(costValue);
lbl.setVisible(true);
x += lbl.getWidth() + 15;
String earnValue = "";
if (costMap != null) {
earnValue = earnMap.get(r).toString();
}
Label costLbl = this.earnLabels.get(r);
UIHelper.drawDarkBox(g, x + 24, y, costLbl.getWidth() + 4,
zoneHeight);
costLbl.setPosition(x + 24, y);
costLbl.setText(earnValue);
costLbl.setVisible(true);
y += 20;
x = sx;
}
}
@Override
public void update(Input input) throws SlickException {
hoverFlag = false;
for (Button b : buttons) {
b.update(input);
if (isShown()) {
b.show();
} else {
b.hide();
}
}
if (!hoverFlag) {
descLabel.setText("");
Resource[] resources = Resource.values();
for (Resource r : resources) {
costLabels.get(r).setText("");
earnLabels.get(r).setText("");
}
costMap = null;
}
}
@Override
public void show() {
super.show();
if (descLabel != null) {
descLabel.show();
costLabel.setVisible(true);
earnLabel.setVisible(true);
}
displayLabels(true);
}
@Override
public void hide() {
super.hide();
if (descLabel != null) {
descLabel.hide();
costLabel.setVisible(false);
earnLabel.setVisible(false);
}
displayLabels(false);
}
/**
* Shows or hide cost / earn labels
*
* @param show
* - true to show labels, false to hide them
*/
private void displayLabels(boolean show) {
for (Resource r : Resource.values()) {
costLabels.get(r).setVisible(show);
earnLabels.get(r).setVisible(show);
}
}
}