package gvps.gui;
import gvps.data.objects.*;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.Color;
import java.util.Vector;
import java.util.Iterator;
public class MapArea extends JComponent implements Runnable {
private double scale = 1;
private Vector<Polygon> buildings = new Vector<Polygon>();
private Vector<Road> roads;
private final BasicStroke ROAD = new BasicStroke(5.0f);
private final BasicStroke BUILDING = new BasicStroke(0.5f);
private final Color BUILDING_INT = new Color(200, 240, 245);
private Vector<MappedVehicle> vehicles;
private int state;
private int carOffset;
private Image carImage;
private int refreshWait = 60; // animation speed: ~20fps
private Graphics2D mapGraphics;
private Image mapImage;
public MapArea() {
setBackground(Color.WHITE);
carImage = Toolkit.getDefaultToolkit().getImage("car_icon.png");
vehicles = new Vector<MappedVehicle>();
carOffset = (carImage.getWidth(this) / 2);
}
/* this might be useful also
public MapArea(AreaMap newMap) {
this.buildings = newMap.getBuildings();
carImage = Toolkit.getDefaultToolkit().getImage("car_icon.png");
vehicles = new Vector<MappedVehicle>();
carOffset = (carImage.getWidth(this) / 2);
drawMap();
}
*/
public void addVehicle(String vehicleId, Vector<Point> path, int speed){
MappedVehicle vehicle = new MappedVehicle(vehicleId, path, speed);
vehicles.add(vehicle);
Thread vehicleThread = new Thread(vehicle);
vehicleThread.start();
}
/**
* Forces the current location of a vehicle with the specified vehicleID
* @param vehicleId the unique identifier of the desired vehicle
* @param location the new location of the vehicle
*/
public void forceVehicleLocation(String vehicleId, Point location){
try {
getMappedVehicle(vehicleId).setLocation(location);
}
catch (VehicleNotFoundException e) {
System.out.println(e);
}
}
/**
* Changes the predictive speed of a vehicle with the specified vehicleID.
* Warning: No mutexes are used to validate the size of vehicles Vector,
* resulting in possibly incorrect vehicle counts.
* @param vehicleID the id of the vehicle
* @param speed the new speed of the chosen vehicle
*/
public void setVehicleSpeed(String vehicleId, int speed) {
try {
getMappedVehicle(vehicleId).setSpeed(speed);
}
catch (VehicleNotFoundException e) {
System.out.println(e);
}
}
/**
* Pauses a selected vehicles movements.
*/
public void pauseVehicle(String vehicleId){
}
/**
* Gets a MappedVehicle object based on it's vehicleId.
* @param id the unique identifier of a vehicle
* @throws VehicleNotFoundException if a vehicle does not exist with this id
*/
public MappedVehicle getMappedVehicle(String id) throws VehicleNotFoundException {
boolean vehicleFound = false;
int totalVehicles = vehicles.size();
int count = 0;
// loop through each vehicle looking for one with the right ID
while ( !vehicleFound || count < totalVehicles ){
if ( vehicles.get(count).getId().equals(id) ){
vehicleFound = true;
}
else {
count++;
}
}
if ( !vehicleFound ){
throw new VehicleNotFoundException("A vehicle does not exist "+
"with the id \"" + id + "\"" );
}
else {
return vehicles.get(count);
}
}
public void run(){
while (true){
repaint();
try {
Thread.sleep(refreshWait);
}
catch (InterruptedException e){
System.out.println("This thread has been broken... "+
"I have NO idea what that means");
}
}
}
public void paint(Graphics g){
super.paint(g);
/* places a "car" image at every point on the map where a car is *
* supposed to be then draws that to the component */
int totalVehicles = vehicles.size();
int positionX;
int positionY;
g.clearRect(0,0,getWidth(),getHeight());
if ( mapImage != null){
g.drawImage(mapImage, 0, 0, this);
}
// if we have vehicles, loop through them, get their position, and draw them
if ( totalVehicles > 0 ){
for ( int i = 0; i < totalVehicles; i++ ){
MappedVehicle currentVehicle = vehicles.get(i);
// check if the current vehicle hasn't reached its destination
if ( !currentVehicle.isFinished() ){
positionX = (int)currentVehicle.getLocation().getX() - carOffset;
positionY = (int)currentVehicle.getLocation().getY() - carOffset;
g.drawImage(carImage, positionX, positionY, this);
}
// else, remove it from the list of vehicles
else {
vehicles.remove(i);
// compensate for removed vehicle
i--;
totalVehicles = vehicles.size();
}
}
}
}
/**
* Updates the current map image in memory according to the currently
* stored Map object.
*/
public void drawMap(){
if ( mapGraphics == null ){
mapImage = createImage(getWidth(), getHeight());
mapGraphics = (Graphics2D)mapImage.getGraphics();
}
mapGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//do roads
mapGraphics.setStroke(ROAD);
if(roads != null) {
Iterator<Road> i = roads.iterator();
while(i.hasNext()) {
Road r = i.next();
mapGraphics.setColor(Color.BLACK);
mapGraphics.drawPolyline(r.getX(), r.getY(), r.getX().length);
}
}
//buildings
mapGraphics.setStroke(BUILDING);
if(buildings != null) {
Iterator<Polygon> i = buildings.iterator();
while(i.hasNext()) {
Polygon p = i.next();
mapGraphics.setColor(BUILDING_INT);
mapGraphics.fillPolygon(p);
mapGraphics.setColor(Color.BLACK);
mapGraphics.drawPolygon(p);
}
}
}
public void setMap(AreaMap map) {
Iterator<Building> i;
i = map.getBuildings().iterator();
System.out.println(map.getBuildings().size());
while(i.hasNext()) {
buildings.add(i.next().getPolygon());
}
roads = map.getRoads();
System.out.println(roads.size());
drawMap();
}
public void zoomIn() {
if ( mapGraphics != null ){
scale+=0.01;
mapGraphics.transform(AffineTransform.getScaleInstance(scale, scale));
}
}
public void zoomOut() {
if ( mapGraphics != null ){
scale-=0.01;
mapGraphics.transform(AffineTransform.getScaleInstance(scale, scale));
}
}
}