package rescuecore2.standard.entities;
import rescuecore2.worldmodel.Entity;
import rescuecore2.worldmodel.EntityID;
import rescuecore2.worldmodel.Property;
import rescuecore2.worldmodel.WorldModel;
import rescuecore2.worldmodel.EntityListener;
import rescuecore2.worldmodel.properties.IntProperty;
import rescuecore2.worldmodel.properties.EntityRefListProperty;
import rescuecore2.misc.Pair;
import java.util.List;
import java.util.ArrayList;
import java.awt.Shape;
import java.awt.Polygon;
/**
The Area object.
*/
public abstract class Area extends StandardEntity {
private IntProperty x;
private IntProperty y;
private EdgeListProperty edges;
private EntityRefListProperty blockades;
private Shape shape;
private int[] apexList;
private List<EntityID> neighbours;
/**
Construct a subclass of Area with entirely undefined property values.
@param id The ID of this entity.
*/
protected Area(EntityID id) {
super(id);
x = new IntProperty(StandardPropertyURN.X);
y = new IntProperty(StandardPropertyURN.Y);
edges = new EdgeListProperty(StandardPropertyURN.EDGES);
blockades = new EntityRefListProperty(StandardPropertyURN.BLOCKADES);
registerProperties(x, y, edges, blockades);
shape = null;
apexList = null;
neighbours = null;
addEntityListener(new EdgesListener());
}
/**
Area copy constructor.
@param other The Area to copy.
*/
protected Area(Area other) {
super(other);
x = new IntProperty(other.x);
y = new IntProperty(other.y);
edges = new EdgeListProperty(other.edges);
blockades = new EntityRefListProperty(other.blockades);
registerProperties(x, y, edges, blockades);
shape = null;
apexList = null;
neighbours = null;
addEntityListener(new EdgesListener());
}
@Override
public Pair<Integer, Integer> getLocation(WorldModel<? extends StandardEntity> world) {
return new Pair<Integer, Integer>(x.getValue(), y.getValue());
}
@Override
public Property getProperty(String urn) {
StandardPropertyURN type;
try {
type = StandardPropertyURN.fromString(urn);
}
catch (IllegalArgumentException e) {
return super.getProperty(urn);
}
switch (type) {
case X:
return x;
case Y:
return y;
case EDGES:
return edges;
case BLOCKADES:
return blockades;
default:
return super.getProperty(urn);
}
}
/**
Get the X property.
@return The X property.
*/
public IntProperty getXProperty() {
return x;
}
/**
Get the X coordinate.
@return The X coordinate.
*/
public int getX() {
return x.getValue();
}
/**
Set the X coordinate.
@param x The new X coordinate.
*/
public void setX(int x) {
this.x.setValue(x);
}
/**
Find out if the X property has been defined.
@return True if the X property has been defined, false otherwise.
*/
public boolean isXDefined() {
return x.isDefined();
}
/**
Undefine the X property.
*/
public void undefineX() {
x.undefine();
}
/**
Get the Y property.
@return The Y property.
*/
public IntProperty getYProperty() {
return y;
}
/**
Get the Y coordinate.
@return The Y coordinate.
*/
public int getY() {
return y.getValue();
}
/**
Set the Y coordinate.
@param y The new y coordinate.
*/
public void setY(int y) {
this.y.setValue(y);
}
/**
Find out if the Y property has been defined.
@return True if the Y property has been defined, false otherwise.
*/
public boolean isYDefined() {
return y.isDefined();
}
/**
Undefine the Y property.
*/
public void undefineY() {
y.undefine();
}
/**
Get the edges property.
@return The edges property.
*/
public EdgeListProperty getEdgesProperty() {
return edges;
}
/**
Get the edges of this area.
@return The edges.
*/
public List<Edge> getEdges() {
return edges.getValue();
}
/**
Set the edges.
@param edges The new edges.
*/
public void setEdges(List<Edge> edges) {
this.edges.setEdges(edges);
}
/**
Find out if the edges property has been defined.
@return True if the edges property has been defined, false otherwise.
*/
public boolean isEdgesDefined() {
return edges.isDefined();
}
/**
Undefine the edges property.
*/
public void undefineEdges() {
edges.undefine();
}
/**
Get the blockades property.
@return The blockades property.
*/
public EntityRefListProperty getBlockadesProperty() {
return blockades;
}
/**
Get the blockades in this area.
@return The blockades.
*/
public List<EntityID> getBlockades() {
return blockades.getValue();
}
/**
Set the blockades in this area.
@param blockades The new blockades.
*/
public void setBlockades(List<EntityID> blockades) {
this.blockades.setValue(blockades);
}
/**
Find out if the blockades property has been defined.
@return True if the blockades property has been defined, false otherwise.
*/
public boolean isBlockadesDefined() {
return blockades.isDefined();
}
/**
Undefine the blockades property.
*/
public void undefineBlockades() {
blockades.undefine();
}
/**
Get the neighbours of this area.
@return The neighbours.
*/
public List<EntityID> getNeighbours() {
if (neighbours == null) {
neighbours = new ArrayList<EntityID>();
for (Edge next : edges.getValue()) {
if (next.isPassable()) {
neighbours.add(next.getNeighbour());
}
}
}
return neighbours;
}
/**
Get the edge that crosses to a particular neighbour.
@param neighbour The neighbour ID.
@return The edge that crosses to the given neighbour, or null if no edges border that neighbour.
*/
public Edge getEdgeTo(EntityID neighbour) {
for (Edge next : getEdges()) {
if (neighbour.equals(next.getNeighbour())) {
return next;
}
}
return null;
}
/**
Get the list of apexes for this area.
@return The list of apexes.
*/
public int[] getApexList() {
if (apexList == null) {
List<Edge> e = getEdges();
apexList = new int[e.size() * 2];
int i = 0;
for (Edge next : e) {
apexList[i++] = next.getStartX();
apexList[i++] = next.getStartY();
}
}
return apexList;
}
/**
Get this area as a Java Shape object.
@return A Shape describing this area.
*/
public Shape getShape() {
if (shape == null) {
int[] apexes = getApexList();
int count = apexes.length / 2;
int[] xs = new int[count];
int[] ys = new int[count];
for (int i = 0; i < count; ++i) {
xs[i] = apexes[i * 2];
ys[i] = apexes[i * 2 + 1];
}
shape = new Polygon(xs, ys, count);
}
return shape;
}
private class EdgesListener implements EntityListener {
@Override
public void propertyChanged(Entity e, Property p, Object oldValue, Object newValue) {
if (p == edges) {
shape = null;
apexList = null;
neighbours = null;
}
}
}
}