package j3deditor.bin.hierarchy.util;


/**
 * A point representing a location in (x, y) coordinate space, specified in integer precision.
 * 
 * @author Risto Seene
 */
public class J3DePoint2D{

	/** the x coordinate */
	private int x;
	
	/** the y coordinate */
	private int y;


	/**
	 * Creates an instance of <code>J3DePoint2D</code> at (0, 0).
	 */
	public J3DePoint2D(){
		x = y = 0;
	}

	/**
	 * Creates an instance of <code>J3DePoint2D</code> at (x, y).
	 * 
	 * @param x
	 * 	x coordinate
	 * @param y
	 * 	y coordinate
	 */
	public J3DePoint2D(int x, int y){
		this.x = x;
		this.y = y;
	}

	/**
	 * Creates an instance of <code>J3DePoint2D</code> with the same location
	 * as the specified <code>J3DePoint2D</code>.
	 * 
	 * @param p
	 * 	a point
	 */
	public J3DePoint2D(J3DePoint2D p){
		this(p.getX(), p.getY());
	}


	/**
	 * Sets the x coordinate of this point.
	 * 
	 * @param x
	 * 	new x coordinate value
	 */
	public void setX(int x){
		this.x = x;
	}

	/**
	 * Sets the y coordinate of this point.
	 * 
	 * @param y
	 * 	new y coordinate value
	 */
	public void setY(int y){
		this.y = y;
	}

	/**
	 * Sets the location of this point.
	 * 
	 * @param x
	 * 	new x coordinate value
	 * @param y
	 * 	new y coordinate value
	 */
	public void setCoordinates(int x, int y){
		this.x = x;
		this.y = y;
	}

	/**
	 * Sets the location of this point.
	 * 
	 * @param p
	 * 	the specified location
	 */
	public void setCoordinates(J3DePoint2D p){
		setCoordinates(p.getX(), p.getY());
	}

	/**
	 * Returns the x coordiante of this point.
	 * 
	 * @return the x coordiante of this point
	 */
	public int getX(){
		return x;
	}

	/**
	 * Returns the x coordiante of this point.
	 * 
	 * @return the y coordiante of this point
	 */
	public int getY(){
		return y;
	}
	
	/**
	 * Sets each component of this point to its absolute value.
	 */
	public void absolute(){
		x = Math.abs(x);
		y = Math.abs(y);
	}
	
	/**
	 * Negates the value of this point.
	 */
	public void negate(){
		x = -x;
		y = -y;
	}
	
	
	/**
	 * Returns new <code>J3DePoint2D</code> which value is
	 * the vector sum of points p1 and p2.
	 * 
	 * @param p1
	 * 	the first point
	 * @param p2
	 * 	the second point
	 * @return new <code>J3DePoint2D</code> which value is
	 * 	the vector sum of points p1 and p2
	 */
	public static J3DePoint2D add(J3DePoint2D p1, J3DePoint2D p2){
		return new J3DePoint2D(p1.getX() + p2.getX(), p1.getY() + p2.getY());
	}
	
	/**
	 * Returns new <code>J3DePoint2D</code> which value is
	 * the vector difference of points p1 and p2.
	 * 
	 * @param p1
	 * 	the first point
	 * @param p2
	 * 	the second point
	 * @return new <code>J3DePoint2D</code> which value is
	 * 	the vector difference of points p1 and p2
	 */
	public static J3DePoint2D sub(J3DePoint2D p1, J3DePoint2D p2){
		return new J3DePoint2D(p1.getX() - p2.getX(), p1.getY() - p2.getY());
	}
	
	
	/**
	 * Returns the length of the vector
	 * represented by this J3DePoint2D.
	 * 
	 * @return Returns the length of the vector
	 * 	represented by this J3DePoint2D
	 */
	public double getVectorLength(){
		return Math.sqrt(this.x * this.x + this.y * this.y);
	}
	
	/**
	 * Returns the angle of the vector
	 * represented by this J3DePoint2D.
	 * 
	 * @return the angle of the vector
	 * 	represented by this J3DePoint2D
	 */
	public double getVectorAngle(){
		return Math.atan2(this.getY(), this.getX());
	}
	
	
	/**
	 * Returns true if the Object object is of type J3DePoint2D and both
	 * coordinates in it are equal to the corresponding coordinates in this J3DePoint2D.
	 * 
	 * @param object
	 * 	the Object with which the comparison is made
	 * @return true if the Object object is of type J3DePoint2D and both
	 * 	coordinates in it are equal to the corresponding coordinates in this J3DePoint2D
	 */
	@Override
	public boolean equals(Object object){
		if(object instanceof J3DePoint2D){
			J3DePoint2D p = (J3DePoint2D)object;
			return (p.getX() == this.x && p.getY() == this.y);
		}
		return false;
	}

	/**
	 * Returns the <code>String</code> representation of this object.
	 * 
	 * @return the <code>String</code> representation of this object
	 */
	@Override
	public String toString(){
		return this.x + " x " + this.y;
	}
	
}
