package org.erikaredmark.monkeyshines;
import org.erikaredmark.monkeyshines.bounds.Boundable;
import org.erikaredmark.monkeyshines.bounds.IPoint2D;
/**
*
* Represents a clipping region in the game. A clipping region is nothing but a rectangle that indicates the bounds of some 'thing', whether
* it be graphics or collision.
* <p/>
* Objects of this type are mutable to a point. The width and height of a clipping rectangle may not be changed, but the x, y top-left
* corner may be changed easily. The position of the clipping region MAY be out of drawable bounds; it is up to other code to ignore out-
* of-bounds positions.
*
* @author Erika Redmark
*
*/
public class ClippingRectangle extends Boundable {
private ClippingRectangle(final int x, final int y, final int width, final int height) {
super.location = Point2D.of(x, y);
super.size = ImmutablePoint2D.of(width, height);
}
private ClippingRectangle(ClippingRectangle cpy) {
super.size = ImmutablePoint2D.of(cpy.width(), cpy.height() );
super.size = ImmutablePoint2D.of(cpy.x(), cpy.y() );
}
/**
*
* Returns a copy of this clipping rectangle's location so it may not be modified by clients. The copy may be
* modified without affecting the original.
*
*/
@Override public IPoint2D getLocation() {
return Point2D.from(super.location);
}
/**
* Returns a clipping rectangle whose location and size are all specified. Note that location is mutable, but size is immutable
*
* @param width
* @param height
* @param x
* @param y
*
* @return
* a new instance of a clipping rectangle
*/
public static ClippingRectangle of(final int x, final int y, final int width, final int height) { return new ClippingRectangle(width, height, x, y); }
/**
* Returns a clipping rectangle whose location is 0,0 (mutable) and whose width and height is as specified (immutable)
*
* @param width
* @param height
*
* @return
* a new instance of a clipping rectangle with the given features
*/
public static ClippingRectangle of(final int width, final int height) { return new ClippingRectangle(0, 0, width, height); }
/**
* Returns a new clipping rectangle whose properties are a copy of the passed clipping rectangle.
*
* @param other
* Clipping rectangle to copy from
*
* @return
* new instance of a clipping rectangle initialised to the fields of the passed one. This is a deep-copy.
*/
public static ClippingRectangle of(final ClippingRectangle other) { return new ClippingRectangle(other); }
public int x() { return super.location.x(); }
public int y() { return super.location.y(); }
public int width() { return super.size.x(); }
public int height() { return super.size.y(); }
/**
* Moves the clipping region to a new location, keeping the same size.
*
* @param X
* new x location for upper-left point
*
* @param Y
* new y location for upper-left point
*/
public void move(final int x, final int y) { ((Point2D)super.location).setX(x); ((Point2D)super.location).setY(y); }
public void setX(final int x) { ((Point2D)super.location).setX(x); }
public void setY(final int y) { ((Point2D)super.location).setY(y); }
/**
*
* Translates the region the number of units left and down. Use negative values to indicate a reverse direction (right and up)
*
* @param unitsX
* positive for n units right, negative for n units left
*
* @param unitsDown
* positive for n units down, negative for n units up
*
*/
public void translate(final int unitsX, final int unitsY) { ((Point2D)super.location).translateX(unitsX); ((Point2D)super.location).translateY(unitsY); }
public void translateX(final int units) { ((Point2D)super.location).translateX(units); }
public void translateY(final int units) { ((Point2D)super.location).translateY(units); }
}