package trackerModule.sim.map;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import trackerModule.core.datastructure.TDB;
import trackerModule.core.datastructure.Unit;
import trackerModule.core.rulestructure.IMessageObject;
import trackerModule.core.rulestructure.RDB;
import trackerModule.sim.map.draw.UCanvas;
import trackerModule.sim.tracker.World;
import trackerModule.sim.tracker.World.Tile;
/**
* The Class GMap.
*/
public class GMap extends UCanvas implements MouseMotionListener, MouseListener, ComponentListener, KeyListener, IMessageObject
{
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 2738911165525422437L;
/** The mode edit. */
static String MODE_EDIT = "Editing Mode";
/** The mode sim. */
static String MODE_SIM = "Simulation Mode";
/** The background image. */
BufferedImage backgroundImg;
/** The current tile. */
String curTile;
/** The current mode. */
String curMode;
/** The frame. */
MapFrame frame = null;
/** The show info. */
boolean showInfo = true;
/** The show ship info. */
boolean showShipInfo = false;
/** The scale. */
double scale = 1.0;//0.166666667;
/** The dashed stroke. */
Stroke dashedStroke = new BasicStroke(1f,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
1f,
new float[] {5f},
0f);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Instantiates a new g map.
*
* @param f the Map Frame
*/
public GMap(MapFrame f) {
super();
frame = f;
addMouseMotionListener(this);
addMouseListener(this);
addComponentListener(this);
addKeyListener(this);
setFocusable(true);
RDB.This().addMessageObjectForTime(this);
this.setBackground(Color.white);
this.setOpaque(true);
setMode(MODE_SIM);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Set
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Sets the mode.
*
* @param s the new mode
*/
public void setMode( String s ){
curMode = s;
}
/**
* Sets the show info.
*
* @param b the new show info
*/
public void setShowInfo( boolean b ){
showInfo = b;
repaint();
}
/**
* Sets the show ship info.
*
* @param b the new show ship info
*/
public void setShowShipInfo( boolean b ){
showShipInfo = b;
for( int i = 0; i< this.getComponentCount(); i++ ){
Object o = this.getComponent(i);
if(o instanceof GEntity ){
((GEntity)o).setShowInfo(b);
}
}
repaint();
}
/**
* Sets the cur tile.
*
* @param s the new cur tile
*/
public void setCurTile( String s ){
curTile = s;
repaint();
}
/**
* Sets the background image.
*
* @param pathImage the new background image
*/
public void setBackgroundImage(URL pathImage) {
try {
backgroundImg = ImageIO.read(pathImage);
} catch (IOException e) {
e.printStackTrace();
return;
}
setPreferredSize(new Dimension(getScaledWidth(), getScaledHeight()));
setSize(new Dimension(getScaledWidth(), getScaledHeight()));
}
/**
* Sets the scale.
*
* @param s the new scale
*/
public void setScale(double s){
scale = s;
setPreferredSize(new Dimension(getScaledWidth(), getScaledHeight()));
setSize(new Dimension(getScaledWidth(), getScaledHeight()));
repaint();
}
/**
* Gets the scale.
*
* @return the scale
*/
public double getScale(){
return scale;
}
/**
* Gets the scaled width.
*
* @return the scaled width
*/
public int getScaledWidth(){
return (int)(backgroundImg.getWidth(null)*scale);
}
/**
* Gets the scaled height.
*
* @return the scaled height
*/
public int getScaledHeight(){
return (int)(backgroundImg.getHeight(null)*scale);
}
/**
* Sets the tile.
*
* @param x the x
* @param y the y
* @param str the name
*/
private void setTile(int x, int y, String str) {
if( str == null )
return;
Integer tileSize = World.This().TILE_SIZE;
int width = World.This().MAP_WIDTH;
int height = World.This().MAP_HEIGHT;
int xTile = x/tileSize;
int yTile = y/tileSize;
if( xTile < 0 || yTile < 0 || xTile >= width || yTile >= height )
return;
World.This().setTile(xTile, yTile, str);
Tile t = World.This().getLocation(str);
if( t != null ){
t.x = xTile;
t.y = yTile;
}
}
/**
* Removes the all g entity.
*/
public void removeAllGEntity(){
this.removeAll();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Gets the mode.
*
* @return the mode
*/
public String getMode() {
return curMode;
}
/**
* Gets the show info.
*
* @return the show info
*/
public boolean getShowInfo() {
return showInfo;
}
/**
* Gets the show ship info.
*
* @return the show ship info
*/
public boolean getShowShipInfo() {
return showShipInfo;
}
/**
* Gets the cur tile.
*
* @return the cur tile
*/
public String getCurTile() {
return curTile;
}
/**
* Gets the tile.
*
* @param x the x
* @param y the y
* @return the tile
*/
public String getTile(int x, int y) {
Integer tileSize = World.This().TILE_SIZE;
return World.This().getTile(x/tileSize, y/tileSize);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Draw
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#paintComponent(java.awt.Graphics)
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.scale(scale, scale);
g.drawImage(backgroundImg, 0, 0, null);
if( getMode() == MODE_EDIT ){
if( curTile != null ){
if( World.This().mapRoute.containsKey(curTile) )
drawRoutes(g);
else
drawTiles(g);
}
else
drawTiles(g);
}
if( getMode() == MODE_SIM && getShowInfo() )
drawLocations(g);
drawSelectedShipCircle(g);
super.paintComponent(g);
}
/**
* Draw selected ship circle.
*
* @param g the Graphics
*/
private void drawSelectedShipCircle(Graphics g) {
Unit s = frame.getCurEntity();
if(s != null){
String strState = s.get("State").getData();
if( strState.indexOf("waiting") >=0 || strState.equalsIgnoreCase("end"))
return;
Graphics2D g2 = (Graphics2D) g;
Integer x = s.get("X").getDataByInt();
Integer y = s.get("Y").getDataByInt();
int iDiameter = World.This().getDetectingMileForScreen();
Stroke oldStroke = g2.getStroke();
g2.setColor(new Color(10,10,255,100));
g2.setStroke(dashedStroke);
g2.drawOval(x - iDiameter/2 , y - iDiameter/2 , iDiameter, iDiameter);
g2.setStroke (oldStroke);
}
}
/**
* Draw locations.
*
* @param g the Graphics
*/
private void drawLocations(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Integer tileSize = World.This().TILE_SIZE;
for( String str : World.This().tileMap.keySet() ){
Tile tile = World.This().tileMap.get(str);
Integer x = tile.x;
Integer y = tile.y;
Integer xSize = tile.width + 60;
Integer ySize = tile.height + 60;
if( World.This().listBigPort.contains(str) ){
g2.setColor(new Color(237,28,36,50));
}else
if( World.This().listSmallPort.contains(str) ){
g2.setColor(new Color(237,28,36,50));
}else
if( World.This().listFishingArea.contains(str) ){
g2.setColor(new Color(255,255,0,50));
}else
if( World.This().listMerchantArea.contains(str) ){
g2.setColor(new Color(255,201,124,50));
}else
if( World.This().listArea.contains(str) ){
g2.setColor(new Color(0,162,232,50));
}else
g2.setColor(new Color(0,0,255,50));
if( !World.This().listUnusualArea.contains(str) ){
g2.drawString(str,x*tileSize - xSize/2 + 20/2, y*tileSize - ySize/2 + tileSize/2);
g2.fillOval(x*tileSize - xSize/2 + tileSize/2, y*tileSize - ySize/2 + tileSize/2, xSize, ySize);
}
}
}
/**
* Draw tiles.
*
* @param g the Graphics
*/
public void drawTiles(Graphics g) {
Integer tileSize = World.This().TILE_SIZE;
int width = World.This().MAP_WIDTH;
int height = World.This().MAP_HEIGHT;
for( Integer y = 0 ; y < height; y++ ){
for( Integer x = 0 ; x < width; x++ ){
String str = World.This().getTile(x, y);
if( str != null ){
String cmpstr = str.substring(0, 3);
if( cmpstr.equals("Wat")){
g.setColor(Color.BLUE);
cmpstr = str.substring(0,1);
}
else
if( cmpstr.equals("Lan")){
g.setColor(Color.ORANGE);
cmpstr = str.substring(0,1);
}
else
if( cmpstr.equals("Are") ||
cmpstr.equals("Fis") ||
cmpstr.equals("Mer")
){
g.setColor(Color.GREEN);
Pattern intsOnly = Pattern.compile("\\d+");
Matcher makeMatch = intsOnly.matcher(str);
makeMatch.find();
cmpstr = makeMatch.group();
}
else
g.setColor(Color.RED);
g.drawString(cmpstr, x*tileSize + 5, y*tileSize + 14);
}
}
}
for( int y = 0 ; y < height; y++ ){
g.drawLine(0, y*tileSize, width*tileSize, y*tileSize);
}
for( int x = 0 ; x < width; x++ ){
g.drawLine(x*tileSize, 0, x*tileSize, height*tileSize);
}
}
/**
* Draw routes.
*
* @param g the Graphics
*/
public void drawRoutes(Graphics g) {
Integer tileSize = World.This().TILE_SIZE;
int width = World.This().MAP_WIDTH;
int height = World.This().MAP_HEIGHT;
for( Integer y = 0 ; y < height; y++ ){
for( Integer x = 0 ; x < width; x++ ){
boolean b = World.This().getRoute(curTile, x, y);
if( b ){
g.setColor(Color.WHITE);
g.drawString("R", x*tileSize + 5, y*tileSize + 14);
}else{
g.setColor(Color.BLUE);
g.drawString("U", x*tileSize + 5, y*tileSize + 14);
}
}
}
for( int y = 0 ; y < height; y++ ){
g.drawLine(0, y*tileSize, width*tileSize, y*tileSize);
}
for( int x = 0 ; x < width; x++ ){
g.drawLine(x*tileSize, 0, x*tileSize, height*tileSize);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Update data
//////////////////////////////////////////////////////////////////////////////////////////////////////
/* (non-Javadoc)
* @see trackerModule.core.rulestructure.IMessageObject#onUpdated(java.lang.Object)
*/
public void onUpdated(Object o) {
Unit ships = TDB.This().get("TDBROOT.MODEL.WORLD.SHIPS");
for( Unit ship : ships.getList() ){
updateShipGEntityOnCanvas(ship);
}
Rectangle r = this.getVisibleRect();
repaint((int)r.getX(), (int)r.getY(), (int)r.getWidth(), (int)r.getHeight());
}
/**
* Gets the g entity.
*
* @param ship the ship
* @return the g entity
*/
GEntity getGEntity(Unit ship){
GEntity ge = null;
for(Component com : getComponents()){
if(com instanceof GEntity){
ge = (GEntity)com;
if(ge.getName().equalsIgnoreCase(ship.getName())){
return ge;
}
}
}
return null;
}
/**
* Update ship g entity on canvas.
*
* @param ship the ship
*/
void updateShipGEntityOnCanvas(Unit ship){
Integer x = ship.get("X").getDataByInt();
Integer y = ship.get("Y").getDataByInt();
GEntity gEntity = getGEntity(ship);
if( gEntity == null ){
gEntity = new GEntity(this, ship, x, y);
add(gEntity);
}
//set position
gEntity.setPosition(x, y);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Mouse
//////////////////////////////////////////////////////////////////////////////////////////////////////
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mouseDragged(java.awt.event.MouseEvent)
*/
public void mouseDragged(MouseEvent e) {
super.mouseDragged(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mouseMoved(java.awt.event.MouseEvent)
*/
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mouseClicked(java.awt.event.MouseEvent)
*/
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if( getMode() == MODE_EDIT )
setTile(e.getX(), e.getY(), getCurTile());
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mouseEntered(java.awt.event.MouseEvent)
*/
public void mouseEntered(MouseEvent e) {
super.mouseEntered(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mouseExited(java.awt.event.MouseEvent)
*/
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mousePressed(java.awt.event.MouseEvent)
*/
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#mouseReleased(java.awt.event.MouseEvent)
*/
public void mouseReleased(MouseEvent e) {
if( getMode() == MODE_EDIT )
if (dragRect.x != 0 && dragRect.y != 0) {
for( int x = 0; x < selectRect.width; x+=10)
for( int y = 0; y < selectRect.height; y+=10)
setTile(x+selectRect.x, y + selectRect.y, getCurTile());
repaint();
}
super.mouseReleased(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#componentHidden(java.awt.event.ComponentEvent)
*/
public void componentHidden(ComponentEvent e) {
super.componentHidden(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#componentMoved(java.awt.event.ComponentEvent)
*/
public void componentMoved(ComponentEvent e) {
super.componentMoved(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#componentResized(java.awt.event.ComponentEvent)
*/
public void componentResized(ComponentEvent e) {
super.componentResized(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#componentShown(java.awt.event.ComponentEvent)
*/
public void componentShown(ComponentEvent e) {
super.componentShown(e);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#keyPressed(java.awt.event.KeyEvent)
*/
public void keyPressed(KeyEvent arg0) {
super.keyPressed(arg0);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#keyReleased(java.awt.event.KeyEvent)
*/
public void keyReleased(KeyEvent arg0) {
super.keyReleased(arg0);
}
/* (non-Javadoc)
* @see trackerModule.sim.map.draw.UCanvas#keyTyped(java.awt.event.KeyEvent)
*/
public void keyTyped(KeyEvent arg0) {
super.keyTyped(arg0);
}
}