/******************************************************************************  		
 * Company:         SINED GmbH
 * Author:          Andriy Kurhanevych, Maksim Kulagin
 * Created:         4.10.2004
 * Last modified:   $Modtime: 17.05.07 19:43 $
 * Purpose:         Declaration of the Point structure  
 ******************************************************************************/

#pragma once
#ifndef POLYGONLIBRARY_POINT_H
#define POLYGONLIBRARY_POINT_H

#include <cmath>

namespace PolygonLibrary
{
	///////////////////////////////////////////////////////////////////////////
	/// Represents a point in a two-dimensional plane.
	///////////////////////////////////////////////////////////////////////////	
	class Point
	{
	// ------------------------------ Interface -------------------------------
	public:	
		// --- Constructors ---
		Point(): m_dX(0), m_dY(0) {}
		Point(double dX, double dY): m_dX(dX), m_dY(dY) {}

		// --- Attributes ---

		/// Returns the x-coordinate of the point.
		double X() const { return m_dX; }
		
		/// Returns the y-coordinate of the point.
		double Y() const { return m_dY; }

		// --- Operations ---
		
		/// Gets the square of the distance between the specified points.
		static double DistanceSquare(const Point& pointA, const Point& pointB)
		{
			const double diffX = pointA.X() - pointB.X();
			const double diffY = pointA.Y() - pointB.Y();
			return diffX * diffX + diffY * diffY;
		}

		/// Gets the distance between the specified points.
		static double Distance(const Point& pointA, const Point& pointB)
		{
			return std::sqrt(DistanceSquare(pointA, pointB));
		}
		
		/// Determines whether this point is equal to the specified point 
		/// with the specified absolute accuracy of coordinates.  
		bool Equals(const Point& point, const double dCoordinateAbsoluteAccuracy) const
		{
			return ( (std::abs(point.X() - X()) <= dCoordinateAbsoluteAccuracy) && 
			         (std::abs(point.Y() - Y()) <= dCoordinateAbsoluteAccuracy));
		}
		
		// --- Operators ---
		
		/// Determines whether this point is exactly equal to the specified point 
		bool operator == (const Point& point) const { return m_dX == point.m_dX && m_dY == point.m_dY; }

		/// Determines whether this point is not exactly equal to the specified point 
		bool operator != (const Point& point) const { return m_dX != point.m_dX || m_dY != point.m_dY; }	
		
		/// Determines whether this point is on the right of the specified point or 
		/// straight over it. Is designed to be used for spatial sorting of Point objects. 
		bool operator >  (const Point& point) const { return m_dX > point.m_dX  || m_dX == point.m_dX && m_dY > point.m_dY; }
	
	
	// ------------------------------ Implementation -------------------------------
	private:
		double m_dX;
		double m_dY;
	};
}
#endif