package rts.core.engine.ingamegui;
import java.awt.Point;
import java.util.ArrayList;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import rts.core.engine.Engine;
import rts.core.engine.GameSound;
import rts.core.engine.Player;
import rts.core.engine.Utils;
import rts.core.engine.layers.entities.ActiveEntity;
import rts.core.engine.layers.entities.EData;
import rts.core.engine.layers.entities.EntityGenerator;
import rts.core.engine.layers.entities.MoveableEntity;
import rts.core.engine.layers.entities.buildings.Building;
import rts.core.engine.layers.entities.buildings.BuildingECreator;
import rts.core.engine.layers.entities.others.Wall;
import rts.utils.Colors;
import rts.utils.Timer;
public class GuiButton {
private static final Color TRANS_CYAN = new Color(51, 51, 102, 200);
private static final Color TRANS = new Color(255, 255, 255, 100);
private static final int BLINK_TIME = 300;
private static final int TIME_BEFORE_MOUSEOVER = 1000;
private GuiPanel panel;
private Engine engine;
private Building building;
private ArrayList<int[]> enableCombination;
private ArrayList<CreateEntityProcess> processList;
private Timer blinkTimer;
private Timer mouseOverTimer;
private String name;
private String price;
private Image image;
private int x;
private int y;
private int width;
private int height;
private boolean enable;
private boolean visible; // not sure what visible is
private boolean tabButton;
private boolean limitAtOne;
private boolean blink;
private boolean alwaysEnable;
private int entType;
private int diX;
private int diY;
public GuiButton(Engine engine, Image image, int x, int y) {
this.image = image;
this.x = x;
this.y = y;
this.width = image.getWidth();
this.height = image.getHeight();
this.engine = engine;
this.processList = new ArrayList<CreateEntityProcess>();
this.enableCombination = new ArrayList<int[]>();
this.entType = -1;
this.blinkTimer = new Timer(BLINK_TIME);
this.mouseOverTimer = new Timer(TIME_BEFORE_MOUSEOVER);
}
public void clear() {
processList.clear();
blinkTimer.resetTime();
mouseOverTimer.resetTime();
if (!alwaysEnable)
enable = false;
visible = false;
blink = false;
}
public void addEnableCombination(int[] combination) {
enableCombination.add(combination);
}
public void launchCreateEntityProcess() {
if (!processList.isEmpty()) {
if (processList.get(0).ready) {
building = (Building) EntityGenerator.createActiveEntityNoNetwork(engine, entType, 0, 0);
} else {
if (processList.get(0).pause) {
processList.get(0).pause = false;
} else {
panel.addButtonToWait(this);
if (!limitAtOne)
processList.add(new CreateEntityProcess());
}
}
} else if(enable) {
GameSound.construction();
panel.addButtonToWait(this);
processList.add(new CreateEntityProcess());
}
}
public boolean isMouseOver(int mx, int my) {
if (tabButton || (!tabButton && visible))
return ((mx > x && mx < x + width) && (my > y && my < y + height));
else
return false;
}
private boolean isMouseOver() {
return isMouseOver(engine.getContainer().getInput().getMouseX(), engine.getContainer().getInput().getMouseY());
}
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
public void checkCancelProcess() {
if (engine.isMouseRightPressed() && isMouseOver()) {
if (enable) {
if (!processList.isEmpty()) {
if (processList.get(0).pause || processList.get(0).ready) {
if (processList.size() > 1) {
processList.get(1).advancement = processList.get(0).advancement;
if (processList.get(0).pause)
processList.get(1).pause = true;
} else {
engine.getPlayer().addMoney(processList.get(0).advancement);
}
processList.remove(0);
building = null;
} else {
if (!processList.get(0).pause) {
processList.get(0).pause = true;
} else {
processList.remove(0);
building = null;
}
}
}
}
}
}
public void blink(int delta) {
blinkTimer.update(delta);
if (blinkTimer.isTimeComplete()) {
blink = !blink;
blinkTimer.resetTime();
}
}
public void resetBlink() {
if (blink) {
blinkTimer.resetTime();
blink = false;
}
}
public void render(GameContainer container, Graphics g) {
if (enable) {
if (blink) {
g.drawImage(image, x, y, TRANS);
} else {
g.drawImage(image, x, y);
}
} else {
g.drawImage(image, x, y, TRANS);
}
if (!processList.isEmpty()) {
g.setColor(Color.red);
CreateEntityProcess process = processList.get(0);
g.fillRect(x + 2, y + 51, (56 * process.advancement) / process.price, 7);
if (process.pause) {
g.drawString("Pause", x + 10, y + 15);
} else {
if (process.ready) {
g.drawString("Ready", x + 10, y + 15);
}
}
g.drawString("" + processList.size(), x + 3, y + 1);
}
if (building != null) {
building.renderLocationOnMap(container, g);
}
}
public void renderInfo(GameContainer container, Graphics g) {
if (isMouseOver() && mouseOverTimer.isTimeComplete()) {
g.setColor(TRANS_CYAN);
if (diX == -1 && diY == -1) {
diX = container.getInput().getMouseX();
diY = container.getInput().getMouseY();
}
if (tabButton) {
if (diX + name.length() > container.getWidth()) {
diX -= name.length();
}
g.fillRect(diX, diY, name.length() * 10, 20);
g.setColor(Color.black);
g.drawRect(diX, diY, name.length() * 10, 20);
g.setColor(Color.white);
g.drawString(name, diX + 2, diY);
} else {
int w = (name.length() > price.length() ? name.length() : price.length()) * 10;
if (diX + w > container.getWidth()) {
diX -= w;
}
g.fillRect(diX, diY, w, 60);
g.setColor(Color.black);
g.drawRect(diX, diY, w, 60);
g.setColor(Color.white);
g.drawString(name, diX + 2, diY);
g.setColor(Colors.GOLD);
g.drawString(price, diX + 2, diY + 20);
g.setColor((engine.getPlayer().getTecLevel() >= EData.TEC_LEVEL[entType] ? Color.cyan : Color.red));
g.drawString("Level: " + (EData.TEC_LEVEL[entType] + 1), diX + 2, diY + 40);
}
}
}
public boolean hasProcessReady() {
if (!processList.isEmpty()) {
return processList.get(0).ready;
}
return false;
}
public boolean update(int delta) {
if (visible && engine.isMouseLeftPressed()) {
int x = engine.getMouseX() / engine.getTileW();
int y = engine.getMouseY() / engine.getTileH();
System.out.println("buildIng at coor" + x + ", " + y);
if (building != null && building.isValidLocation(x, y)) {
Player player = engine.getPlayer();
if (engine.isNetwork()) {
if (building instanceof Wall) {
ArrayList<Point> a = ((Wall) building).getOthersValidLocation();
for (int i = 0; i < a.size(); i++) {
engine.getNetworkManager().sendCreateEntity(entType, player.getId(), player.getTeamId(), a.get(i).x * engine.getTileW(),
a.get(i).y * engine.getTileH());
}
}
engine.getNetworkManager().sendCreateEntity(entType, player.getId(), player.getTeamId(), x * engine.getTileW(), y * engine.getTileH());
} else {
ActiveEntity ae = EntityGenerator.createActiveEntityNoNetwork(engine, entType, player.getId(), player.getTeamId());
ae.setLocation(x * engine.getTileW(), y * engine.getTileH());
if (ae instanceof BuildingECreator) {
((BuildingECreator) ae).checkPrimary();
} else {
if (ae instanceof Wall) {
ArrayList<Point> a = ((Wall) ae).getOthersValidLocation();
for (int i = 0; i < a.size(); i++) {
ActiveEntity w = EntityGenerator.createActiveEntityNoNetwork(engine, entType, player.getId(), player.getTeamId());
w.setLocation(a.get(i).x * engine.getTileW(), a.get(i).y * engine.getTileH());
engine.addEntity(w);
}
}
}
engine.addEntity(ae);
// Special case type = refinery = + 1 collector
if (entType == EData.BUILDING_REFINERY) {
Point p2 = Utils.getCloserPoint(engine.getMap(), x, y);
if (p2 != null) {
ae = EntityGenerator.createActiveEntityNoNetwork(engine, EData.MOVER_COLLECTOR, player.getId(), player.getTeamId());
ae.setLocation(p2.x * engine.getTileW(), p2.y * engine.getTileH());
engine.addEntity(ae);
}
}
}
engine.getGui().addEntityToBuildingList(entType);
processList.remove(0);
building = null;
}
} else {
if (engine.isMouseRightPressed()) {
building = null;
}
}
return checkProcess(delta);
}
// Modeled after update(delta) function above
public boolean placeBuilding(int x, int y) {
// first check to see if we can build a building
if (processList.size() > 0 && processList.get(0).ready) {
building = (Building) EntityGenerator.createActiveEntityNoNetwork(engine, entType, 0, 0);
}
// visible checked to see if you were on the correct panel,
// but i don't really care about what panel i'm on anymore,
// i just need to build the building.
// this is why i didn't include boolean visible in this check
if (building != null && building.checkValidPlacement(x, y)) {
Player player = engine.getPlayer();
if (engine.isNetwork()) {
if (building instanceof Wall) {
ArrayList<Point> a = ((Wall) building).getOthersValidLocation();
for (int i = 0; i < a.size(); i++) {
engine.getNetworkManager().sendCreateEntity(entType, player.getId(), player.getTeamId(), a.get(i).x * engine.getTileW(),
a.get(i).y * engine.getTileH());
}
}
engine.getNetworkManager().sendCreateEntity(entType, player.getId(), player.getTeamId(), x * engine.getTileW(), y * engine.getTileH());
} else {
ActiveEntity ae = EntityGenerator.createActiveEntityNoNetwork(engine, entType, player.getId(), player.getTeamId());
ae.setLocation(x * engine.getTileW(), y * engine.getTileH());
if (ae instanceof BuildingECreator) {
((BuildingECreator) ae).checkPrimary();
} else {
if (ae instanceof Wall) {
ArrayList<Point> a = ((Wall) ae).getOthersValidLocation();
for (int i = 0; i < a.size(); i++) {
ActiveEntity w = EntityGenerator.createActiveEntityNoNetwork(engine, entType, player.getId(), player.getTeamId());
w.setLocation(a.get(i).x * engine.getTileW(), a.get(i).y * engine.getTileH());
engine.addEntity(w);
}
}
}
engine.addEntity(ae);
// Special case type = refinery = + 1 collector
if (entType == EData.BUILDING_REFINERY) {
Point p2 = Utils.getCloserPoint(engine.getMap(), x, y);
if (p2 != null) {
ae = EntityGenerator.createActiveEntityNoNetwork(engine, EData.MOVER_COLLECTOR, player.getId(), player.getTeamId());
ae.setLocation(p2.x * engine.getTileW(), p2.y * engine.getTileH());
engine.addEntity(ae);
}
}
}
engine.getGui().addEntityToBuildingList(entType);
processList.remove(0);
building = null;
return true;
}
// if we tried to place a building but failed, then deselect the building we are trying to place
building = null;
return false;
}
private boolean checkProcess(int delta) {
if (!processList.isEmpty()) {
processList.get(0).update(delta);
if (processList.get(0).complete()) {
// CREATE ENTITY
if (EData.isBuilding(entType)) {
// Building
if (!processList.get(0).ready) {
processList.get(0).ready = true;
GameSound.buildingReady();
}
} else {
// Mover
ArrayList<Building> buildings = engine.getPlayerBuilding();
int[] possibilities = EData.BUILDING_PLACE[entType];
boolean find = false;
for (int i = 0; i < possibilities.length; i++) {
for (int j = 0; j < buildings.size(); j++) {
if (buildings.get(j).getType() == possibilities[i] && ((BuildingECreator) buildings.get(j)).isPrimary()) {
Building b = buildings.get(j);
Point p = Utils.getCloserPoint(engine.getMap(), (int) b.getX() / engine.getTileW(), (int) b.getY() / engine.getTileH());
Point rp = null;
if (b instanceof BuildingECreator) {
rp = ((BuildingECreator) b).getRallyingPoint();
}
Player player = engine.getPlayer();
if (engine.isNetwork()) {
if (rp != null) {
engine.getNetworkManager().sendCreateEntity(entType, player.getId(), player.getTeamId(), rp.x, rp.y,
p.x * engine.getTileW(), p.y * engine.getTileH());
} else {
engine.getNetworkManager().sendCreateEntity(entType, player.getId(), player.getTeamId(), p.x * engine.getTileW(),
p.y * engine.getTileH());
}
} else {
ActiveEntity ae = EntityGenerator.createActiveEntityNoNetwork(engine, entType, player.getId(), player.getTeamId());
ae.setLocation(p.x * engine.getTileW(), p.y * engine.getTileH());
engine.addEntity(ae);
if (ae instanceof MoveableEntity && rp != null) {
Point pt = Utils.getCloserPoint(engine.getMap(), rp.x / engine.getTileW(), rp.y / engine.getTileH());
((MoveableEntity) ae).move(pt.x * engine.getTileW(), pt.y * engine.getTileH());
}
}
GameSound.unitReady();
find = true;
break;
}
}
if (find)
break;
}
processList.remove(0);
}
}
return false;
} else
return true;
}
public void checkEnable(ArrayList<Integer> buildingList, int delta, boolean visible) {
this.visible = visible;
if (!alwaysEnable) {
boolean hasBuildingNeeded = true;
for (int i = 0; i < enableCombination.size(); i++) {
int[] comb = enableCombination.get(i);
hasBuildingNeeded = true;
for (int j = 0; j < comb.length; j++) {
if (!buildingList.contains(new Integer(comb[j]))) {
hasBuildingNeeded = false;
break;
}
}
if (hasBuildingNeeded)
break;
}
if (enable) {
if (limitAtOne) {
if (!hasBuildingNeeded || buildingList.contains(new Integer(entType))) {
setEnable(false);
processList.clear();
}
} else {
if (!hasBuildingNeeded) {
setEnable(false);
processList.clear();
}
}
} else {
// No enable
if (limitAtOne) {
if (hasBuildingNeeded && !buildingList.contains(new Integer(entType)) && engine.getPlayer().getTecLevel() >= EData.TEC_LEVEL[entType]) {
setEnable(true);
}
} else {
if (hasBuildingNeeded) {
if (tabButton) {
setEnable(true);
} else {
if (entType != -1 && engine.getPlayer().getTecLevel() >= EData.TEC_LEVEL[entType]) {
setEnable(true);
}
}
}
}
}
}
// Show info timer
if (isMouseOver()) {
mouseOverTimer.update(delta);
} else {
diX = -1;
diY = -1;
mouseOverTimer.resetTime();
}
}
public ArrayList<CreateEntityProcess> getProcessList() {
return processList;
}
public void setImage(Image image) {
this.image = image;
}
public void setEntType(int entType) {
this.entType = entType;
this.name = EData.NAMES[entType];
this.price = "Price: " + EData.PRICE[entType] + "$";
}
public void setName(String name) {
this.name = name;
}
public boolean isEnable() {
return enable;
}
private void setEnable(boolean enable) {
this.enable = enable;
}
public void setPanel(GuiPanel panel) {
this.panel = panel;
}
public void setTabButton(boolean tabButton) {
this.tabButton = tabButton;
}
public void setLimitAtOne(boolean limitAtOne) {
this.limitAtOne = limitAtOne;
}
public void setAlwaysEnable(boolean alwaysEnable) {
this.alwaysEnable = alwaysEnable;
this.enable = alwaysEnable;
}
private class CreateEntityProcess {
private Timer timer;
private int price;
private int advancement;
private boolean pause;
private boolean ready;
public CreateEntityProcess() {
timer = new Timer(80);
price = EData.PRICE[entType];
}
public void update(int delta) {
if (!pause && !complete()) {
timer.update(delta);
if (timer.isTimeComplete()) {
if (engine.getPlayer().removeMoney(5)) {
advancement += 5;
GameSound.build();
} else {
GameSound.insiffucientFunds();
}
timer.resetTime();
}
}
}
public boolean complete() {
return advancement == price;
}
}
}