// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.resource.are.viewer;
import java.awt.Color;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import org.infinity.datatype.DecNumber;
import org.infinity.datatype.Flag;
import org.infinity.datatype.HexNumber;
import org.infinity.datatype.SectionOffset;
import org.infinity.gui.layeritem.AbstractLayerItem;
import org.infinity.gui.layeritem.ShapedLayerItem;
import org.infinity.resource.Viewable;
import org.infinity.resource.vertex.Vertex;
import org.infinity.resource.wed.WallPolygon;
import org.infinity.resource.wed.WedResource;
/**
* Handles specific layer type: ARE/Wall Polygon
*/
public class LayerObjectWallPoly extends LayerObject
{
private static final Color[] Color = {new Color(0xFF005046, true), new Color(0xFF005046, true),
new Color(0x8020A060, true), new Color(0xA030B070, true)};
private final WallPolygon wall;
private final Point location = new Point();
private ShapedLayerItem item;
private Point[] shapeCoords;
public LayerObjectWallPoly(WedResource parent, WallPolygon wallPoly)
{
super(ViewerConstants.RESOURCE_WED, "Wall Poly", WallPolygon.class, parent);
this.wall = wallPoly;
init();
}
@Override
public Viewable getViewable()
{
return wall;
}
@Override
public Viewable[] getViewables()
{
return new Viewable[]{wall};
}
@Override
public AbstractLayerItem getLayerItem()
{
return item;
}
@Override
public AbstractLayerItem getLayerItem(int type)
{
return (type == 0) ? item : null;
}
@Override
public AbstractLayerItem[] getLayerItems()
{
return new AbstractLayerItem[]{item};
}
@Override
public void reload()
{
init();
}
@Override
public void update(double zoomFactor)
{
if (item != null) {
item.setItemLocation((int)(location.x*zoomFactor + (zoomFactor / 2.0)),
(int)(location.y*zoomFactor + (zoomFactor / 2.0)));
Polygon poly = createPolygon(shapeCoords, zoomFactor);
normalizePolygon(poly);
item.setShape(poly);
}
}
@Override
public Point getMapLocation()
{
return location;
}
@Override
public Point[] getMapLocations()
{
return new Point[]{location};
}
private void init()
{
if (wall != null) {
shapeCoords = null;
String msg = "";
Polygon poly = null;
Rectangle bounds = null;
int count = 0;
try {
int baseOfs = ((SectionOffset)getParentStructure().getAttribute(WedResource.WED_OFFSET_WALL_POLYGONS)).getValue();
int ofs = wall.getOffset();
count = (ofs - baseOfs) / wall.getSize();
Flag flags = (Flag)wall.getAttribute(WallPolygon.WED_POLY_FLAGS);
msg = String.format("Wall polygon #%1$d %2$s", count,
createFlags(flags, org.infinity.resource.wed.Polygon.s_flags));
int vNum = ((DecNumber)wall.getAttribute(WallPolygon.WED_POLY_NUM_VERTICES)).getValue();
int vOfs = ((HexNumber)getParentStructure().getAttribute(WedResource.WED_OFFSET_VERTICES)).getValue();
int startIdx = flags.isFlagSet(2) ? 2 : 0; // skipping first two vertices for "hovering walls"
shapeCoords = loadVertices(wall, vOfs, startIdx, vNum - startIdx, Vertex.class);
poly = createPolygon(shapeCoords, 1.0);
bounds = normalizePolygon(poly);
} catch (Exception e) {
e.printStackTrace();
if (shapeCoords == null) {
shapeCoords = new Point[0];
}
if (poly == null) {
poly = new Polygon();
}
if (bounds == null) {
bounds = new Rectangle();
}
}
location.x = bounds.x; location.y = bounds.y;
item = new ShapedLayerItem(location, wall, msg, poly);
item.setName(getCategory());
item.setToolTipText(msg);
item.setStrokeColor(AbstractLayerItem.ItemState.NORMAL, Color[0]);
item.setStrokeColor(AbstractLayerItem.ItemState.HIGHLIGHTED, Color[1]);
item.setFillColor(AbstractLayerItem.ItemState.NORMAL, Color[2]);
item.setFillColor(AbstractLayerItem.ItemState.HIGHLIGHTED, Color[3]);
item.setStroked(true);
item.setFilled(true);
item.setVisible(isVisible());
}
}
// Returns a flags string
private String createFlags(Flag flags, String[] desc)
{
if (flags != null) {
int numFlags = 0;
for (int i = 0, size = flags.getSize() << 3; i < size; i++) {
if (flags.isFlagSet(i)) {
numFlags++;
}
}
if (numFlags > 0) {
StringBuilder sb = new StringBuilder("[");
for (int i = 0, size = flags.getSize() << 3; i < size; i++) {
if (flags.isFlagSet(i)) {
numFlags--;
if (desc != null && i+1 < desc.length) {
sb.append(desc[i+1]);
} else {
sb.append("Bit " + i);
}
if (numFlags > 0) {
sb.append(", ");
}
}
}
sb.append("]");
return sb.toString();
}
}
return "[No flags]";
}
}