1 module nudsfml.system.vector2;
2 
3 import std.traits;
4 
5 /**
6  * Utility template struct for manipulating 2-dimensional vectors.
7  */
8 struct Vector2(T)
9 	if(isNumeric!(T) || is(T == bool))
10 {
11 	/// X coordinate of the vector.
12 	T x = 0;
13 
14 	/// Y coordinate of the vector.
15 	T y = 0;
16 
17 	/**
18 	 * Construct the vector from its coordinates.
19 	 *
20 	 * Params:
21 	 * 		X = X coordinate
22 	 * 		Y = Y coordinate
23 	 */
24 	this(T X,T Y)
25 	{
26 		x = X;
27 		y = Y;
28 	}
29 
30 	/**
31 	 * Construct the vector from another type of vector.
32 	 *
33 	 * Params:
34 	 * 	otherVector = Vector to convert
35 	 */
36 	this(E)(Vector2!(E) otherVector)
37 	{
38 		x = cast(T)(otherVector.x);
39 		y = cast(T)(otherVector.y);
40 	}
41 
42 	/// Invert the members of the vector.
43 	Vector2!(T) opUnary(string s)() const
44 	if (s == "-")
45 	{
46 		return Vector2!(T)(-x, -y);
47 	}
48 
49 	/// Add/Subtract between two vector2's.
50 	Vector2!(T) opBinary(string op, E)(Vector2!(E) otherVector) const
51 	if(isNumeric!(E) && ((op == "+") || (op == "-")))
52 	{
53 		static if (op == "+")
54 		{
55 			return Vector2!(T)(cast(T)(x+otherVector.x),cast(T)(y+otherVector.y));
56 		}
57 		static if(op == "-")
58 		{
59 			return Vector2!(T)(cast(T)(x-otherVector.x),cast(T)(y-otherVector.y));
60 		}
61 	}
62 
63 	/// Multiply/Divide a vector with a numaric value.
64 	Vector2!(T) opBinary (string op, E)(E num) const
65 	if(isNumeric!(E) && ((op == "*") || (op == "/")))
66 	{
67 		static if (op == "*")
68 		{
69 			return Vector2!(T)(cast(T)(x*num),cast(T)(y*num));
70 		}
71 		static if(op == "/")
72 		{
73 			return Vector2!(T)(cast(T)(x/num),cast(T)(y/num));
74 		}
75 	}
76 
77 	/// Assign Add/Subtract with another vector2.
78 	ref Vector2!(T) opOpAssign(string op, E)(Vector2!(E) otherVector)
79 	if(isNumeric!(E) && ((op == "+") || (op == "-")))
80 	{
81 		static if(op == "+")
82 		{
83 			x = cast(T)(x + otherVector.x);
84 			y = cast(T)(y + otherVector.y);
85 			return this;
86 		}
87 		static if(op == "-")
88 		{
89 			x = cast(T)(x - otherVector.x);
90 			y = cast(T)(y - otherVector.y);
91 			return this;
92 		}
93 	}
94 
95 	/// Assign Multiply/Divide with a numaric value.
96 	ref Vector2!(T) opOpAssign(string op,E)(E num)
97 	if(isNumeric!(E) && ((op == "*") || (op == "/")))
98 	{
99 		static if(op == "*")
100 		{
101 			x *= num;
102 			y *= num;
103 			return this;
104 		}
105 		static if(op == "/")
106 		{
107 			x /= num;
108 			y /= num;
109 			return this;
110 		}
111 	}
112 
113 	/// Assign the value of another vector whose type can be converted to T.
114 	ref Vector2!(T) opAssign(E)(Vector2!(E) otherVector)
115 	{
116 		x = cast(T)(otherVector.x);
117 		y = cast(T)(otherVector.y);
118 		return this;
119 	}
120 
121 	/// Compare two vectors for equality.
122 	bool opEquals(E)(const Vector2!(E) otherVector) const
123 	if(isNumeric!(E))
124 	{
125 		return ((x == otherVector.x) && (y == otherVector.y));
126 	}
127 
128 	/// Output the string representation of the Vector2.
129 	string toString() const
130 	{
131 		import std.conv;
132 		return "X: " ~ text(x) ~ " Y: " ~ text(y);
133 	}
134 }
135 
136 /// Definition of a Vector2 of integers.
137 alias Vector2i = Vector2!(int);
138 
139 /// Definition of a Vector2 of floats.
140 alias Vector2f = Vector2!(float);
141 
142 /// Definition of a Vector2 of unsigned integers.
143 alias Vector2u = Vector2!(uint);