// 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.wed;
import java.nio.ByteBuffer;
import org.infinity.datatype.Bitmap;
import org.infinity.datatype.DecNumber;
import org.infinity.datatype.HexNumber;
import org.infinity.datatype.RemovableDecNumber;
import org.infinity.datatype.SectionCount;
import org.infinity.datatype.SectionOffset;
import org.infinity.datatype.TextString;
import org.infinity.resource.AbstractStruct;
import org.infinity.resource.AddRemovable;
import org.infinity.resource.HasAddRemovable;
import org.infinity.util.io.StreamUtils;
public final class Door extends AbstractStruct implements AddRemovable, HasAddRemovable
{
// WED/Door-specific field labels
public static final String WED_DOOR = "Door";
public static final String WED_DOOR_NAME = "Name";
public static final String WED_DOOR_IS_DOOR = "Is door?";
public static final String WED_DOOR_TILEMAP_LOOKUP_INDEX = "Tilemap lookup index";
public static final String WED_DOOR_NUM_TILEMAP_INDICES = "# tilemap indices";
public static final String WED_DOOR_NUM_POLYGONS_OPEN = "# polygons open";
public static final String WED_DOOR_NUM_POLYGONS_CLOSED = "# polygons closed";
public static final String WED_DOOR_OFFSET_POLYGONS_OPEN = "Polygons open offset";
public static final String WED_DOOR_OFFSET_POLYGONS_CLOSED = "Polygons closed offset";
public static final String WED_DOOR_TILEMAP_INDEX = "Tilemap index";
public static final String[] s_noyes = {"No", "Yes"};
public Door() throws Exception
{
super(null, WED_DOOR, StreamUtils.getByteBuffer(26), 0);
}
public Door(AbstractStruct superStruct, ByteBuffer buffer, int offset, int number) throws Exception
{
super(superStruct, WED_DOOR + " " + number, buffer, offset);
}
// --------------------- Begin Interface HasAddRemovable ---------------------
@Override
public AddRemovable[] getAddRemovables() throws Exception
{
return new AddRemovable[]{new OpenPolygon(), new ClosedPolygon()};
}
@Override
public AddRemovable confirmAddEntry(AddRemovable entry) throws Exception
{
return entry;
}
@Override
public boolean confirmRemoveEntry(AddRemovable entry) throws Exception
{
return true;
}
// --------------------- End Interface HasAddRemovable ---------------------
//--------------------- Begin Interface AddRemovable ---------------------
@Override
public boolean canRemove()
{
return true;
}
//--------------------- End Interface AddRemovable ---------------------
@Override
protected void setAddRemovableOffset(AddRemovable datatype)
{
if (datatype instanceof RemovableDecNumber) {
int offset = ((HexNumber)getSuperStruct().getAttribute(WedResource.WED_OFFSET_DOOR_TILEMAP_LOOKUP)).getValue();
int index = getTilemapIndex().getValue();
datatype.setOffset(offset + index * 2);
}
}
public DecNumber getTilemapIndex()
{
return (DecNumber)getAttribute(WED_DOOR_TILEMAP_LOOKUP_INDEX);
}
public void readVertices(ByteBuffer buffer, int offset) throws Exception
{
for (int i = 0; i < getFieldCount(); i++) {
Object o = getField(i);
if (o instanceof Polygon)
((Polygon)o).readVertices(buffer, offset);
}
}
public void updatePolygonsOffset(int offset)
{
int polyOffset = Integer.MAX_VALUE;
for (int i = 0; i < getFieldCount(); i++) {
Object o = getField(i);
if (o instanceof Polygon) {
polyOffset = Math.min(polyOffset, ((Polygon)o).getOffset());
}
}
if (polyOffset != Integer.MAX_VALUE) {
offset = polyOffset;
}
((SectionOffset)getAttribute(WED_DOOR_OFFSET_POLYGONS_OPEN)).setValue(offset);
for (int i = 0; i < getFieldCount(); i++) {
if (getField(i) instanceof OpenPolygon) {
offset += 18;
}
}
((SectionOffset)getAttribute(WED_DOOR_OFFSET_POLYGONS_CLOSED)).setValue(offset);
for (int i = 0; i < getFieldCount(); i++) {
if (getField(i) instanceof ClosedPolygon) {
offset += 18;
}
}
}
@Override
public int read(ByteBuffer buffer, int offset) throws Exception
{
addField(new TextString(buffer, offset, 8, WED_DOOR_NAME));
addField(new Bitmap(buffer, offset + 8, 2, WED_DOOR_IS_DOOR, s_noyes));
DecNumber indexTileCell = new DecNumber(buffer, offset + 10, 2, WED_DOOR_TILEMAP_LOOKUP_INDEX);
addField(indexTileCell);
SectionCount countTileCell = new SectionCount(buffer, offset + 12, 2, WED_DOOR_NUM_TILEMAP_INDICES,
RemovableDecNumber.class);
addField(countTileCell);
SectionCount countOpen = new SectionCount(buffer, offset + 14, 2, WED_DOOR_NUM_POLYGONS_OPEN, OpenPolygon.class);
addField(countOpen);
SectionCount countClosed = new SectionCount(buffer, offset + 16, 2, WED_DOOR_NUM_POLYGONS_CLOSED,
ClosedPolygon.class);
addField(countClosed);
SectionOffset offsetOpen = new SectionOffset(buffer, offset + 18, WED_DOOR_OFFSET_POLYGONS_OPEN,
OpenPolygon.class);
addField(offsetOpen);
SectionOffset offsetClosed = new SectionOffset(buffer, offset + 22, WED_DOOR_OFFSET_POLYGONS_CLOSED,
ClosedPolygon.class);
addField(offsetClosed);
for (int i = 0; i < countOpen.getValue(); i++) {
addField(new OpenPolygon(this, buffer, offsetOpen.getValue() + 18 * i, i));
}
for (int i = 0; i < countClosed.getValue(); i++) {
addField(new ClosedPolygon(this, buffer, offsetClosed.getValue() + 18 * i, i));
}
if (getSuperStruct() != null) {
HexNumber offsetTileCell = (HexNumber)getSuperStruct().getAttribute(WedResource.WED_OFFSET_DOOR_TILEMAP_LOOKUP);
for (int i = 0; i < countTileCell.getValue(); i++) {
addField(new RemovableDecNumber(buffer, offsetTileCell.getValue() +
2 * (indexTileCell.getValue() + i), 2,
WED_DOOR_TILEMAP_INDEX + " " + i));
}
}
return offset + 26;
}
}