/* Point.java -- represents a point in 2-D space
   Copyright (C) 1999, 2002 Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt;

import java.awt.geom.Point2D;
import java.io.Serializable;

/**
 * This class represents a point on the screen using cartesian coordinates.
 * Remember that in screen coordinates, increasing x values go from left to
 * right, and increasing y values go from top to bottom.
 *
 * <p>There are some public fields; if you mess with them in an inconsistent
 * manner, it is your own fault when you get invalid results. Also, this
 * class is not threadsafe.
 *
 * @author Per Bothner (bothner@cygnus.com)
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Eric Blake (ebb9@email.byu.edu)
 * @since 1.0
 * @status updated to 1.4
 */
public class Point extends Point2D implements Serializable
{
  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = -5276940640259749850L;

  /**
   * The x coordinate.
   *
   * @see #getLocation()
   * @see #move(int, int)
   * @serial the X coordinate of the point
   */
  public int x;

  /**
   * The y coordinate.
   *
   * @see #getLocation()
   * @see #move(int, int)
   * @serial The Y coordinate of the point
   */
  public int y;

  /**
   * Initializes a new instance of <code>Point</code> representing the
   * coordiates (0,0).
   *
   * @since 1.1
   */
  public Point()
  {
  }

  /**
   * Initializes a new instance of <code>Point</code> with coordinates
   * identical to the coordinates of the specified points.
   *
   * @param p the point to copy the coordinates from
   * @throws NullPointerException if p is null
   */
  public Point(Point p)
  {
    x = p.x;
    y = p.y;
  }

  /**
   * Initializes a new instance of <code>Point</code> with the specified
   * coordinates.
   *
   * @param x the X coordinate
   * @param y the Y coordinate
   */
  public Point(int x, int y)
  {
    this.x = x;
    this.y = y;
  }

  /**
   * Get the x coordinate.
   *
   * @return the value of x, as a double
   */
  public double getX()
  {
    return x;
  }

  /**
   * Get the y coordinate.
   *
   * @return the value of y, as a double
   */
  public double getY()
  {
    return y;
  }

  /**
   * Returns the location of this point. A pretty useless method, as this
   * is already a point.
   *
   * @return a copy of this point
   * @see #setLocation(Point)
   * @since 1.1
   */
  public Point getLocation()
  {
    return new Point(x, y);
  }

  /**
   * Sets this object's coordinates to match those of the specified point.
   *
   * @param p the point to copy the coordinates from
   * @throws NullPointerException if p is null
   * @since 1.1
   */
  public void setLocation(Point p)
  {
    x = p.x;
    y = p.y;
  }

  /**
   * Sets this object's coordinates to the specified values.  This method
   * is identical to the <code>move()</code> method.
   *
   * @param x the new X coordinate
   * @param y the new Y coordinate
   */
  public void setLocation(int x, int y)
  {
    this.x = x;
    this.y = y;
  }

  /**
   * Sets this object's coordinates to the specified values.  This method
   * performs normal casting from double to int, so you may lose precision.
   *
   * @param x the new X coordinate
   * @param y the new Y coordinate
   */
  public void setLocation(double x, double y)
  {
    this.x = (int) x;
    this.y = (int) y;
  }

  /**
   * Sets this object's coordinates to the specified values.  This method
   * is identical to the <code>setLocation(int, int)</code> method.
   *
   * @param x the new X coordinate
   * @param y the new Y coordinate
   */
  public void move(int x, int y)
  {
    this.x = x;
    this.y = y;
  }

  /**
   * Changes the coordinates of this point such that the specified
   * <code>dx</code> parameter is added to the existing X coordinate and
   * <code>dy</code> is added to the existing Y coordinate.
   *
   * @param dx the amount to add to the X coordinate
   * @param dy the amount to add to the Y coordinate
   */
  public void translate(int dx, int dy)
  {
    x += dx;
    y += dy;
  }

  /**
   * Tests whether or not this object is equal to the specified object.
   * This will be true if and only if the specified object is an instance
   * of Point2D and has the same X and Y coordinates.
   *
   * @param obj the object to test against for equality
   * @return true if the specified object is equal
  */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof Point2D))
      return false;
    Point2D p = (Point2D) obj;
    return x == p.getX() && y == p.getY();
  }

  /**
   * Returns a string representation of this object. The format is:
   * <code>getClass().getName() + "[x=" + x + ",y=" + y + ']'</code>.
   *
   * @return a string representation of this object
   */
  public String toString()
  {
    return getClass().getName() + "[x=" + x + ",y=" + y + ']';
  }
} // class Point
