// /home/heron/projekte/mameBot/ABot/Framework1/Framework1/Point2D.cs 
// User: heron at 20:30 19.04.2008

using System;

namespace Framework1
{
	
	
	public class Point2D
	{
		//Constant
		//private const double WorldWidth = 1023 - 0;
		//private const double WorldHeight = 895 - 128;
		
		//Fields
		private double theX;
		private double theY;
		//Properties
		public double X { get{ return theX; } set{ theX = value;} }
		public double Y { get{ return theY; } set{ theY = value;} }
		//Methods
		public Point2D(double x, double y)
		{
			theX = x;
			theY = y;
		}
		public Point2D(Point2D p)
		{
			theX = p.X;
			theY = p.Y;
		}
		///returns [p1] + [p2]
		public static Point2D operator+(Point2D p1,Point2D p2)
		{
			// do not consider wrap-around, here!
			return new Point2D( p1.X + p2.X, p1.Y + p2.Y );
		}
		///returns [p] over d   
		public static Point2D operator/(Point2D p, double d)
		{
			return new Point2D( p.X / d, p.Y / d );
		}
		///returns [p] times d   
		public static Point2D operator*(Point2D p, double d)
		{
			return new Point2D( p.X * d, p.Y * d );
		}
		///returns [p1] times [p2]   
		public static double operator*(Point2D p1, Point2D p2)
		{
			return  p1.X * p2.X +  p1.Y * p2.Y;
		}
		///returns the p1 - p2
		public static Point2D operator-(Point2D p1, Point2D p2)
		{
			// consider wrap-around
			//TODO this can be faster but will get ugly
			Point2D[] distances = new Point2D[9];
			distances[0] =  new Point2D( p1.X - p2.X, p1.Y - p2.Y );
			distances[1] =  new Point2D( p1.X - p2.X + Playfield.WORLD_WIDTH, p1.Y - p2.Y );
			distances[2] =  new Point2D( p1.X - p2.X - Playfield.WORLD_WIDTH, p1.Y - p2.Y );
			distances[3] =  new Point2D( p1.X - p2.X, p1.Y - p2.Y + Playfield.WORLD_HEIGHT);
			distances[4] =  new Point2D( p1.X - p2.X, p1.Y - p2.Y - Playfield.WORLD_HEIGHT);
			distances[5] =  new Point2D( p1.X - p2.X + Playfield.WORLD_WIDTH, p1.Y - p2.Y + Playfield.WORLD_HEIGHT);
			distances[6] =  new Point2D( p1.X - p2.X + Playfield.WORLD_WIDTH, p1.Y - p2.Y - Playfield.WORLD_HEIGHT);
			distances[7] =  new Point2D( p1.X - p2.X - Playfield.WORLD_WIDTH, p1.Y - p2.Y + Playfield.WORLD_HEIGHT);
			distances[8] =  new Point2D( p1.X - p2.X - Playfield.WORLD_WIDTH, p1.Y - p2.Y - Playfield.WORLD_HEIGHT);
			double minDist = distances[0].Abs();
			int result = 0;
			for( int i = 1; i< 9 ; i++ )
			{
				double aktDist = distances[i].Abs();
				if(minDist > aktDist)
				{
					minDist = aktDist;
					result = i;
				}
			}
				
			return distances[result];
		}
		///returns the absulute of the vector
		public double Abs()
		{
			return Math.Sqrt(X*X + Y*Y);
		}
		///reurns the angle w.r.t. X-Axis
		public double Phi()
		{
			return Math.Atan2(Y,X);
		}
		///returns String with the Coordinates
		public override string ToString ()
		{
			return "["+X.ToString()+", "+Y.ToString()+"]";
		}
		public static Point2D Test()
		{
			LogOutput.LogInfo("Point2D","Testing Point2D:");
			Point2D p = new Point2D(0,0);
			LogOutput.LogInfo("Point2D","   "+p.ToString());
			LogOutput.LogInfo("Point2D","Done.");
			return p;
		}
	
	}
}
