/**
 * \file Vector.h
 * \date 21.04.2002
 *
 * Interface for the Vector class
 */

#ifndef COMMON_WORLD_VECTOR_H
#define COMMON_WORLD_VECTOR_H

#include "Common/World/Angle.h"

class Point;

/**
 * \class Vector
 * \author Marek Lehuta
 * \author Matus Horvath
 * \brief Vector in orthogonal coordinate system
 */
class Vector
{
public:
	void Copy(const Vector& vector);
// Construction and destruction
	Vector() : length(0), xSize(0), ySize(0) {}
	inline Vector(const Vector &vect);

// Operations
	float GetX() const { return xSize; }
	float GetY() const { return ySize; }
	float GetLength() const { return length; }
	Angle GetAngle() const { return angle; }
	float GetAngle2(Vector vect);//cos uhla medzi dvoma vektormi

	void SetX(float x) { xSize = x; AdjustAng(); }
	void SetY(float y) { ySize = y; AdjustAng(); }
	void SetLength(float len) { length = len; AdjustXY(); }
	void SetAngle(Angle ang) { angle = ang; AdjustXY(); }

	inline Vector operator+(const Vector& vect) const;
	inline Point operator+(const Point& pos) const;
	inline Vector operator-(const Vector& vect) const;

	//inline const Vector& operator=(const Vector& vect);
	inline       Vector& operator=(const Vector& vector);
	inline const Vector& operator+=(const Vector& vect);
	inline const Vector& operator-=(const Vector& vect);

	inline Vector operator*(float f) const;
	inline Vector operator/(float f) const;
	inline Vector operator+(Angle a) const;
	inline Vector operator-(Angle a) const;

	const Vector& operator*=(float f) { length *= f; AdjustXY(); return *this; }
	const Vector& operator/=(float f) { length /= f; AdjustXY(); return *this; }
	const Vector& operator+=(Angle a) { angle += a; AdjustXY(); return *this; }
	const Vector& operator-=(Angle a) { angle += a; AdjustXY(); return *this; }

	// Rotate vector 90 degrees counter-clockwise
	inline Vector OrthoLeft() const;
	// Rotate vector 90 degrees clockwise
	inline Vector OrthoRight() const;

//	static float RadToDeg(float angle) { return angle * 180.f / M_PI; }
//	static float DegToRad(float angle) { return angle * M_PI / 180.f; }
//	static inline float NormDeg(float angle);
//	static inline float NormRad(float angle);

protected:
	void AdjustAng();
	void AdjustXY();

private:
	float xSize, ySize;
	float length;
	Angle angle;

};

class RectVector : public Vector
{
public:
// Construction and destruction
	RectVector(float x, float y) { SetX(x); SetY(y); AdjustAng(); }

};

class PolarVector : public Vector
{
public:
// Construction and destruction
	PolarVector(float l, Angle a) { SetLength(l); SetAngle(a); AdjustXY(); }

};



#include "Common/World/Point.h"

Vector::Vector(const Vector &vector)
{
	length = vector.length;
	angle = vector.angle;
	xSize = vector.xSize;
	ySize = vector.ySize;
}


Vector Vector::operator+(const Vector& vector) const
{
	return RectVector(xSize + vector.xSize, ySize + vector.ySize);
}

Point Vector::operator+(const Point& point) const
{
	return Point(xSize + point.GetX(), ySize + point.GetY());
}

Vector Vector::operator-(const Vector& vector) const
{
	return RectVector(xSize - vector.xSize, ySize - vector.ySize);
}


/*const Vector& Vector::operator=(const Vector& vector)
{
	xSize = vector.xSize; ySize = vector.ySize;
	length = vector.length; angle = vector.angle;
	return *this;
}
*/

Vector& Vector::operator=(const Vector& vector)
{
	xSize = vector.xSize; ySize = vector.ySize;
	length = vector.length; angle = vector.angle;
	return *this;
}

const Vector& Vector::operator+=(const Vector& vector)
{
	xSize += vector.xSize; ySize += vector.ySize;
	AdjustAng();
	return *this;
}

const Vector& Vector::operator-=(const Vector& vector)
{
	xSize -= vector.xSize; ySize -= vector.ySize;
	AdjustAng();
	return *this;
}


Vector Vector::operator*(float f) const
{
	return PolarVector(length * f, angle);
}

Vector Vector::operator/(float f) const
{
	// Possible division by zero
	return PolarVector(length / f, angle);
}

Vector Vector::operator+(Angle a) const
{
	return PolarVector(length, angle + a);
}

Vector Vector::operator-(Angle a) const
{
	return PolarVector(length, angle - a);
}


Vector Vector::OrthoLeft() const
{
	return RectVector(-ySize, xSize);
}

Vector Vector::OrthoRight() const
{
	return RectVector(ySize, -xSize);
}




/*float Vector::NormDeg(float angle)
{
	while(angle < 180.f) angle += 360.f;
	while(angle > 180.f) angle -= 360.f;
	return angle;
}*/

/*float Vector::NormRad(float angle)
{
	while(angle < M_PI) angle += 2 * M_PI;
	while(angle > M_PI) angle -= 2 * M_PI;
	return angle;
}*/

#endif // SUPPORT_VECTOR_H
