package ch.sahits.game.graphic.display.dialog;
import java.awt.Color;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import ch.sahits.game.event.EViewChangeEvent;
import ch.sahits.game.event.Event;
import ch.sahits.game.event.IEventListener;
import ch.sahits.game.event.KeyPressEvent;
import ch.sahits.game.event.MouseClickEvent;
import ch.sahits.game.event.ViewChangeEvent;
import ch.sahits.game.graphic.display.gameplay.MainView;
import ch.sahits.game.graphic.display.model.CityPlayerProxy;
import ch.sahits.game.graphic.display.notice.NoticeView;
import ch.sahits.game.graphic.display.util.ClickablePolygons;
import ch.sahits.game.graphic.image.DisplayImageDIResolver;
import ch.sahits.game.graphic.image.IImageLoader;
import ch.sahits.game.graphic.image.IOpenPatricianPainter;
import ch.sahits.game.graphic.image.model.NamedPolygon;
import ch.sahits.game.image.IImageUtilities;
import ch.sahits.game.openpatrician.model.Date;
import ch.sahits.game.openpatrician.model.IBalanceSheet;
import ch.sahits.game.openpatrician.model.building.IBuilding;
import ch.sahits.game.openpatrician.model.building.ITownHouse;
import ch.sahits.game.openpatrician.model.building.ITradingOffice;
import ch.sahits.game.openpatrician.model.building.IWorkShop;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.rendering.RenderablePart;
public class TradingOfficeBalanceDialog extends OpenPatricianGameDialog implements IEventListener, RenderablePart{
/** reference to the utilities for image manipulation */
private IImageUtilities imageUtils;
private IOpenPatricianPainter opPainter;
private boolean enabled = true;
private ClickablePolygons footerPolygons;
/** Hold all the positioning information, initialized in initBackgroundImage */
private DialogPositions positions;
public TradingOfficeBalanceDialog(Point topLeft, double scale,
CityPlayerProxy cityProxy) {
super(topLeft, DisplayImageDIResolver.getInstance().getMainScreenLoader(), scale, cityProxy);
Event.add(this);
}
@Override
protected void init() {
DisplayImageDIResolver resolver = DisplayImageDIResolver.getInstance();
opPainter = resolver.getOpenPatricianPainter();
imageUtils = resolver.getImageUtilities();
super.init();
}
@Override
protected void initiatePolygons() {
footerPolygons = new ClickablePolygons();
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean flag) {
enabled=flag;
}
@Override
public void gameUpdate(Event e, Object notice) {
if (e instanceof KeyPressEvent){
KeyEvent key= ((KeyPressEvent)e).getKey();
if (key.getKeyCode()==KeyEvent.VK_ESCAPE){
new ViewChangeEvent(MainView.class).notify(EViewChangeEvent.CLOSE_DIALOG);
new ViewChangeEvent(NoticeView.class).notify(EViewChangeEvent.NOTICE_HIDE);
Event.remove(this);
}
}
if (e instanceof MouseClickEvent){
footerPolygons.testAndExecute((Point) notice);
}
}
/**
* Draw the table header
* @param g2d
* @param y position of the table header baseline
* @throws FontFormatException
* @throws IOException
*/
private void drawTableHeader(Graphics2D g2d,final int y) throws FontFormatException, IOException{
Date date = Date.getInstance(0); // TODO very ugly solution
GlyphVector gv = opPainter.createGlyphVector(g2d, date.getStartOfWeek()+" to "+date.getEndOfWeek(), 19); // TODO externalize
int x = positions.lastWeek+50-(int)Math.rint(gv.getVisualBounds().getWidth());
g2d.drawGlyphVector(gv, x, y);
String columnTitle = "Forecast";
gv = opPainter.createGlyphVector(g2d, columnTitle, 19);
g2d.drawGlyphVector(gv, positions.forecast, y);
}
/**
* Draw a text string at a defined position. The Y-position is passed as an argument, updated for the next row
* and returned. The X-coordinate is computed from the left border argument and the visual length of the text string
* @param g2d Graphic context
* @param y position
* @param leftBorder left inset
* @param text to be drawn
* @return updated y coordinate
* @throws FontFormatException
* @throws IOException
*/
private int drawRow(Graphics2D g2d, int y,int leftBorder, String text) throws FontFormatException, IOException{
y += positions.lineHeight;
GlyphVector gv = opPainter.createGlyphVector(g2d, text, 18);
int x = leftBorder-(int)Math.rint(gv.getVisualBounds().getWidth());
g2d.drawGlyphVector(gv, x, y);
return y;
}
@Override
protected BufferedImage initBackgroundImage(IImageLoader loader,Point topLeft) {
BufferedImage bg = super.initBackgroundImage(loader,topLeft);
Graphics2D g2d = bg.createGraphics();
g2d.setColor(Color.BLACK);
try {
GlyphVector gv = opPainter.createGlyphVector(g2d, "Balance", 24); // TODO externalize
double titleHeight = gv.getVisualBounds().getHeight();
int length = (int) Math.rint(gv.getVisualBounds().getWidth());
int x = ((bg.getWidth()-getInset().left-getInset().right)-length)/2;
int y = getInset().top+10+(int)Math.rint(titleHeight*2/3);
g2d.drawGlyphVector(gv, x, y);
// Dynamic row
y += titleHeight;
y += (int)Math.rint(titleHeight*2/3);
BufferedImage waxSeal = loader.getImage("waxseal");
int leftBorderX = topLeft.x+getInset().left;
int firstColumn = leftBorderX+120; // right aligned
int lastWeek = leftBorderX+200;
int forecast = leftBorderX+300;
int secondcolumn = leftBorderX+150;
int thirdColumn = leftBorderX+200;
int forthColumn = leftBorderX+280;
int fifthColumn = leftBorderX+330;
int yLineDiff = waxSeal.getHeight();
// Initialize the position relative to the frame
positions = new DialogPositions(titleHeight, yLineDiff, lastWeek, forecast, secondcolumn, thirdColumn, forthColumn,fifthColumn);
leftBorderX = getInset().left; // Use local coordinates
firstColumn = leftBorderX+120; // right aligned
// table header
y += positions.lineHeight; // more space to the title
y += positions.lineHeight;
y += positions.lineHeight;
y += positions.lineHeight;
// Table
// Rental income
y = drawRow(g2d, y, firstColumn, "Rental income");
// wages
y = drawRow(g2d, y, firstColumn, "Wage costs");
// tax
y = drawRow(g2d, y, firstColumn, "Property tax");
// office trading
y = drawRow(g2d, y, firstColumn, "Office trading");
// steward
y = drawRow(g2d, y, firstColumn, "Steward");
// other
y = drawRow(g2d, y, firstColumn, "Other");
// sum
y += positions.lineHeight;
y += positions.lineHeight;
gv = opPainter.createGlyphVector(g2d, "Sum", 18);
x = firstColumn-(int)Math.rint(gv.getVisualBounds().getWidth());
g2d.drawGlyphVector(gv, x, y);
y += positions.lineHeight;
y += positions.lineHeight;
// Buildings
y = drawRow(g2d, y, firstColumn, "Buildings");
// workshops
y = drawRow(g2d, y, firstColumn, "Workshops");
// Tenement
y = drawRow(g2d, y, firstColumn, "Tenements");
// Footer buttons
y = bg.getHeight()-getInset().bottom-positions.lineHeight;
x = getInset().left+30;
int footerWidth = bg.getWidth()-getInset().left-getInset().right-2*30;
x += 3*footerWidth/4;
// close
g2d.drawImage(waxSeal, x,y-(int)(positions.lineHeight*0.8), null);
NamedPolygon polygon = new NamedPolygon("Close");
polygon.addPoint(topLeft.x+x, topLeft.y+y-(int)(positions.lineHeight*0.8));
polygon.addPoint(topLeft.x+x+waxSeal.getWidth(), topLeft.y+y-(int)(positions.lineHeight*0.8));
polygon.addPoint(topLeft.x+x+waxSeal.getWidth(), topLeft.y+y-(int)(positions.lineHeight*0.8)+waxSeal.getHeight());
polygon.addPoint(topLeft.x+x, topLeft.y+y-(int)(positions.lineHeight*0.8)+waxSeal.getHeight());
footerPolygons.add(polygon, new CloseAction(this));
g2d.setColor(new Color(0xEA,0xC1,0x17)); // Gold
gv = opPainter.createGlyphVector(g2d, "X", 18);
int xPadding = imageUtils.computeCenterAlignX(x, waxSeal.getWidth(), (int)gv.getVisualBounds().getWidth());
g2d.drawGlyphVector(gv, xPadding, y); // centeralign
} catch (FontFormatException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return bg;
}
@Override
public void gameRender(Graphics gScr) {
Color oldColor = gScr.getColor();
super.gameRender(gScr);
gScr.setColor(Color.BLACK);
Graphics2D g2d = (Graphics2D) gScr;
try {
// Dialog title
int y = getBounds().y+getInset().top+10+(int)Math.rint(positions.titleHeigth*2/3);
final BufferedImage coin = loader.getImage("coin_icon");
// Sub title
y += positions.titleHeigth;
ICity cityModel = city.getCity();
y += (int)Math.rint(positions.titleHeigth*2/3);
// Table header
y += positions.lineHeight; // more space to the title
y += positions.lineHeight;
drawTableHeader(g2d, y);
y += positions.lineHeight;
y += positions.lineHeight;
y += positions.lineHeight;
// TODO fill in the data
ITradingOffice office = city.getPlayer().findTradingOffice(cityModel);
drawRentalIncome(g2d,office,coin,y);
y += positions.lineHeight;
drawWageCosts(g2d,office,coin,y);
y += positions.lineHeight;
drawPropertyTax(g2d,office,coin,y);
y += positions.lineHeight;
drawOfficeTradeing(g2d,office,coin,y);
y += positions.lineHeight;
drawStewardCosts(g2d,office,coin,y);
y += positions.lineHeight;
drawOtherCosts(g2d,office,coin,y);
y += positions.lineHeight;
y += positions.lineHeight;
drawBalanceSum(g2d,office,coin,y);
y += positions.lineHeight;
y += positions.lineHeight;
y += positions.lineHeight;
y += positions.lineHeight; // Buildings
// Workshops
List<IBuilding> buidlings = city.getPlayer().findBuildings(cityModel, IWorkShop.class);
int amount = buidlings.size();
int people = 0;
int maxPeople = 0;
for (IBuilding building : buidlings) {
people += ((IWorkShop)building).getWorkers();
maxPeople += ((IWorkShop)building).getMaxWorkers();
}
drawBalanceRow(g2d, y, amount, people, maxPeople, "Workers"); // TODO externalize
y += positions.lineHeight;
buidlings = city.getPlayer().findBuildings(cityModel, ITownHouse.class);
amount = buidlings.size();
people = 0;
maxPeople = 0;
for (IBuilding building : buidlings) {
people += ((ITownHouse)building).getOccupancy();
maxPeople += ((ITownHouse)building).getCapacity();
}
drawBalanceRow(g2d, y, amount, people, maxPeople, "Tenants"); // TODO externalize
// Tenament
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
gScr.setColor(oldColor);
}
private void drawBalanceRow(Graphics2D g2d, int y, int amount, int people,
int maxPeople, String label) throws FontFormatException, IOException {
int xPadding = positions.secondcolumn;
GlyphVector gv = opPainter.createGlyphVector(g2d, String.valueOf(amount), 18);
g2d.drawGlyphVector(gv, xPadding, y);
xPadding = positions.thirdColumn;
gv = opPainter.createGlyphVector(g2d, label, 18);
g2d.drawGlyphVector(gv, xPadding, y);
xPadding = positions.forthColumn;
gv = opPainter.createGlyphVector(g2d, String.valueOf(people), 18);
g2d.drawGlyphVector(gv, xPadding, y);
xPadding = positions.fifthColumn;
gv = opPainter.createGlyphVector(g2d, "(max. "+maxPeople+")", 18); // TODO externalize
g2d.drawGlyphVector(gv, xPadding, y);
}
/**
* Draw the balance line summing up
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws FontFormatException
* @throws IOException
*/
private void drawBalanceSum(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
int lastWeek =0;
IBalanceSheet bal = office.getBalanceLastWeek();
lastWeek += bal.getOtherCosts() + bal.getPropertyTaxes() + bal.getStewardCost() + bal.getWageCosts();
lastWeek -= (bal.getOfficeTrading() + bal.getRentalIncome());
int forcast = 0;
bal = office.getCurrentWeek();
forcast += bal.getOtherCosts() + bal.getPropertyTaxes() + bal.getStewardCost() + bal.getWageCosts();
forcast -= (bal.getOfficeTrading() + bal.getRentalIncome());
drawBalanceRow(g2d, coin, y, lastWeek, forcast);
}
/**
* Draw the balance line for other costs
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws IOException
* @throws FontFormatException
*/
private void drawOtherCosts(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
drawBalanceRow(g2d, coin, y, office.getBalanceLastWeek().getOtherCosts(), office.getCurrentWeek().getOtherCosts());
}
/**
* Draw the balance line for the steward costs
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws FontFormatException
* @throws IOException
*/
private void drawStewardCosts(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
drawBalanceRow(g2d, coin, y, office.getBalanceLastWeek().getStewardCost(), office.getCurrentWeek().getStewardCost());
}
/**
* Draw the balance line for the office traiding
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws IOException
* @throws FontFormatException
*/
private void drawOfficeTradeing(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
drawBalanceRow(g2d, coin, y, office.getBalanceLastWeek().getOfficeTrading(), office.getCurrentWeek().getOfficeTrading());
}
/**
* Draw the balance line for the property taxes
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws FontFormatException
* @throws IOException
*/
private void drawPropertyTax(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
drawBalanceRow(g2d, coin, y, office.getBalanceLastWeek().getPropertyTaxes(), office.getCurrentWeek().getPropertyTaxes());
}
/**
* Draw the balance line for the wage costs
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws FontFormatException
* @throws IOException
*/
private void drawWageCosts(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
drawBalanceRow(g2d, coin, y, office.getBalanceLastWeek().getWageCosts(), office.getCurrentWeek().getWageCosts());
}
/**
* Draw the balance line for the rental income
* @param g2d Graphic context
* @param office Trading office instance
* @param coin image
* @param y position
* @throws FontFormatException
* @throws IOException
*/
private void drawRentalIncome(Graphics2D g2d, ITradingOffice office,
BufferedImage coin, int y) throws FontFormatException, IOException {
drawBalanceRow(g2d, coin, y, office.getBalanceLastWeek().getRentalIncome(), office.getCurrentWeek().getRentalIncome());
}
/**
* Draw the balance line with the last weeks values and the forcast values
* @param g2d Graphic context
* @param coin image
* @param y position
* @param lastWeek value of the last week
* @param forcaset valeu forcast of the current week
* @throws FontFormatException
* @throws IOException
*/
private void drawBalanceRow(Graphics2D g2d, BufferedImage coin, int y, int lastWeek, int forcaset) throws FontFormatException, IOException{
int xPadding = positions.lastWeek;
GlyphVector gv = opPainter.createGlyphVector(g2d, String.valueOf(lastWeek), 18);
g2d.drawGlyphVector(gv, xPadding, y);
g2d.drawImage(coin, (int)(xPadding+gv.getVisualBounds().getWidth())+5, y-positions.lineHeight*2/3, null);
xPadding = positions.forecast;
gv = opPainter.createGlyphVector(g2d, String.valueOf(forcaset), 18);
g2d.drawGlyphVector(gv, xPadding, y);
g2d.drawImage(coin, (int)(xPadding+gv.getVisualBounds().getWidth())+5, y-positions.lineHeight*2/3, null);
}
/**
* This class holds the positions where different elements are
* placed on the dialog.
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Dec 9, 2011
*
*/
private static class DialogPositions{
private final double titleHeigth;
private final int lineHeight;
private final int lastWeek;
private final int forecast;
private final int secondcolumn;
private final int thirdColumn;
private final int forthColumn;
private final int fifthColumn;
public DialogPositions(double titleHeigth, int lineHeight,
int lastWeek, int forecast, int secondcolumn,
int thirdColumn, int forthColumn, int fifthColumn) {
super();
this.titleHeigth = titleHeigth;
this.lineHeight = lineHeight;
this.lastWeek = lastWeek;
this.forecast = forecast;
this.secondcolumn = secondcolumn;
this.thirdColumn = thirdColumn;
this.forthColumn = forthColumn;
this.fifthColumn = fifthColumn;
}
}
}