package com.revolsys.geometry.model.segment;
import java.util.Iterator;
import java.util.NoSuchElementException;
import com.revolsys.geometry.model.Geometry;
import com.revolsys.geometry.model.GeometryFactory;
import com.revolsys.geometry.model.impl.AbstractLineString;
import com.revolsys.geometry.model.vertex.Vertex;
public class GeometryCollectionSegment extends AbstractLineString implements Segment {
private static final long serialVersionUID = 1L;
private final Geometry geometryCollection;
private int partIndex = -1;
private Segment segment;
public GeometryCollectionSegment(final Geometry geometryCollection, final int... segmentId) {
super();
this.geometryCollection = geometryCollection;
setSegmentId(segmentId);
}
@Override
public GeometryCollectionSegment clone() {
return (GeometryCollectionSegment)super.clone();
}
@Override
public int getAxisCount() {
return this.geometryCollection.getAxisCount();
}
@Override
public double getCoordinate(final int index, final int axisIndex) {
if (this.segment == null) {
return Double.NaN;
} else {
return this.segment.getCoordinate(index, axisIndex);
}
}
@Override
public double[] getCoordinates() {
final int axisCount = getAxisCount();
final double[] coordinates = new double[axisCount * 2];
for (int vertexIndex = 0; vertexIndex < 2; vertexIndex++) {
for (int axisIndex = 0; axisIndex < axisCount; axisIndex++) {
coordinates[vertexIndex * axisCount + axisIndex] = getCoordinate(vertexIndex, axisIndex);
}
}
return coordinates;
}
@SuppressWarnings("unchecked")
@Override
public <V extends Geometry> V getGeometry() {
return (V)this.geometryCollection;
}
public Geometry getGeometryCollection() {
return getGeometry();
}
@Override
public GeometryFactory getGeometryFactory() {
return this.geometryCollection.getGeometryFactory();
}
@Override
public Vertex getGeometryVertex(final int index) {
final Geometry geometryCollection = this.geometryCollection;
if (index == 0) {
getSegmentId().clone();
return geometryCollection.getVertex(getSegmentId());
} else if (index == 1) {
final int[] segmentId = getSegmentId();
segmentId[segmentId.length - 1]++;
return geometryCollection.getVertex(segmentId);
} else {
return null;
}
}
@Override
public int getPartIndex() {
return this.partIndex;
}
@Override
public int[] getSegmentId() {
if (this.partIndex < 0) {
return new int[] {
-1
};
} else if (this.segment == null) {
return new int[] {
this.partIndex
};
} else {
final int[] partSegmentId = this.segment.getSegmentId();
final int[] segmentId = new int[partSegmentId.length + 1];
segmentId[0] = this.partIndex;
System.arraycopy(partSegmentId, 0, segmentId, 1, partSegmentId.length);
return segmentId;
}
}
@Override
public double getX(final int vertexIndex) {
if (this.segment == null) {
return Double.NaN;
} else {
return this.segment.getX(vertexIndex);
}
}
@Override
public double getY(final int vertexIndex) {
if (this.segment == null) {
return Double.NaN;
} else {
return this.segment.getY(vertexIndex);
}
}
@Override
public double getZ(final int vertexIndex) {
if (this.segment == null) {
return Double.NaN;
} else {
return this.segment.getZ(vertexIndex);
}
}
@Override
public boolean hasNext() {
if (this.partIndex == -2) {
return false;
} else {
final Geometry geometryCollection = this.geometryCollection;
int partIndex = this.partIndex;
Segment segment = this.segment;
if (segment != null && !segment.hasNext()) {
partIndex++;
segment = null;
}
while (segment == null && partIndex < geometryCollection.getGeometryCount()) {
if (partIndex >= 0) {
final Geometry part = geometryCollection.getGeometry(partIndex);
if (part != null) {
final Iterator<Segment> segmentIterator = part.segments().iterator();
if (segmentIterator.hasNext()) {
return true;
} else {
segment = null;
}
}
}
if (partIndex > -2) {
partIndex++;
}
}
if (segment == null) {
return false;
} else {
return segment.hasNext();
}
}
}
@Override
public boolean isLineClosed() {
return this.segment.isLineClosed();
}
@Override
public boolean isLineEnd() {
if (this.segment == null) {
return false;
} else {
return this.segment.isLineEnd();
}
}
@Override
public boolean isLineStart() {
if (this.segment == null) {
return false;
} else {
return this.segment.isLineStart();
}
}
@Override
public Segment next() {
if (this.partIndex == -2) {
throw new NoSuchElementException();
} else {
final Geometry geometryCollection = this.geometryCollection;
if (this.segment != null && !this.segment.hasNext()) {
this.partIndex++;
this.segment = null;
}
while (this.segment == null && this.partIndex < geometryCollection.getGeometryCount()) {
if (this.partIndex >= 0) {
final Geometry part = geometryCollection.getGeometry(this.partIndex);
if (part != null) {
final Iterator<Segment> segmentIterator = part.segments().iterator();
if (segmentIterator.hasNext()) {
this.segment = segmentIterator.next();
return this.segment;
} else {
this.segment = null;
}
}
}
if (this.partIndex > -2) {
this.partIndex++;
}
}
if (this.segment != null && this.segment.hasNext()) {
return this.segment.next();
} else {
throw new NoSuchElementException();
}
}
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removing vertices not supported");
}
@Override
public void setSegmentId(final int... segmentId) {
this.segment = null;
if (segmentId.length > 0) {
this.partIndex = segmentId[0];
final Geometry geometryCollection = this.geometryCollection;
if (this.partIndex >= 0 && this.partIndex < geometryCollection.getGeometryCount()) {
final Geometry part = geometryCollection.getGeometry(this.partIndex);
if (part != null) {
final int[] partSegmentId = new int[segmentId.length - 1];
System.arraycopy(segmentId, 1, partSegmentId, 0, partSegmentId.length);
this.segment = part.getSegment(partSegmentId);
}
}
} else {
this.partIndex = -2;
}
}
}