package ch.sahits.game.graphic.display.notice;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.apache.log4j.Logger;
import ch.sahits.game.event.EViewChangeEvent;
import ch.sahits.game.event.Event;
import ch.sahits.game.event.IEventListener;
import ch.sahits.game.event.MouseClickEvent;
import ch.sahits.game.event.ViewChangeEvent;
import ch.sahits.game.graphic.display.dialog.ETransferDialogType;
import ch.sahits.game.graphic.display.dialog.TradeDialog;
import ch.sahits.game.graphic.display.gameplay.MainView;
import ch.sahits.game.graphic.display.model.ICityPlayerProxy;
import ch.sahits.game.graphic.display.model.ViewChangeCityPlayerProxy;
import ch.sahits.game.graphic.display.util.ClickableOffsetPolygons;
import ch.sahits.game.graphic.display.util.ClickablePolygons;
import ch.sahits.game.graphic.image.DisplayImageDIResolver;
import ch.sahits.game.graphic.image.IFontLoader;
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.openpatrician.model.building.ITradingOffice;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.openpatrician.model.ship.IConvoy;
import ch.sahits.game.openpatrician.model.ship.IShip;
import ch.sahits.game.rendering.AbstractRenderPart;
/**
* This represents the notice view
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Sep 30, 2011
*
*/
public class NoticeView extends AbstractRenderPart implements IEventListener {
private static final Logger logger = Logger.getLogger(NoticeView.class);
private final IOpenPatricianPainter opPainter;
private final IFontLoader fontLoader;
/** Offset that is scrolled with one click on the scroll bar */
private static final int SCROLL_OFFSET = 15;
private final BufferedImage scrollUp;
private final BufferedImage scrollDown;
/** Full notice, not all may be visible */
private BufferedImage fullNotice;
/**
* Offset indicating how far the fullNotice is scrolled down.
* The value is always positive. Zero indicates no scroll
*/
private int noticeOffset = 0;
/** height of the font in size 18 */
private final int font18Height;
/** Polygons of the scrollbar */
private final ClickablePolygons polygons = new ClickablePolygons();
/** Polygons in the fullNotice image */
private ClickableOffsetPolygons offsetPolys = new ClickableOffsetPolygons();
/**
* Data object that corresponds to the rendered data in {@link #fullNotice}.
* The meta data provide the necessairy informations to process updates in the
* notice.
*/
private INoticeMetaData metaData = null;
public NoticeView(Rectangle rect,IImageLoader loader) {
super(rect);
scrollUp = loader.getImage("scrollUp");
scrollDown = loader.getImage("scrollDown");
DisplayImageDIResolver resolver = DisplayImageDIResolver.getInstance();
fontLoader =resolver.getFontLoader();
opPainter = resolver.getOpenPatricianPainter();
int size;
try {
GlyphVector gv = opPainter.createGlyphVector((Graphics2D)scrollDown.getGraphics(), "8ypg", fontLoader.createDefaultFont(18));
size = (int)Math.ceil(gv.getVisualBounds().getHeight());
} catch (Exception e) {
logger.warn("Error initializing font", e);
size = 35;
}
font18Height=size;
initPolygons();
Event.add(this);
}
/**
* Initialize common polygons
*/
private void initPolygons() {
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int x =bounds.x+bounds.width-scrollDown.getWidth()-insets.right;
int y = bounds.y+insets.top;
NamedPolygon poly = new NamedPolygon("scrollUp");
poly.addPoint(x, y);
poly.addPoint(x+scrollUp.getWidth(), y);
poly.addPoint(x+scrollUp.getWidth(), y+scrollUp.getHeight());
poly.addPoint(x, y+scrollUp.getHeight());
polygons.add(poly, new ScrollUpAction());
y = getBounds().y+bounds.height-insets.bottom-scrollDown.getHeight();
poly = new NamedPolygon("scrollDown");
poly.addPoint(x, y);
poly.addPoint(x+scrollDown.getWidth(), y);
poly.addPoint(x+scrollDown.getWidth(), y+scrollDown.getHeight());
poly.addPoint(x, y+scrollDown.getHeight());
polygons.add(poly, new ScrollDownAction());
}
@Override
public void gameRender(Graphics gScr) {
Color oldColor = gScr.getColor();
// gScr.drawImage(img, getBounds().x, getBounds().y, null);
// gScr.setColor(Color.MAGENTA);
// gScr.fillRect(rect.x, rect.y, rect.width, rect.height);
gScr.setColor(ColorProvider.getStringColorActive());
drawNotice(gScr);
drawScrollBar(gScr);
gScr.setColor(oldColor);
}
/**
* Draw the scrollbar only if needed
* @param gScr
*/
private void drawScrollBar(Graphics gScr) {
if (needsScrollBar()){
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int x =bounds.x+bounds.width-scrollDown.getWidth()-insets.right;
int y = bounds.y+insets.top;
gScr.drawImage(scrollUp, x, y, null);
y = getBounds().y+bounds.height-insets.bottom-scrollDown.getHeight();
gScr.drawImage(scrollDown, x, y, null);
}
}
/**
* Insets for the notice board
* @return
*/
public Insets getInsets(){
return new Insets(9, 0, 15, 0);
}
/**
* Draw the visible part of the notice image
* @param gScr
*/
private void drawNotice(Graphics gScr) {
if (fullNotice!=null){
Rectangle bounds = getBounds();
// Insets insets = getInsets();
// FIXME draw the correct portion of the full image
// final int drawWidth = fullNotice.getWidth();
// final int drawHeight = bounds.height-insets.top-insets.bottom;
// // Define the destination area
// final int dx1 = bounds.x+insets.left; // top left x position
// final int dx2 = bounds.x+insets.left+drawWidth; // bottom right x position
// final int dy1 = bounds.y+insets.top; // top left y position
// final int dy2 = bounds.y+insets.top+drawHeight; // bottom right y position
// // define the source area
// final int sx1 = 0;
// final int sx2 = fullNotice.getWidth();
// final int sy1 = noticeOffset;
// final int sy2 = fullNotice.getHeight()+noticeOffset;
// gScr.drawImage(fullNotice, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
gScr.drawImage(fullNotice, bounds.x, bounds.y, null);
}
}
@Override
public void gameUpdate(Event e, Object notice) {
if (e instanceof MouseClickEvent){
polygons.testAndExecute((Point) notice);
if (fullNotice!=null){
offsetPolys.testAndExecute((Point) notice, noticeOffset);
}
}
if (e instanceof ViewChangeEvent){
ViewChangeEvent event = (ViewChangeEvent) e;
if (event.getAddresse()==NoticeView.class){
if (notice instanceof EViewChangeEvent){
if (notice==EViewChangeEvent.NOTICE_HIDE){
resetNoticeView();
}
} else if (notice instanceof ViewChangeCityPlayerProxy){
ViewChangeCityPlayerProxy n = (ViewChangeCityPlayerProxy) notice;
if (n.getViewChangeEvent()==EViewChangeEvent.NOTICE_TRADE){
try {
createTradeNotice(n);
} catch (Exception e1) {
logger.error("Could not create notice for trade dialog", e1);
}
} else if (n.getViewChangeEvent()==EViewChangeEvent.NOTICE_MARKET_BOOTH){
try {
createMarketBoothNotice(n);
} catch (Exception e1){
logger.error("Could not create notice for market booth dialog", e1);
}
} else if (n.getViewChangeEvent()==EViewChangeEvent.NOTICE_TRADING_OFFICE){
try {
createTradingOfficeNotice(n);
} catch (Exception e1){
logger.error("Could not create notice for trading office", e1);
}
}
} // end instanteof ViewChangeCityPlayerProxy
} // end addressee == this
} // end ViewChangeEvent
}
/**
* Reset the notice view and other affiliated members
*/
private void resetNoticeView() {
fullNotice=null;
noticeOffset=0;
offsetPolys = new ClickableOffsetPolygons();
}
/**
* Initialize the full notice with the market boot notice
* @param n
* @throws IOException
* @throws FontFormatException
*/
private void createMarketBoothNotice(ViewChangeCityPlayerProxy n) throws FontFormatException, IOException {
metaData = new MarketBoothDialogMetaData(n, EStringSelectionState.ACTIVE, EStringSelectionState.INACTIVE);
creatOrUpdateMarketBoothNotice();
}
/**
* Initialize the full notice with the trading office
* @param n
* @throws IOException
* @throws FontFormatException
*/
private void createTradingOfficeNotice(ViewChangeCityPlayerProxy proxy) throws FontFormatException, IOException {
EStringSelectionState inact = EStringSelectionState.INACTIVE;
metaData = new TradingOfficeDialogMataData(proxy, EStringSelectionState.ACTIVE, inact, inact, inact, inact, EStringSelectionState.DISABLE);
createOrUpdateTradingOfficeNotice();
}
/**
* Initialize the full notice with the trade notice
* @throws IOException
* @throws FontFormatException
*/
private void createTradeNotice(ICityPlayerProxy proxy) throws FontFormatException, IOException {
ICity city = proxy.getCity();
ITradingOffice office = proxy.getPlayer().findTradingOffice(city);
IShip ship = proxy.getActiveShip();
boolean city2ShipFlag = proxy.getActiveShip()!=null; // if true this is active
boolean hasTradingOffice = office!=null;
boolean hasWeapons = (city2ShipFlag&&hasTradingOffice&&office.hasWeapons()&&ship.getUpgradeSpaceReduction()>0&&ship.hasWeapons());
EStringSelectionState city2ship;
if (city2ShipFlag){
city2ship = EStringSelectionState.ACTIVE;
} else if (proxy.getPlayersShips().isEmpty()){
// no active ship => disable
city2ship = EStringSelectionState.DISABLE;
} else {
// there are ships but none is active
city2ship = EStringSelectionState.INACTIVE;
}
EStringSelectionState city2office;
if (hasTradingOffice && city2ShipFlag){
// traiding office and active ship
city2office=EStringSelectionState.INACTIVE;
} else {
// no trading office or no active ships
city2office=EStringSelectionState.DISABLE;
}
EStringSelectionState office2ship;
if (hasTradingOffice && !proxy.getPlayersShips().isEmpty() && !city2ShipFlag){
// trading office and ships but none active
office2ship = EStringSelectionState.ACTIVE;
} else if (hasTradingOffice && city2ShipFlag){
// traiding office and active ship
office2ship=EStringSelectionState.INACTIVE;
} else {
// no trading office or no ships
office2ship=EStringSelectionState.DISABLE;
}
EStringSelectionState weapons;
if (hasWeapons && city2ShipFlag){
// weapons and active ship
weapons=EStringSelectionState.INACTIVE;
} else {
// no trading office or no active ships
weapons=EStringSelectionState.DISABLE;
}
metaData = new TradeDialogMetaData(city2ship, office2ship, city2office, weapons, proxy);
createOrUpdateTradeNotice();
}
/**
* Create or update the trading office notice based on the meta data object
* @throws IOException
* @throws FontFormatException
*/
private void createOrUpdateTradingOfficeNotice() throws FontFormatException, IOException {
final int lineSpacing = font18Height/2;
final int topOffset = 50;
// figure the dimensions out
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int width = bounds.width-insets.left-insets.right;
final int height = topOffset+6*font18Height+5*lineSpacing; // 6 lines
offsetPolys = new ClickableOffsetPolygons();
fullNotice = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = (Graphics2D) fullNotice.getGraphics();
g2d.setColor(ColorProvider.getStringColor(((TradingOfficeDialogMataData)metaData).balance));
Font font =fontLoader.createDefaultFont(18);
font = font.deriveFont(Font.BOLD);
String s = "Balance sheet"; // TODO externalize
GlyphVector gv = opPainter.createGlyphVector(g2d, s, font);
int x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
int y = insets.top+topOffset+2/3*font18Height;
g2d.drawGlyphVector(gv, x, y);
if (((TradingOfficeDialogMataData)metaData).balance!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"BalanceDialog",new TradingOfficeChangeAction(ENoticeItem.TO_BALANCE));
}
s = "Personal"; // TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.setColor(ColorProvider.getStringColor(((TradingOfficeDialogMataData)metaData).personal));
g2d.drawGlyphVector(gv, x, y);
if (((TradingOfficeDialogMataData)metaData).personal!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"PersonalDialog",new TradingOfficeChangeAction(ENoticeItem.TO_PERSONAL));
}
s = "Consumtion/Production"; // TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.setColor(ColorProvider.getStringColor(((TradingOfficeDialogMataData)metaData).consumtionProduction));
g2d.drawGlyphVector(gv, x, y);
if (((TradingOfficeDialogMataData)metaData).consumtionProduction!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"ConsumptionProductionDialog",new TradingOfficeChangeAction(ENoticeItem.TO_CONSUMPTION_PRODUCTION));
}
s = "Weapons"; // TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.setColor(ColorProvider.getStringColor(((TradingOfficeDialogMataData)metaData).weapons));
g2d.drawGlyphVector(gv, x, y);
if (((TradingOfficeDialogMataData)metaData).weapons!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"WeaponsDialog",new TradingOfficeChangeAction(ENoticeItem.TO_WEAPONS));
}
s = "Warehouses"; // TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.setColor(ColorProvider.getStringColor(((TradingOfficeDialogMataData)metaData).warehouses));
g2d.drawGlyphVector(gv, x, y);
if (((TradingOfficeDialogMataData)metaData).warehouses!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"WarehouseDialog",new TradingOfficeChangeAction(ENoticeItem.TO_WAREHOUSES));
}
s = "Storage Manager/Trading"; // TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.setColor(ColorProvider.getStringColor(((TradingOfficeDialogMataData)metaData).storageManager));
logger.debug("Draw string '"+s+"' at "+x+","+y);
g2d.drawGlyphVector(gv, x, y);
if (((TradingOfficeDialogMataData)metaData).storageManager!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"OfficeTraidingDialog",new TradingOfficeChangeAction(ENoticeItem.TO_OFFICE_TRADING));
}
}
/**
* Create or update the market booth notice based on the meta data object
* @throws IOException
* @throws FontFormatException
*/
private void creatOrUpdateMarketBoothNotice() throws FontFormatException, IOException {
final int lineSpacing = font18Height/2;
final int topOffset = 50;
// figure the dimensions out
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int width = bounds.width-insets.left-insets.right;
final int height = topOffset+2*font18Height+1*lineSpacing;
offsetPolys = new ClickableOffsetPolygons();
fullNotice = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = (Graphics2D) fullNotice.getGraphics();
g2d.setColor(ColorProvider.getStringColor(((MarketBoothDialogMetaData)metaData).stockPrices));
Font font =fontLoader.createDefaultFont(18);
font = font.deriveFont(Font.BOLD);
String s = "Stock and Prices"; // TODO externalize
GlyphVector gv = opPainter.createGlyphVector(g2d, s, font);
int x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
int y = insets.top+topOffset+2/3*font18Height;
g2d.drawGlyphVector(gv, x, y);
if (((MarketBoothDialogMetaData)metaData).stockPrices!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"TradingStockDialog",new MarketBoothChangeAction(ENoticeItem.MB_STOCK_PRICES));
}
s = "Consumtion/Production"; // TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.setColor(ColorProvider.getStringColor(((MarketBoothDialogMetaData)metaData).consumtionProduction));
g2d.drawGlyphVector(gv, x, y);
if (((MarketBoothDialogMetaData)metaData).consumtionProduction!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"ConsumptionProductionDialog",new MarketBoothChangeAction(ENoticeItem.MB_CONSUMPTION_PRODUCTION));
}
}
private void createOrUpdateTradeNotice()
throws FontFormatException, IOException {
final int lineSpacing = font18Height/2;
final int topOffset = 50;
// figure the dimensions out
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int width = bounds.width-insets.left-insets.right;
final int height = topOffset+4*font18Height+3*lineSpacing;
offsetPolys = new ClickableOffsetPolygons();
fullNotice = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = (Graphics2D) fullNotice.getGraphics();
// Draw inactive dark gray
// Draw selected black
// Draw disabled grey
g2d.setColor(ColorProvider.getStringColor(((TradeDialogMetaData)metaData).city2ship));
Font font =fontLoader.createDefaultFont(18);
font = font.deriveFont(Font.BOLD);
String s = "City <- -> Ship";// TODO externalize
if (((TradeDialogMetaData)metaData).getCityProxy().getActiveShip() instanceof IConvoy){
s = "City <- -> Convoy";// TODO externalize
}
GlyphVector gv = opPainter.createGlyphVector(g2d, s, font);
int x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
int y = insets.top+topOffset+2/3*font18Height;
g2d.drawGlyphVector(gv, x, y);
if (((TradeDialogMetaData)metaData).city2ship!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"City2ShipTradeDialog",new TradeDialogeChangeAction(ETransferDialogType.CITY_TO_SHIP));
}
g2d.setColor(ColorProvider.getStringColor(((TradeDialogMetaData)metaData).office2ship));
s = "Ship <- -> Trading Office";
if (((TradeDialogMetaData)metaData).getCityProxy().getActiveShip() instanceof IConvoy){
s = "Convoy <- -> Trading Office";// TODO externalize
}
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.drawGlyphVector(gv, x, y);
if (((TradeDialogMetaData)metaData).office2ship!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"Ship2StorageTradeDialog",new TradeDialogeChangeAction(ETransferDialogType.STORAGE_TO_SHIP));
}
g2d.setColor(ColorProvider.getStringColor(((TradeDialogMetaData)metaData).city2office));
s = "City <- -> Trading Office";// TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.drawGlyphVector(gv, x, y);
if (((TradeDialogMetaData)metaData).city2office!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"City2StorageTradeDialog",new TradeDialogeChangeAction(ETransferDialogType.CITY_TO_STORAGE));
}
g2d.setColor(ColorProvider.getStringColor(((TradeDialogMetaData)metaData).weapons));
s = "Weapons";// TODO externalize
gv = opPainter.createGlyphVector(g2d, s, font);
y += lineSpacing+font18Height;
x = insets.left+(int)Math.ceil((width-gv.getVisualBounds().getWidth())/2);
g2d.drawGlyphVector(gv, x, y);
if (((TradeDialogMetaData)metaData).weapons!=EStringSelectionState.DISABLE){
addOffsetPolygon(bounds, gv, x, y,"WeaponsTradeDialog",new TradeDialogeChangeAction(ETransferDialogType.WEAPON));
}
}
/**
* Add a named polygon to the offset polygon list. the contour of the polygon
* is computed by the outline of the string that makes out the GlyphVector added
* at position x,y within bounds. (x,y) are relative coordinates to bounds.
* @param bounds Bounds of the view
* @param gv {@link GlyphVector} holding the string
* @param x position of the left most character
* @param y position of the strings baseline
* @param polyName name of the Polygon
* @param action to be executed when run.
*/
private void addOffsetPolygon(final Rectangle bounds, GlyphVector gv,
int x, int y, String polyName, Runnable action) {
NamedPolygon polygon = new NamedPolygon(polyName);
Rectangle rect = gv.getVisualBounds().getBounds();
polygon.addPoint(bounds.x+x, bounds.y+y+rect.y);
polygon.addPoint(bounds.x+x+rect.width, bounds.y+y+rect.y);
polygon.addPoint(bounds.x+x+rect.width, bounds.y+y+rect.y+rect.height);
polygon.addPoint(bounds.x+x, bounds.y+y+rect.y+rect.height);
offsetPolys.add(polygon, action);
}
/**
* check if the notice is to large to be displayed without scrolling
* @return
*/
private boolean needsScrollBar(){
if (fullNotice==null) return false; // there is no notice at all
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
if (fullNotice.getHeight()>bounds.height-insets.top-insets.bottom){
return true;
} else {
return false;
}
}
/**
* check if the top of the notice is shown
* @return
*/
private boolean isScrolledToTop(){
if (needsScrollBar()){
return noticeOffset==0;
} else {
return true;
}
}
/**
* Check if the bottom of the notice is shown
* @return
*/
private boolean isScrolledToBottom(){
if (needsScrollBar()){
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int maxVisibleHeight = bounds.height-insets.top-insets.bottom;
// if what we scrolled down and what we see makes up the same height as the notice
return noticeOffset+maxVisibleHeight >= fullNotice.getHeight();
} else {
return true;
}
}
/**
* Action for the scrolling up
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Dec 17, 2011
*
*/
private class ScrollUpAction implements Runnable{
@Override
public void run() {
if (!isScrolledToTop()){
noticeOffset -= SCROLL_OFFSET;
if (noticeOffset<0) noticeOffset = 0;
logger.debug("Scroll up");
}
}
}
/**
* Action for the scrolling down
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Dec 17, 2011
*
*/
private class ScrollDownAction implements Runnable{
@Override
public void run() {
if (!isScrolledToBottom()){
final Rectangle bounds = getBounds();
final Insets insets = getInsets();
final int maxVisibleHeight = bounds.height-insets.top-insets.bottom;
final int maxOffset = fullNotice.getHeight()-maxVisibleHeight;
noticeOffset += SCROLL_OFFSET;
if (noticeOffset>maxOffset) noticeOffset = maxOffset;
logger.debug("Scroll down");
}
}
}
private class TradeDialogeChangeAction implements Runnable {
/** dialog type to change into */
private final ETransferDialogType dialogType;
public TradeDialogeChangeAction(ETransferDialogType dialogType) {
super();
this.dialogType = dialogType;
}
@Override
public void run() {
boolean doUpdate=false;
TradeDialogMetaData meta = ((TradeDialogMetaData)metaData);
switch (dialogType) {
case CITY_TO_SHIP:
meta.inactivateAllNotDisabled();
if (meta.city2ship!=EStringSelectionState.DISABLE){
meta.city2ship=EStringSelectionState.ACTIVE;
doUpdate=true;
}
break;
case CITY_TO_STORAGE:
meta.inactivateAllNotDisabled();
if (meta.city2office!=EStringSelectionState.DISABLE){
meta.city2office=EStringSelectionState.ACTIVE;
doUpdate=true;
}
break;
case STORAGE_TO_SHIP:
meta.inactivateAllNotDisabled();
if (meta.office2ship!=EStringSelectionState.DISABLE){
meta.office2ship=EStringSelectionState.ACTIVE;
doUpdate=true;
}
break;
case WEAPON:
meta.inactivateAllNotDisabled();
if (meta.weapons!=EStringSelectionState.DISABLE){
meta.weapons=EStringSelectionState.ACTIVE;
doUpdate=true;
}
break;
}
if (doUpdate){
new ViewChangeEvent(TradeDialog.class).notify(dialogType);
try {
createOrUpdateTradeNotice();
} catch (Exception e) {
logger.error("Could not create notice for trade dialog", e);
}
}
}
}
/**
* Inner class handling the clicks on the notice for the trading office
* @author Andi Hotz, (c) Sahits GmbH, 2012
* Created on Jul 20, 2012
*
*/
private class TradingOfficeChangeAction implements Runnable {
/** Indicate the item that is selected */
private final ENoticeItem selected;
public TradingOfficeChangeAction(ENoticeItem selected) {
super();
if (selected==null){
throw new NullPointerException("The notice item my not be null");
}
this.selected = selected;
}
@Override
public void run() {
boolean doUpdate=false;
TradingOfficeDialogMataData meta = (TradingOfficeDialogMataData) metaData;
switch (selected) {
case TO_BALANCE:
meta.inactivateAll();
meta.balance=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
case TO_CONSUMPTION_PRODUCTION:
meta.inactivateAll();
meta.consumtionProduction=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
case TO_OFFICE_TRADING:
meta.inactivateAll();
meta.storageManager=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
case TO_PERSONAL:
meta.inactivateAll();
meta.personal=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
case TO_WAREHOUSES:
meta.inactivateAll();
meta.warehouses=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
case TO_WEAPONS:
meta.inactivateAll();
meta.weapons=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
default:
throw new IllegalArgumentException("Unhandled notice type item in market booth: "+selected);
}
if (doUpdate){
new ViewChangeEvent(MainView.class).notify(selected);
try {
createOrUpdateTradingOfficeNotice();
} catch (Exception e) {
logger.error("Could not create notice for trading office dialog", e);
}
}
}
}
/**
* Inner class handling the clicks on the notice for the market booth
* @author Andi Hotz, (c) Sahits GmbH, 2012
* Created on Jul 20, 2012
*
*/
private class MarketBoothChangeAction implements Runnable {
/** Indicate the item that is selected */
private final ENoticeItem selected;
public MarketBoothChangeAction(ENoticeItem selected) {
super();
if (selected==null){
throw new NullPointerException("The notice item my not be null");
}
this.selected = selected;
}
@Override
public void run() {
boolean doUpdate=false;
MarketBoothDialogMetaData meta = (MarketBoothDialogMetaData) metaData;
switch (selected) {
case MB_STOCK_PRICES:
meta.consumtionProduction=EStringSelectionState.INACTIVE;
meta.stockPrices=EStringSelectionState.ACTIVE;
doUpdate=true;
break;
case MB_CONSUMPTION_PRODUCTION:
meta.consumtionProduction=EStringSelectionState.ACTIVE;
meta.stockPrices=EStringSelectionState.INACTIVE;
doUpdate=true;
break;
default:
throw new IllegalArgumentException("Unhandled notice type item in market booth: "+selected);
}
if (doUpdate){
new ViewChangeEvent(MainView.class).notify(selected);
try {
creatOrUpdateMarketBoothNotice();
} catch (Exception e) {
logger.error("Could not create notice for trade dialog", e);
}
}
}
}
}