/* 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 point 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
