/* This file is part of CivQuest.
*
* CivQuest 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.
*
* CivQuest 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 CivQuest; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: DetailedUnitInfoComponent.java 606 2005-06-29 08:07:39Z wpausch $
*/
package civquest.swing.panes.unitComp;
import civquest.core.GameDataAccessor;
import civquest.damage.Damagable;
import civquest.gameChange.GameChangeException;
import civquest.gameChange.GameChangeListener;
import civquest.gameChange.RulesetGameChangeLoader;
import civquest.io.Messages;
import civquest.map.MapObjectReader;
import civquest.map.UnitReader;
import civquest.map.gameChange.SetMapObjectHealth;
import civquest.map.mapobj.MapObject;
import civquest.nation.RestrictedToNation;
import civquest.parser.ruleset.Ruleset;
import civquest.parser.ruleset.Section;
import civquest.units.gameChange.UnitChange;
import civquest.units.models.Musketeer;
import civquest.util.ref.MethodCallerException;
import civquest.util.ref.OPMethodCaller;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
/**
*/
public class DetailedUnitInfoComponent extends JComponent implements GameChangeListener {
private GameDataAccessor gameData;
private Long unitID = null;
private static OPMethodCaller<Boolean, MapObject, DetailPainter> detailCaller = null;
private DetailPainter detailPainter = new DetailPainter();
private static final int WIDTH = 250;
public DetailedUnitInfoComponent(Ruleset ruleset) {
setPreferredSize(new Dimension(WIDTH, 100));
try {
if (detailCaller == null) {
detailCaller = new OPMethodCaller<Boolean, MapObject, DetailPainter>
("draw", null, MapObject.class, DetailPainter.class);
}
} catch (MethodCallerException e) {
Messages.getMessages().err("DetailedUnitInfoComponent", "Problem when setting up "
+ "detailCaller: " + e);
Messages.getMessages().err("DetailedUnitInfoComponent", "CivQuest will abort NOW!");
System.exit(-1);
}
try {
Section listenerSection = ruleset.getSection("listens");
RulesetGameChangeLoader.addListener(listenerSection, this);
} catch (Exception e) {
Messages.getMessages().err("DetailedUnitInfoComponent", "Problem when setting up "
+ "listeners: " + e);
Messages.getMessages().err("DetailedUnitInfoComponent", "CivQuest will abort NOW!");
System.exit(-1);
}
}
public void newData(GameDataAccessor gameData) {
this.gameData = gameData;
repaint();
}
public void setUnit(Long unitID) {
this.unitID = unitID;
repaint();
}
public void paintComponent(Graphics g) {
if (unitID == null) {
g.drawString("No unit", 10, 10);
} else {
int y = 10;
g.drawString("Information about unit " + unitID, 10, y);
y += 15;
drawUnitName(g, unitID, 10, y);
y += 15;
drawRemainingTime(g, unitID, 10, y);
y += 15;
drawHealth(g, unitID, 10, y, WIDTH);
y += 25;
drawDetailInformation(g, unitID, 10, y, WIDTH);
}
}
private void drawUnitName(Graphics g, Long unitID, int x, int y) {
if (gameData.getMapObjectReader().isMapObjectModelNameAvailable(unitID)) {
String modelName = gameData.getMapObjectReader().getMapObjectModelName(unitID);
g.drawString(modelName, x, y);
} else {
g.drawString("Model-name not known", x, y);
}
}
private void drawRemainingTime(Graphics g, Long unitID, int x, int y) {
if (gameData.getMapObjectReader().isMapObjectTimeAvailable(unitID)) {
int time = gameData.getMapObjectReader().getMapObjectTime(unitID);
g.drawString("Remaining time: " + time, x, y);
} else {
g.drawString("Remaining time not known", x, y);
}
}
private void drawHealth(Graphics g, Long unitID, int x, int y, int width) {
MapObjectReader moReader = gameData.getMapObjectReader();
if (moReader.isMapObjectHealthAvailable(unitID)) {
double health = moReader.getMapObjectHealth(unitID);
float healthPercentile = (float)(health);
g.drawString("Health: " + (int)(healthPercentile * 100) + "%", x, y);
int barX = x + 90;
int barY = y - 8;
int rightBarX = width - 15;
// int barWidth = (int)(healthPercentile * (rightBarX - barX));
int barWidth = rightBarX - barX;
int barHeight = 5;
drawHealthBar(g, barX, barY, barWidth, barHeight, healthPercentile);
} else {
g.drawString("Health not known", x, y);
}
}
private static void drawHealthBar(Graphics g, int x, int y, int width, int height,
float healthPercentile) {
if (healthPercentile >= 0 && healthPercentile <= 1) {
Color color;
if (healthPercentile < 0.5) {
color = new Color(1, 2 * healthPercentile, 0);
} else {
color = new Color((float)(1 - 2 * (healthPercentile - 0.5)), 1, 0);
}
g.setColor(color);
g.fillRect(x, y, (int)(healthPercentile * (float)width), height);
}
g.setColor(Color.BLACK);
g.drawRect(x, y, width, height);
}
private void drawDetailInformation(Graphics g, Long unitID,
int x, int y, int width) {
MapObjectReader moReader = gameData.getMapObjectReader();
if (moReader.asMapObjectAvailable(unitID)) {
MapObject mo = moReader.getAsMapObject(unitID);
detailPainter.set(g, x, y, mo);
try {
detailCaller.callV(detailPainter, mo);
} catch (MethodCallerException e) {
Messages.getMessages().err("DetailedUnitInfoComponent", "Problem with "
+ "detailCaller: " + e);
Messages.getMessages().err("DetailedUnitInfoComponent",
"CivQuest will abort NOW!");
System.exit(-1);
}
} else {
g.drawString("Details unknown", x, y);
}
}
public static class DetailPainter {
private int x;
private int y;
private Graphics g;
private MapObject mo;
private void set(Graphics g, int x, int y, MapObject mo) {
this.x = x;
this.y = y;
this.g = g;
this.mo = mo;
}
public void draw(MapObject mo) {
g.drawString("Drawing special information for this", x, y);
g.drawString("type of unit not yet implemented!", x, y + 15);
}
public void draw(Musketeer musketeer) {
g.drawString("A musketeer", x, y);
}
}
public int getWidth() {
return WIDTH;
}
public void afterGameChanged(UnitChange unitChange) {
repaint();
}
public void afterGameChanged(SetMapObjectHealth setMOH) {
repaint();
}
public RestrictedToNation[] getResToNations() {
return new RestrictedToNation[] {gameData.getRestrictedToNation()};
}
/*
private static class SummaryUnitPartVisitor implements UnitPartVisitor {
private int x, y;
private int width;
private Graphics g;
public void set(Graphics g, int x, int y, int width) {
this.g = g;
this.x = x;
this.y = y;
this.width = width;
}
public void visitDefaultAttackManager(DefaultAttackManager defaultAttackManager) {
g.setColor(Color.GRAY);
g.drawRect(x, y, (width - 10 - x), 20);
g.setColor(Color.BLACK);
g.drawString("DefaultAttackManager", x + 5, y + 15);
int barX = x + 160;
drawHealthBar(g, barX, y + 7, width - 15 - barX, 5,
(float)defaultAttackManager.getHealth());
y += 20;
}
public void visitHumanEngine(HumanEngine humanEngine) {
g.setColor(Color.GRAY);
g.drawRect(x, y, (width - 10 - x), 20);
g.setColor(Color.BLACK);
g.drawString("HumanEngine", x + 5, y + 15);
int barX = x + 160;
drawHealthBar(g, barX, y + 7, width - 15 - barX, 5,
(float)humanEngine.getHealth());
y += 20;
}
public void visitGun(Gun gun) {
g.setColor(Color.GRAY);
g.drawRect(x, y, (width - 10 - x), 20);
g.setColor(Color.BLACK);
g.drawString("Gun", x + 5, y + 15);
int barX = x + 160;
drawHealthBar(g, barX, y + 7, width - 15 - barX, 5,
(float)gun.getHealth());
y += 20;
}
}
*/
}