context: using System;
  using System.Runtime.InteropServices;
  
  namespace Duality
  {
  	/// <summary>
  	/// Represents a 2D point using two integer values. For vector math, see <see cref="Vector2"/>.
  	/// </summary>
  	[StructLayout(LayoutKind.Sequential)]
  	public struct Point2 : IEquatable<Point2>
  	{
  		/// <summary>
  		/// A point at the origin (0, 0).
  		/// </summary>
  		public static readonly Point2 Zero = new Point2(0, 0);
  
  		/// <summary>
  		/// The X component of the Point.
  		/// </summary>
  		public int X;
  		/// <summary>
  		/// The Y component of the Point.
  		/// </summary>
  		public int Y;
  		
  		/// <summary>
  		/// Gets or sets the value at the index of the Point.
  		/// </summary>
  		public int this[int index]
  		{
  			get
  			{
  				switch (index)
  				{
  					case 0: return this.X;
  					case 1: return this.Y;
  					default: throw new IndexOutOfRangeException("Point2 access at index: " + index);
  				}
  			}
  			set
  			{
  				switch (index)
  				{
  					case 0: this.X = value; return;
  					case 1: this.Y = value; return;
  					default: throw new IndexOutOfRangeException("Point2 access at index: " + index);
  				}
  			}
  		}
  
  		/// <summary>
  		/// Constructs a new Point.
  		/// </summary>
  		/// <param name="x">The x coordinate of the Point.</param>
  		/// <param name="y">The y coordinate of the Point.</param>
  		public Point2(int x, int y)
  		{
  			this.X = x;
  			this.Y = y;
  		}
  
  		/// <summary>
  		/// Calculate the component-wise minimum of two points.
  		/// </summary>
  		/// <param name="a">First operand</param>
  		/// <param name="b">Second operand</param>
  		/// <returns>The component-wise minimum</returns>
  		public static Point2 Min(Point2 a, Point2 b)
  		{
  			a.X = a.X < b.X ? a.X : b.X;
  			a.Y = a.Y < b.Y ? a.Y : b.Y;
  			return a;
  		}
  		/// <summary>
  		/// Calculate the component-wise maximum of two points.
  		/// </summary>
  		/// <param name="a">First operand</param>
  		/// <param name="b">Second operand</param>
  		/// <returns>The component-wise maximum</returns>
  		public static Point2 Max(Point2 a, Point2 b)
  		{
  			a.X = a.X > b.X ? a.X : b.X;
  			a.Y = a.Y > b.Y ? a.Y : b.Y;
  			return a;
  		}
  		/// <summary>
  		/// Calculates the distance between two points described by two points. 
  		/// </summary>
  		/// <param name="left"></param>
  		/// <param name="right"></param>
  		/// <returns></returns>
  		public static float Distance(Point2 left, Point2 right)
  		{
  			Point2 diff;
  			diff.X = left.X - right.X;
  			diff.Y = left.Y - right.Y;
  			return MathF.Sqrt(diff.X * diff.X + diff.Y * diff.Y);
  		}
  		
  		/// <summary>
  		/// Adds the specified points component-wise.
  		/// </summary>
  		public static Point2 operator +(Point2 left, Point2 right)
  		{
  			return new Point2(
  				left.X + right.X, 
  				left.Y + right.Y);
  		}
  		/// <summary>
  		/// Subtracts the specified points component-wise.
  		/// </summary>
  		public static Point2 operator -(Point2 left, Point2 right)
  		{
  			return new Point2(
  				left.X - right.X, 
  				left.Y - right.Y);
  		}
  		/// <summary>
  		/// Inverts the specified point component-wise,
  		/// </summary>
  		public static Point2 operator -(Point2 point)
  		{
  			return new Point2(
  				-point.X, 
  				-point.Y);
  		}
  		/// <summary>
  		/// Multiplies the specified point component-wise with the specified factor.
  		/// </summary>
  		public static Point2 operator *(Point2 left, int right)
  		{
  			return new Point2(
  				left.X * right, 
  				left.Y * right);
  		}
  		/// <summary>
  		/// Multiplies the specified point component-wise with the specified factor.
  		/// </summary>
  		public static Point2 operator *(int left, Point2 right)
  		{
  			return right * left;
  		}
  		/// <summary>
  		/// Multiplies the specified points component-wise.
  		/// </summary>
  		public static Point2 operator *(Point2 left, Point2 right)
  		{
  			return new Point2(
  				left.X * right.X, 
  				left.Y * right.Y);
  		}
  		/// <summary>
  		/// Divides the specified point component-wise with the specified value.
  		/// </summary>
  		public static Point2 operator /(Point2 left, int right)
  		{
  			return new Point2(
  				left.X / right, 
  				left.Y / right);
  		}
  		/// <summary>
  		/// Divides the specified points component-wise.
  		/// </summary>
  		public static Point2 operator /(Point2 left, Point2 right)
  		{
  			return new Point2(
  				left.X / right.X, 
  				left.Y / right.Y);
  		}
  
  		/// <summary>
  		/// Multiplies the specified point component-wise with the specified factor.
  		/// </summary>
  		public static Vector2 operator *(Point2 left, float right)
  		{
  			return new Vector2(
  				left.X * right, 
  				left.Y * right);
  		}
  		/// <summary>
  		/// Multiplies the specified point component-wise with the specified factor.
  		/// </summary>
  		public static Vector2 operator *(float left, Point2 right)
  		{
  			return right * left;
  		}
  		/// <summary>
  		/// Divides the specified point component-wise with the specified value.
  		/// </summary>
  		public static Vector2 operator /(Point2 left, float right)
  		{
  			float mult = 1.0f / right;
  			return new Vector2(
  				left.X * mult, 
  				left.Y * mult);
  		}
  
  		/// <summary>
  		/// Compares the specified instances for equality.
  		/// </summary>
  		/// <param name="left">Left operand.</param>
  		/// <param name="right">Right operand.</param>
  		/// <returns>True if both instances are equal; false otherwise.</returns>
  		public static bool operator ==(Point2 left, Point2 right)
  		{
  			return left.Equals(right);
  		}
  		/// <summary>
  		/// Compares the specified instances for inequality.
  		/// </summary>
  		/// <param name="left">Left operand.</param>
  		/// <param name="right">Right operand.</param>
  		/// <returns>True if both instances are not equal; false otherwise.</returns>
  		public static bool operator !=(Point2 left, Point2 right)
  		{
  			return !left.Equals(right);
  		}
  
  		/// <summary>
  		/// Returns a System.String that represents the current Point.
  		/// </summary>
  		/// <returns></returns>
  		public override string ToString()
  		{
  
gt: 			return string.Format("({0}, {1})", this.X, this.Y);