// __author__ = Juan Carlos De Abreu (jcabreur@gmail.com)

/**
 * TODO(jcabreur): write a general comment here
 */

#ifndef MATH_VEC2_H__
#define MATH_VEC2_H__

#include "../../global.h"
#include <math.h>
#include <memory.h>

BEGIN_TEG_NAMESPACE();

// 
namespace math {

// Estructura para representar un vector de 2 dimensiones
template<class _T>
class Vec2 {
public:
	// Definicion de la estructura del Vec2
	// Attributes
	union {
		struct {_T x, y;};		// Componentes de vector
		struct {_T r, g;};		// Componentes de color
		struct {_T s, t;};		// Componentes de textura
		_T values[2];			//
	};
	
	// Constructores del vector
	Vec2();
	Vec2(const _T& _tx);
	Vec2(const _T& _tx, const _T& _ty);

	// Destructor del vector
	~Vec2();

	// Operadores de asignacion	
	void operator = (const _T& _param);
	void operator = (const Vec2<_T>& _param);

	// Operador para obtener un elemento del vector
	_T operator [](const int& _index) const;

	// Operador para incrementar todas las componentes del vector
	void operator ++();

	// Operador para decrementar todas las componentes del vector
	void operator --();

	// Operador para negar el vector
	Vec2<_T> operator - ();

	// Operadores para la suma de dos vectores
	Vec2<_T> operator + (const Vec2<_T>& _param) const;
	void operator +=(const Vec2<_T>& _param);
	
	// Operadores para sumarle a las componentes del vector un flotante
	Vec2<_T> operator + (const _T& _param) const;
	void operator +=(const _T& _param);
	
	// Operadores para la resta de dos vectores
	Vec2<_T> operator - (const Vec2<_T>& _param) const;
	void operator -=(const Vec2<_T>& _param);

	// Operadores para restarle a las componentes del vector un flotante
	Vec2<_T> operator - (const _T& _param) const;
	void operator -=(const _T& _param);
	
	// Operadores para el producto de un vector por un escalar
	Vec2<_T> operator * (const _T& _param) const;
	void operator *=(const _T& _param);
	
	// Operadores para la division de un vector por un escalar
	Vec2<_T> operator / (const _T& _param) const;
	void operator /=(const _T& _param);
	
	// Operadores de comparacion entre dos vectores
	bool operator >  (const Vec2<_T>& _param) const;
	bool operator <  (const Vec2<_T>& _param) const;
	bool operator >= (const Vec2<_T>& _param) const;
	bool operator <= (const Vec2<_T>& _param) const;
	bool operator == (const Vec2<_T>& _param) const;
	bool operator != (const Vec2<_T>& _param) const;

	// Operadores de comparacion entre un vector y un flotante
	bool operator >  (const _T& _param) const;
	bool operator <  (const _T& _param) const;
	bool operator >= (const _T& _param) const;
	bool operator <= (const _T& _param) const;
	bool operator == (const _T& _param) const;
	bool operator != (const _T& _param) const;

	// Metodos
	void init();		// Para inicializar el vector
	_T module() const;	// Para calcular el modulo del vector
	void normalize();	// Para normalizar el vector
	void set(const _T& _tx);
	void set(const _T& _tx, const _T& _ty);
};

// Constructors
template<class _T>
Vec2<_T>::Vec2() : x(0), y(0) { }

template<class _T>
Vec2<_T>::Vec2(const _T& _tx) : x(_tx), y(0) { }

template<class _T>
Vec2<_T>::Vec2(const _T& _tx, const _T& _ty) : x(_tx), y(_ty) { }

// Destructor
template<class _T>
Vec2<_T>::~Vec2() { }

};	// Math namespace

END_TEG_NAMESPACE();

#endif  // MATH_VEC2_H__
