/*
   math/vector2f.h
   This file is part of the Osirion project and is distributed under
   the terms of the GNU General Public License version 2
*/

#ifndef __INCLUDED_MATH_VECTOR2F_H__
#define __INCLUDED_MATH_VECTOR2F_H__

#include <iostream>

namespace math
{

/// a point or vector in 2D space
class Vector2f
{

public:
	/// default constructor
	Vector2f();

	/// assignment constructor
	Vector2f(const float x, const float y);

	/// copy constructor
	Vector2f(const Vector2f &other);

	/// assign (0,0)
	void clear();

	/// assignment operator
	void assign(const float x, const float y);

	/// assignment operator
	void assign(const Vector2f &other);

	/// assignment operator
	Vector2f & operator=(const Vector2f &other);

	/// vector subtraction
	Vector2f & operator-=(const Vector2f &other);

	/// vector sum
	Vector2f & operator+=(const Vector2f &other);

	/// vector subtraction
	inline Vector2f operator+(const Vector2f &other) const {
		Vector2f v(coord[0] + other.coord[0], coord[1] + other.coord[1]);
		return v;
	}

	/// vector sum
	inline Vector2f operator-(const Vector2f &other) const {
		Vector2f v(coord[0] - other.coord[0], coord[1] - other.coord[1]);
		return v;
	}

	/// scalar product
	inline Vector2f operator*(const float scalar) const {
		Vector2f v(coord[0]*scalar, coord[1]*scalar);
		return v;
	}

	/// scalar division
	inline Vector2f operator/(const float scalar) const {
		Vector2f v(coord[0] / scalar, coord[1] / scalar);
		return v;
	}

	/// array operator
	inline float& operator[](const size_t index) {
		return coord[index];
	}

	/// array operator
	inline float operator[](const size_t index) const {
		return coord[index];
	}

	/// x coordinate
	inline float width() const {
		return coord[0];
	}

	/// y coordinate
	inline float height() const {
		return coord[1];
	}

	/// x coordinate
	inline float x() const {
		return coord[0];
	}

	/// y coordinate
	inline float y() const {
		return coord[1];
	}

	/// mutable reference to the x coordinate
	inline float & get_x() {
		return coord[0];
	}

	/// mutable reference to the y coordinate
	inline float & get_y() {
		return coord[1];
	}

	/// a pointer to the internal data
	inline float *ptr() const {
		return (float *) coord;
	}

	inline bool contains(const Vector2f &other) const {
		return ((other.coord[0] >= 0) && (other.coord[1] >= 0) && (other.coord[0] <= coord[0]) && (other.coord[1] <= coord[1]));
	}

	inline bool contains(float x, float y) const {
		return ((x >= 0) && (y >= 0) && (x <= coord[0]) && (y <= coord[1]));
	}

private:
	float coord[2];
};

/// distance between two vectors
float distance(const Vector2f& first, const Vector2f& second);

/// distance between two vectors squared
float distancesquared(const Vector2f& first, const Vector2f& second);

}
#endif // __INCLUDED_MATH_VECTOR2F_H__