#ifndef __VECTOR_H__
#define __VECTOR_H__

typedef struct Vector2 Vector2;
typedef struct Vector3 Vector3;
typedef struct Vector4 Vector4;

struct Vector2 {
	float x;
	float y;
};

struct Vector3 {
	float x;
	float y;
	float z;
};

struct Vector4 {
	float x;
	float y;
	float z;
	float w;
};

Vector2 Vector2_withValues(float x, float y);
Vector3 Vector3_withValues(float x, float y, float z);
Vector4 Vector4_withValues(float x, float y, float z, float w);

Vector2 Vector2_fromVector3_XY(Vector3 vector);

Vector2 Vector2_zero();
Vector3 Vector3_zero();
Vector4 Vector4_zero();
Vector3 Vector3_left();
Vector3 Vector3_right();
Vector3 Vector3_down();
Vector3 Vector3_up();
Vector3 Vector3_back();
Vector3 Vector3_front();

void Vector2_normalize(Vector2 * vector);
void Vector3_normalize(Vector3 * vector);
void Vector4_normalize(Vector4 * vector);
Vector2 Vector2_normalized(Vector2 vector);
Vector3 Vector3_normalized(Vector3 vector);
Vector4 Vector4_normalized(Vector4 vector);

float Vector2_magnitude(Vector2 vector);
float Vector3_magnitude(Vector3 vector);
float Vector4_magnitude(Vector4 vector);
float Vector2_magnitudeSquared(Vector2 vector);
float Vector3_magnitudeSquared(Vector3 vector);
float Vector4_magnitudeSquared(Vector4 vector);

Vector2 Vector2_add(Vector2 vector1, Vector2 vector2);
Vector3 Vector3_add(Vector3 vector1, Vector3 vector2);
Vector4 Vector4_add(Vector4 vector1, Vector4 vector2);
Vector2 Vector2_subtract(Vector2 vector1, Vector2 vector2);
Vector3 Vector3_subtract(Vector3 vector1, Vector3 vector2);
Vector4 Vector4_subtract(Vector4 vector1, Vector4 vector2);
Vector2 Vector2_multiplyScalar(Vector2 vector, float scalar);
Vector3 Vector3_multiplyScalar(Vector3 vector, float scalar);
Vector4 Vector4_multiplyScalar(Vector4 vector, float scalar);
Vector2 Vector2_divideScalar(Vector2 vector, float scalar);
Vector3 Vector3_divideScalar(Vector3 vector, float scalar);
Vector4 Vector4_divideScalar(Vector4 vector, float scalar);

Vector2 Vector2_interpolate(Vector2 left, Vector2 right, float value);
Vector3 Vector3_interpolate(Vector3 left, Vector3 right, float value);
Vector4 Vector4_interpolate(Vector4 left, Vector4 right, float value);

float Vector2_dot(Vector2 vector1, Vector2 vector2);
float Vector3_dot(Vector3 vector1, Vector3 vector2);
float Vector4_dot(Vector4 vector1, Vector4 vector2);
float Vector2_cross(Vector2 vector1, Vector2 vector2);
Vector3 Vector3_cross(Vector3 vector1, Vector3 vector2);

#endif
