// Copyright (C) 1996 DIMACS Center, Rutgers, The State University of New Jersey
// Author(s): ??

// This software is copyrighted by the DIMACS Center at Rutgers, The State
// University of New Jersey.  IT IS PROVIDED AS IS, AND THE AUTHORS, DIMACS, AND
// RUTGERS, THE STATE UNIVERSITY OF NEW JERSEY  DISCLAIM
// ALL LIABILITY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
// DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
// IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
// NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
// MODIFICATIONS.

// The authors hereby grant permission to use, copy, modify, distribute,
// and license this software and its documentation for any purpose, provided
// that existing copyright notices are retained in all copies and that this
// notice is included verbatim in any distributions. No written agreement,
// license, or royalty fee is required for any of the authorized uses.
// Modifications to this software may be copyrighted by their authors
// and need not follow the licensing terms described here, provided that
// the new terms are clearly indicated on the first page of each file where
// they apply.

// Last File Update: 31-Jul-1996
// 

#ifndef Point_h
#define Point_h

#include <fstream.h>
#include <math.h>
#include <LINK/basic/general.h>


class Point {
public:
    Point()				: x(0), y(0) {}
    Point(short x_val, short y_val)	: x(x_val), y(y_val) {}

		// get and set individual coordinates
    short	xValue() const		{ return x; }
    short	xValue(short x_val)	{ return x = x_val; }
    short	yValue() const		{ return y; }
    short	yValue(short y_val)	{ return y = y_val; }

		// addition, subtraction and negation of Points
    Point	operator=(const Point& p)
				{ x = p.x; y = p.y; return *this; }
    Point	operator+(const Point& p) const
				{ return Point(x+p.x, y+p.y); }
    Point	operator-() const
				{ return Point(-x,-y); }
    Point	operator-(const Point& p) const
				{ return Point(x-p.x, y-p.y); }

		// scaling of points
    friend Point operator*(const Point& p, int i);
    friend Point operator*(int i, const Point& p);
    friend Point operator*(const Point& p, float f);
    friend Point operator*(float f, const Point& p);
    int		operator*(const Point& p) const { return x*p.x + y*p.y; }

		// comparison operators
    Bool	operator==(const Point& p) const
				{ return (x == p.x && y == p.y); }
    Bool	operator!=(const Point& p) const
				{ return (x != p.x || y != p.y); }
    Bool	operator<(const Point& p) const
				{ return (y < p.y && x < p.x); }
    Bool	operator<=(const Point& p) const
				{ return (y <= p.y && x <= p.x); }
    Bool	operator>(const Point& p) const
				{ return (y > p.y && x > p.x); }
    Bool	operator>=(const Point& p) const
				{ return (y >= p.y && x >= p.x); }

		// translation and scaling of Points
    void	operator+=(const Point& p)	{ x += p.x; y += p.y; }
    void	operator-=(const Point& p)	{ x -= p.x; y -= p.y; }
    void	operator*=(int s)		{ x *= s; y *= s; }

		// other functions
    double	distance(const Point& p) const
				{ return hypot(x-p.x, y-p.y); }
    Point	transpose() const		{ return Point(y,x); }
    Point	max(const Point& p) const;
    Point	min(const Point& p) const;
    Bool	withinEpsilon(const Point& p, int eps) const;

    friend ostream& operator<<(ostream& stream, Point p);

    int		x;
    int		y;
};

Point operator*(const Point& p, int i);
Point operator*(int i, const Point& p);
Point operator*(const Point& p, float f);
Point operator*(float f, const Point& p);


#endif
