package test;
import java.awt.Graphics;

//invariant xMin() <= xMax() && yMin() <= yMax() && centerInBounds()

abstract public class Sprite3 {
	private double xMin, yMin, xMax, yMax;
	private double xCenter, yCenter;
	private double speed, heading;

	public Sprite3(double xMin, double xMax, double yMin, double yMax) {
		this.xMax = xMax;
		this.xMin = xMin;
		this.yMax = yMax;
		this.yMin = yMin;

		xCenter = (xMin+xMax)/2;
		yCenter = (yMin+yMax)/2;
		speed = 10;
		heading = 0;
	}

	// requires pointInBounds(x,y)
	abstract public boolean contains(double x, double y);

	// ensures that sprite is drawn on screen
	abstract public void draw(Graphics screen);

	public boolean pointInBounds(double x, double y) {
		return x <= xMax() && x >= xMin() && y <= yMax() && y >= yMin();
	}

	public boolean centerInBounds() {
		return pointInBounds(xCenter(), yCenter());
	}

	// ensures that headingFromCenter(old xCenter(), old yCenter()) == heading() &&
	//              distanceFromCenter(old xCenter(), old yCenter()) == speed(),
	//              assuming no wraparound
	// ensures that sprite wraps around as needed if it goes out of bounds
	public void move() {
		xCenter += speed * Math.cos(heading);
		yCenter += speed * Math.sin(heading);

		if (xCenter > xMax) {xCenter = xMin;}
		if (yCenter > yMax) {yCenter = yMin;}
		if (xCenter < xMin) {xCenter = xMax;}
		if (yCenter < yMin) {yCenter = yMax;}
	}

	public double speed() {
		return speed;
	}

	public double heading() {
		return heading;
	}

	public double xCenter() {
		return xCenter;
	}

	public double yCenter() {
		return yCenter;
	}

	public double xMin() {
		return xMin;
	}

	public double yMin() {
		return yMin;
	}

	public double xMax() {
		return xMax;
	}

	public double yMax() {
		return yMax;
	}

	static public double distance(double x1, double y1, double x2, double y2) {
		double xDiff = x2 - x1;
		double yDiff = y2 - y1;
		return Math.sqrt(xDiff*xDiff + yDiff*yDiff);
	}

	public double distanceFromCenter(double x, double y) {
		return distance(xCenter, yCenter, x, y);
	}
	
	public double headingFromCenter(double x, double y) {
		return Math.atan2(yCenter - y, xCenter - x);
	}
}
