/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.gef.draw2d.geometry;
/**
* @author Frank Shaka
*/
public class PrecisionPointList {
private int size;
private PrecisionPoint[] points;
private PrecisionRectangle bounds;
public PrecisionPointList() {
this(0);
}
public PrecisionPointList(int size) {
this.size = size;
this.points = new PrecisionPoint[size];
this.bounds = null;
}
public void addAll(PrecisionPointList source) {
ensureCapacity(size + source.size);
System.arraycopy(source.points, 0, points, size, source.size);
size += source.size;
}
public void addPoint(PrecisionPoint p) {
addPoint(p.x, p.y);
}
public void addPoint(double x, double y) {
bounds = null;
int index = size;
ensureCapacity(size + 1);
points[index] = new PrecisionPoint(x, y);
size++;
}
private void ensureCapacity(int newSize) {
if (points.length < newSize) {
PrecisionPoint[] old = points;
points = new PrecisionPoint[newSize];
System.arraycopy(old, 0, points, 0, size);
}
}
public PrecisionRectangle getBounds() {
if (bounds == null) {
bounds = new PrecisionRectangle();
if (size > 0) {
bounds.setLocation(getPoint(0));
for (int i = 1; i < size; i++) {
bounds.union(getPoint(i));
}
}
}
return bounds;
}
public PrecisionPointList getCopy() {
PrecisionPointList result = create();
copyTo(result);
return result;
}
/**
* @param result
*/
protected void copyTo(PrecisionPointList result) {
result.setSize(size);
for (int i = 0; i < size; i++) {
result.setPoint(getPoint(i), i);
}
result.bounds = null;
}
protected PrecisionPointList create() {
return new PrecisionPointList(size);
}
public PrecisionPoint getFirstPoint() {
return getPoint(0);
}
public PrecisionPoint getLastPoint() {
return getPoint(size - 1);
}
public PrecisionPoint getMidPoint() {
if (size % 2 == 0) {
return getPoint(size / 2 - 1).getCenter(getPoint(size / 2));
}
return getPoint(size / 2);
}
public PrecisionPoint getPoint(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size); //$NON-NLS-1$ //$NON-NLS-2$
return points[index];
}
public void insertPoint(PrecisionPoint p, int index) {
if (bounds != null && !bounds.contains(p))
bounds = null;
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size); //$NON-NLS-1$ //$NON-NLS-2$
int length = points.length;
PrecisionPoint[] old = points;
points = new PrecisionPoint[length + 1];
System.arraycopy(old, 0, points, 0, index);
System.arraycopy(old, index, points, index + 1, length - index);
if (p == null) {
points[index] = null;
} else if (points[index] == null) {
points[index] = new PrecisionPoint(p);
} else {
points[index].setLocation(p);
}
size++;
}
public boolean isEmpty() {
return size == 0;
}
public void scale(double amount) {
for (PrecisionPoint p : points) {
if (p != null) {
p.scale(amount);
}
}
bounds = null;
}
public void translate(double dx, double dy) {
if (dx == 0 && dy == 0)
return;
for (PrecisionPoint p : points) {
if (p != null) {
p.translate(dx, dy);
}
}
if (bounds != null)
bounds.translate(dx, dy);
}
public void translate(PrecisionDimension d) {
translate(d.width, d.height);
}
public void removeAllPoints() {
bounds = null;
size = 0;
}
public PrecisionPoint removePoint(int index) {
bounds = null;
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size); //$NON-NLS-1$ //$NON-NLS-2$
PrecisionPoint p = getPoint(index);
if (index != size - 1) {
System
.arraycopy(points, index + 1, points, index, size - index
- 1);
}
size--;
return p;
}
public void reverse() {
PrecisionPoint temp;
for (int i = 0, j = size - 1; i < size; i++, j--) {
temp = points[i];
points[i] = points[j];
points[j] = temp;
}
}
public void setPoint(PrecisionPoint p, int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size); //$NON-NLS-1$ //$NON-NLS-2$
if (bounds != null && !bounds.contains(p))
bounds = null;
if (p == null) {
points[index] = null;
} else if (points[index] == null) {
points[index] = new PrecisionPoint(p);
} else {
points[index].setLocation(p);
}
}
public void setSize(int newSize) {
if (points.length > newSize) {
size = newSize;
return;
}
PrecisionPoint[] newArray = new PrecisionPoint[newSize];
System.arraycopy(points, 0, newArray, 0, points.length);
points = newArray;
size = newSize;
}
public int size() {
return size;
}
public PrecisionPoint[] toArray() {
if (points.length != size) {
PrecisionPoint[] old = points;
points = new PrecisionPoint[size];
System.arraycopy(old, 0, points, 0, size());
}
return points;
}
public String toString() {
StringBuffer sb = new StringBuffer(size * 20 + 22);
sb.append("PrecisionPointList:["); //$NON-NLS-1$
for (int i = 0; i < size; i++) {
PrecisionPoint p = getPoint(i);
if (p != null)
sb.append("(" + p.x + "," + p.y + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (i < size - 1)
sb.append(","); //$NON-NLS-1$
}
sb.append("]"); //$NON-NLS-1$
return sb.toString();
}
}