/*
 * Created on Jan 23, 2005
 *
 * Advanced Data Management Group
 * Center for Advanced Computing and Informatics Studies
 * University of Puerto Rico, Mayaguez
 * 
 */
package edu.uprm.admg.point;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * @author Manuel Rodriguez
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class Point {
	// Priate fields
	
	// X coordinate
	private int X;
	
	// Y coordinate
	private int Y;
	
	/**
	 * Default constructor. Creates a new point set a the origin (i.e., (0,0)).
	 *
	 */
	public Point(){
		X = 0;
		Y = 0;
	}
	
	/**
	 * Constructor that creates a new point based on a specific set of coordinates.
	 * @param X - value of the X coordinate
	 * @param Y - value of the Y coordinate
	 */
	public Point(int X, int Y){
		this.X = X;
		this.Y = Y;
	}
	
	/**
	 * Copy constructor used to make a new Point which is an identical copy of
	 * the argument point P. 
	 * @param P - the point used to make a new point.
	 */
	public Point(Point P) {
		
		this.X = P.getX();
		this.Y = P.getY();
	}
	
	
	// Getters 
	
	/**
	 * Returns the value of the X coordinate. 
	 * @return The value of the X coordinate.
	 */
	public int getX(){
		return X;
	}
	
	/**
	 * Returns the value of the Y coordinate.
	 * @return The value of the Y coordinate.
	 */
	public int getY(){
		return Y;
	}
	
	
	// Setters
	/**
	 * Set the value of the X coordinate to a new value. 
	 * @param X - the new value for coordinate X.
	 */
	public void setX(int X) {
		this.X = X;
		
	}

	/**
	 * Set the value of the Y coordinate to a new value.
	 * @param Y - the new value for the coordinate Y.
	 */
	public void setY(int Y) {
		this.Y = Y;
		
	}
	
	/**
	 * Method used to compute the distance from this point to point P.
	 * The function receives as paramater the other point, and returns 
	 * the distance between the two.
	 * @param P - the point whose distance from this point is to be computed
	 * @return The distance between this point and point P.
	 */
	public double distance(Point P){
		double res = 0.0, temp1 = 0.0, temp2 = 0.0;
		
		temp1 = this.getX() - P.getX();
		temp1 *= temp1;
		temp2 = this.getY() - P.getY();
		temp2*= temp2;
		res = Math.sqrt(temp1 + temp2);
		return res;
	}

	/**
	 * Computes the distance from this point to the origin point (0,0).
	 * @return The distance to the origin point (0,0).
	 */
	public double distanceOrigin(){
		Point P = new Point();
		
		return distance(P);
	}
	
	/**
	 * Adds this point to another point P, and returns a new Point with the result.
	 * The operation is equivalten to P3 = P1 + P2, where P1 is this point, P2 is the 
	 * argument P, and P3 is the resulting point. Point P3 has an X coordinate whose
	 * value is P1.X + P2.X . Likewise, P3 has a Y coordinate whose value is 
	 * P1.Y + P2.Y.
	 * @param P - the point to the be sum with this point.
	 * @return A new point resulting from adding this point with point P.
	 */
	public Point sum(Point P){
		Point result = new Point();
		int temp = 0;
		
		temp = this.getX() + P.getX();
		result.setX(temp);
		
		temp = this.getY() + P.getY();
		result.setY(temp);
		
		return result;
	}


	/**
	 * Determines if two this point is equal to another point P, based on 
	 * the values of the coordinates. Returns true if the corresponding coordinates
	 * are the same, or false otherwise.
	 * @param P - the point to the compare with this point.
	 * @return True if this point is the equal to point P, or false otherwise.
	 */
	public boolean equals(Point P){
		return ((this.getX() == P.getX()) && 
				(this.getY() == P.getY()));
	}
	
	public String toString(){
		StringBuffer strBuf = new StringBuffer();
		
		strBuf.append("(");
		strBuf.append(getX());
		strBuf.append(",");
		strBuf.append(getY());
		strBuf.append(")");
		return strBuf.toString();
	}

	/**
	 * @param in
	 * @throws IOException
	 */
	public void read(BufferedReader in) throws IOException {
		String data = null;
		StringTokenizer strTok = null;
		String token = null;
		
		data = in.readLine();
		strTok = new StringTokenizer(data);
		token = strTok.nextToken();
		this.X = Integer.parseInt(token);
		token = strTok.nextToken();
		this.Y = Integer.parseInt(token);
	}
}
