Package ch.sahits.game.graphic.display.gameplay

Source Code of ch.sahits.game.graphic.display.gameplay.TradeDialog$DialogPositions

package ch.sahits.game.graphic.display.gameplay;

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 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.model.CityPlayerProxy;
import ch.sahits.game.graphic.display.util.ClickablePolygons;
import ch.sahits.game.graphic.display.util.NamedPolygon;
import ch.sahits.game.graphic.image.ImagesLoader;
import ch.sahits.game.graphic.image.OpenPatricianPainter;
import ch.sahits.game.image.ImageUtil;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.openpatrician.model.product.AmountablePrice;
import ch.sahits.game.openpatrician.model.product.EWare;
import ch.sahits.game.openpatrician.model.ship.IShip;
import ch.sahits.game.rendering.RenderablePart;
/**
* Trade dialog for buying/selling from/to the city involving either a ship or the branch office.
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Nov 18, 2011
*
*/
public class TradeDialog extends OpenPatricianGameDialog implements
    RenderablePart, IEventListener {
  private boolean enabled = true;
  /** Reference to the city view model */
  private final CityPlayerProxy city;
  /** The amount that is moved with one click */
  private ETransferAmount movableAmount = ETransferAmount.ONE;
  private ClickablePolygons polygons;
  private ClickablePolygons footerPolygons;
  /** Hold all the positiononing information, initialized in initBackgroundImage */
  private DialogPositions positions;

  public TradeDialog(Point topLeft, ImagesLoader loader,double scale, CityPlayerProxy CityPlayerProxy) {
    super(topLeft, loader,scale);
    city = CityPlayerProxy;
    Event.add(this);
  }
 
  @Override
  protected void initiatePolygons() {
    polygons = new ClickablePolygons();
    footerPolygons = new ClickablePolygons();
  }

  /**
   * Retrieve the amount that is to be transferred. This method does
   * not consider how much is available.
   * @param maxMount
   * @return
   */
  private int getAmount(int maxMount){
    switch (movableAmount){
    case ONE:
      return 1;
    case FIVE:
      return 5;
    case MAX:
      return maxMount;
    default:
      return 1;
    }
  }
  @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);
        Event.remove(this);
      }
    }
    if (e instanceof MouseClickEvent){
      polygons.testAndExecute((Point) notice);
      footerPolygons.testAndExecute((Point) notice);
    }
  }

  @Override
  public boolean isEnabled() {
    return enabled;
  }

  @Override
  public void setEnabled(boolean flag) {
    enabled=flag;
  }
 

  @Override
  protected BufferedImage initBackgroundImage(ImagesLoader loader,Point topLeft) {
    BufferedImage bg = super.initBackgroundImage(loader,topLeft);
    Graphics2D g2d = bg.createGraphics();
    g2d.setColor(Color.BLACK);
    try {
      GlyphVector gv = OpenPatricianPainter.createGlyphVector(g2d, "Trade goods", 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 xWare = leftBorderX+100; // right aligned
      int xCity = leftBorderX+110;
      int xBuy = leftBorderX+160; // size of the image + 10
      int xSell = leftBorderX+210;// size of the image + 10
      int xShip = leftBorderX+260;
      int xPrice = leftBorderX+310;
      int yLineDiff = waxSeal.getHeight();
      // Initialize the position relative to the frame
      positions = new DialogPositions(titleHeight, yLineDiff, leftBorderX, xWare, xCity, xBuy, xSell, xShip, xPrice);
     
      leftBorderX = getInset().left; // Use local coordinates
      xWare = leftBorderX+100; // right aligned
      xCity = leftBorderX+110;
      xBuy = leftBorderX+160; // size of the image + 10
      xSell = leftBorderX+210;// size of the image + 10
      xShip = leftBorderX+260;
      xPrice = leftBorderX+310;
     
      // draw the table header
      gv = OpenPatricianPainter.createGlyphVector(g2d, "Ware", 19); // TODO externalize
      x = xWare-(int)Math.rint(gv.getVisualBounds().getWidth());
      y += positions.lineHeight; // more space to the title
      y += positions.lineHeight;
      g2d.drawGlyphVector(gv, x, y);

      gv = OpenPatricianPainter.createGlyphVector(g2d, "City", 19);
      g2d.drawGlyphVector(gv, xCity, y);
      gv = OpenPatricianPainter.createGlyphVector(g2d, "Buy", 19);
      g2d.drawGlyphVector(gv, xBuy, y);
      gv = OpenPatricianPainter.createGlyphVector(g2d, "Sell", 19);
      g2d.drawGlyphVector(gv, xSell, y);
      gv = OpenPatricianPainter.createGlyphVector(g2d, "Ship", 19); // TODO differenciate between ship and convoi
      g2d.drawGlyphVector(gv, xShip, y);
      gv = OpenPatricianPainter.createGlyphVector(g2d, Character.toChars(0x00D8)[0]+"-Price", 19); // TODO do better
      g2d.drawGlyphVector(gv, xPrice, y);
     
      // Table
      EWare[] wares = EWare.values();
      for (EWare ware : wares) {
        // Ware name
        y += positions.lineHeight;
        gv = OpenPatricianPainter.createGlyphVector(g2d, ware.getLocalDisplayName(), 18);
        x = xWare-(int)Math.rint(gv.getVisualBounds().getWidth());
        g2d.drawGlyphVector(gv, x, y);
        // Amount available
       
        // Buy button
        g2d.drawImage(waxSeal, xBuy,y-(int)(positions.lineHeight*0.8), null);
        NamedPolygon polygon = new NamedPolygon(ware.name()+"Buy");
        // The positions of the polygons must be global
        polygon.addPoint(positions.xBuy, topLeft.y+y-(int)(positions.lineHeight*0.8));
        polygon.addPoint(positions.xBuy+waxSeal.getWidth(), topLeft.y+y-(int)(positions.lineHeight*0.8));
        polygon.addPoint(positions.xBuy+waxSeal.getWidth(), topLeft.y+y-(int)(positions.lineHeight*0.8)+waxSeal.getHeight());
        polygon.addPoint(positions.xBuy, topLeft.y+y-(int)(positions.lineHeight*0.8)+waxSeal.getHeight());
        polygons.add(polygon, new City2ShipAction(ware));
       
        // Sell button
        g2d.drawImage(waxSeal, xSell,y-(int)(positions.lineHeight*0.8), null);
        polygon = new NamedPolygon(ware.name()+"Sell");
        polygon.addPoint(positions.xSell, topLeft.y+y-(int)(positions.lineHeight*0.8));
        polygon.addPoint(positions.xSell+waxSeal.getWidth(), topLeft.y+y-(int)(positions.lineHeight*0.8));
        polygon.addPoint(positions.xSell+waxSeal.getWidth(), topLeft.y+y-(int)(positions.lineHeight*0.8)+waxSeal.getHeight());
        polygon.addPoint(positions.xSell, topLeft.y+y-(int)(positions.lineHeight*0.8)+waxSeal.getHeight());
        polygons.add(polygon, new Ship2CityAction(ware));
      }
      // Footer buttons
      y = bg.getHeight()-getInset().bottom-positions.lineHeight;
      x = getInset().left+30;
      int footerWidth = bg.getWidth()-getInset().left-getInset().right-2*30;
      // 1 item
      g2d.setColor(new Color(0xEA,0xC1,0x17)); // Gold
      NamedPolygon polygon;
      g2d.drawImage(waxSeal, x,y-(int)(positions.lineHeight*0.8), null);
      polygon = new NamedPolygon("One");
      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 TransferAmountChangeAction(ETransferAmount.ONE));
      gv = OpenPatricianPainter.createGlyphVector(g2d, "1", 18);
      int xPadding = ImageUtil.computeCenterAlignX(x, waxSeal.getWidth(), (int)gv.getVisualBounds().getWidth());
      g2d.drawGlyphVector(gv, xPadding, y);
      x += footerWidth/4;
      // 5 items
      g2d.drawImage(waxSeal, x,y-(int)(positions.lineHeight*0.8), null);
      polygon = new NamedPolygon("five");
      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 TransferAmountChangeAction(ETransferAmount.FIVE));
      gv = OpenPatricianPainter.createGlyphVector(g2d, "5", 18);
      xPadding = ImageUtil.computeCenterAlignX(x, waxSeal.getWidth(), (int)gv.getVisualBounds().getWidth());
      g2d.drawGlyphVector(gv, xPadding, y); // centeralign
      x += footerWidth/4;
      // Max item
      g2d.drawImage(waxSeal, x,y-(int)(positions.lineHeight*0.8), null);
      polygon = new NamedPolygon("Max");
      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 TransferAmountChangeAction(ETransferAmount.MAX));
      gv = OpenPatricianPainter.createGlyphVector(g2d, "Max", 18); //externalize
      xPadding = ImageUtil.computeCenterAlignX(x, waxSeal.getWidth(), (int)gv.getVisualBounds().getWidth());
      g2d.drawGlyphVector(gv, xPadding, y); // centeralign
      x += footerWidth/4;
      // close
      g2d.drawImage(waxSeal, x,y-(int)(positions.lineHeight*0.8), null);
      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));
      gv = OpenPatricianPainter.createGlyphVector(g2d, "X", 18);
      xPadding = ImageUtil.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);
     
      // Sub title (dynamic)
      // City name
      y += positions.titleHeigth;
      int leftBorderX = getBounds().x+getInset().left;
      int x = leftBorderX + 20;
      ICity cityModel = city.getCity();
      GlyphVector gv = OpenPatricianPainter.createGlyphVector(g2d, cityModel.getName()+" "+cityModel.getPopulation(), 18);
      y += (int)Math.rint(positions.titleHeigth*2/3);
      g2d.drawGlyphVector(gv, x, y);
     
      // Barrel icon
      x += (int)Math.rint(gv.getVisualBounds().getWidth())+50;
      BufferedImage barrel = loader.getImage("barrel_icon");
      BufferedImage bale = loader.getImage("bale_icon");
      g2d.drawImage(barrel, x, y-(int)Math.rint(positions.titleHeigth), null); // Is y correct ???
     
      // loaded on ship and ship capacity
      x += 50;
      IShip ship = city.getActiveShip();
      StringBuilder sb = new StringBuilder();
      sb.append(ship.getLoad()).append(" / ").append(ship.getSize()).append(" ").append(ship.getName());
      gv = OpenPatricianPainter.createGlyphVector(g2d, sb.toString(), 18);
      g2d.drawGlyphVector(gv, x, y); // TODO this is a dynamic line
     
      BufferedImage waxSeal = loader.getImage("waxseal");
      // Table header
      y += positions.lineHeight; // more space to the title
      y += positions.lineHeight;
     
      // Table
      EWare[] wares = EWare.values();
      for (EWare ware : wares) {
        // Ware name
        y += positions.lineHeight;
       
        // Available amount in the city
        AmountablePrice<EWare> wareInCity = cityModel.getWare(ware);
        int availableAmount = wareInCity.getAmount();
        int value = availableAmount; // amount available
        if (value>0){
          gv = OpenPatricianPainter.createGlyphVector(g2d, String.valueOf(value), 18);
          g2d.drawGlyphVector(gv, positions.xCity, y);
          // draw barrel or burden
          if (ware.getSizeAsBarrels()==1){
            // barrel
            g2d.drawImage(barrel, (int)(positions.xCity+gv.getVisualBounds().getWidth())+5, y-positions.lineHeight*2/3, null);
          } else {
            g2d.drawImage(bale, (int)(positions.xCity+gv.getVisualBounds().getWidth())+5, y-positions.lineHeight*2/3, null);
          }
        }
        g2d.setColor(new Color(0xEA,0xC1,0x17)); // Gold
        // buy
        if (availableAmount>0){
          value = ware.computeBuyPrice(availableAmount, getAmount(availableAmount));
        } else {
          value = 0; // cannot buy anything if nothing is there
        }
        gv = OpenPatricianPainter.createGlyphVector(g2d, String.valueOf(value), 18);
        int xPadding = ImageUtil.computeCenterAlignX(positions.xBuy, waxSeal.getWidth(), (int)gv.getVisualBounds().getWidth());
        g2d.drawGlyphVector(gv, xPadding, y);
        // sell
        if (movableAmount==ETransferAmount.MAX){
          value = ware.getMaxValueSell();
        } else {
          value = ware.computeSellPrice(availableAmount, getAmount(availableAmount));
        }
        gv = OpenPatricianPainter.createGlyphVector(g2d, String.valueOf(value), 18);
        xPadding = ImageUtil.computeCenterAlignX(positions.xSell, waxSeal.getWidth(), (int)gv.getVisualBounds().getWidth());
        g2d.drawGlyphVector(gv, xPadding, y);
        g2d.setColor(Color.BLACK);
        // amount loaded
        value = city.getActiveShip().getWare(ware).getAmount(); // differ between ship and convoi
        if (value>0){
          gv = OpenPatricianPainter.createGlyphVector(g2d, String.valueOf(value), 18);
          g2d.drawGlyphVector(gv, positions.xShip, y); // this value is dynamic
          // draw barrel or burden
        }
        if (ship.getWare(ware).getAmount()>0){
          value = ship.getWare(ware).getAVGPrice();
          gv = OpenPatricianPainter.createGlyphVector(g2d, String.valueOf(value), 18);
          g2d.drawGlyphVector(gv, positions.xPrice+10, y);
        }
      } // end for wares
     
    } catch (FontFormatException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
   
    gScr.setColor(oldColor);
  }
 
  /**
   * Action of buying stuff from the city onto the ship
   * @author Andi Hotz, (c) Sahits GmbH, 2011
   * Created on Nov 23, 2011
   *
   */
  private class City2ShipAction implements Runnable{
    private final EWare ware;

    public City2ShipAction(EWare ware) {
      super();
      this.ware = ware;
    }

    @Override
    public void run() {
      int availableAmountCity = city.getCity().getWare(ware).getAmount();
      if (availableAmountCity>0){
        int amount2Move = getAmount(availableAmountCity); // This is war specific size
        System.out.println("Amount in the city: "+amount2Move);       
        // TODO consider available cash and capacity
        final short sizeAsBarrels = ware.getSizeAsBarrels();
        if (sizeAsBarrels==1){
          amount2Move = Math.min(amount2Move, city.getActiveShip().getCapacity());
        } else {
          int temp = Math.min(amount2Move*sizeAsBarrels, city.getActiveShip().getCapacity());
          amount2Move = temp/sizeAsBarrels;
        }
        System.out.println("Amount to be bought: "+amount2Move);       
        int avgPrice = ware.computeBuyPrice(availableAmountCity, amount2Move);
        int movedAmount = city.getCity().move(ware, -amount2Move);
        if (amount2Move!=movedAmount){
          System.out.println("Calc new price: "+amount2Move+","+avgPrice+","+movedAmount);
          avgPrice = ware.computeBuyPrice(city.getCity().getWare(ware).getAmount()+movedAmount, movedAmount);
          amount2Move=movedAmount;
        }
        int loaded = city.getActiveShip().load(ware, amount2Move, avgPrice);
        System.out.println("Loaded onto the ship: "+loaded);
        city.getPlayer().updateCash(-avgPrice*movedAmount);
      }
    }
   
  }
  /**
   * Action of selling stuff to the city from the ship
   * @author Andi Hotz, (c) Sahits GmbH, 2011
   * Created on Nov 23, 2011
   *
   */
  private class Ship2CityAction implements Runnable{
    private final EWare ware;

    public Ship2CityAction(EWare ware) {
      super();
      this.ware = ware;
    }

    @Override
    public void run() {
      if (city.getActiveShip().getWare(ware).getAmount()>0){
        int availableAmountCity = city.getCity().getWare(ware).getAmount();
        int amount2Move = getAmount(city.getActiveShip().getWare(ware).getAmount());
        final int avgPrice;
        if (movableAmount==ETransferAmount.MAX){
          avgPrice = ware.getMaxValueSell();
        } else {
          avgPrice = ware.computeSellPrice(availableAmountCity, amount2Move);
        }
        city.getCity().move(ware, amount2Move); // The price here is irrelevant
        city.getActiveShip().unload(ware, -amount2Move);
        city.getPlayer().updateCash(avgPrice*amount2Move);
      }
    }
  }
  /**
   * Action to change the chunck size that is to be moved.
   * @author Andi Hotz, (c) Sahits GmbH, 2011
   * Created on Nov 25, 2011
   *
   */
  private class TransferAmountChangeAction implements Runnable{
   
    private final ETransferAmount size;
   
    public TransferAmountChangeAction(ETransferAmount size) {
      super();
      this.size = size;
    }

    @Override
    public void run() {
      movableAmount=size;
      // Change the visual of the pressed button
    }
  }
  /**
   * Enumeration over the transferable amount
   * @author Andi Hotz, (c) Sahits GmbH, 2011
   * Created on Nov 25, 2011
   *
   */
  private enum ETransferAmount{
    /** Tranfer one item at the time */
    ONE,
    /** Transfer 5 items at the time */
    FIVE,
    /** Transfer all items at the time */
    MAX
  }
  /**
   * 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 leftBorder;
    private final int xWare;
    private final int xCity;
    private final int xBuy;
    private final int xSell;
    private final int xShip;
    private final int xPrice;
    public DialogPositions(double titleHeigth, int lineHeight,
        int leftBorder, int xWare, int xCity, int xBuy, int xSell,
        int xShip, int xPrice) {
      super();
      this.titleHeigth = titleHeigth;
      this.lineHeight = lineHeight;
      this.leftBorder = leftBorder;
      this.xWare = xWare;
      this.xCity = xCity;
      this.xBuy = xBuy;
      this.xSell = xSell;
      this.xShip = xShip;
      this.xPrice = xPrice;
    }
 
   
  }
}
TOP

Related Classes of ch.sahits.game.graphic.display.gameplay.TradeDialog$DialogPositions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.