#pragma once

#include "vector3d.h"

class LinearMatrix;

class UnitVector : public Vector3D
{
public:
	UnitVector()	{}
	UnitVector(Scalar x, Scalar y, Scalar z) : Vector3D(x, y, z)	{}

	UnitVector& operator=(const UnitVector &vector)
	{
		Check(&vector);
		Vector3D::operator=(vector);
		return *this;
	}
	UnitVector& operator=(const Vector3D& v)
	{
		Vector3D::Normalize(v);
		return *this;
	}

	UnitVector& Negate(const UnitVector &v)
	{
		Check(&v);
		Vector3D::Negate(v);
		return *this;
	}

	Scalar operator*(const Vector3D& v) const	{ return Vector3D::operator*(v); }

	UnitVector& Multiply(const UnitVector &v, const LinearMatrix &m);
	UnitVector& operator*=(const LinearMatrix &m);
	UnitVector& MultiplyByInverse(const UnitVector &v, const LinearMatrix &m)
	{
		Vector3D::MultiplyByInverse(v, m);
		return *this;
	}

	UnitVector& Lerp(const UnitVector& v1, const UnitVector& v2, Scalar t);

	Logical TestInstance() const;
	static Logical TestClass();

private:
	static const UnitVector identity;
	UnitVector& Negate(const Vector3D &V);
	UnitVector& Add(const Vector3D& V1,const Vector3D& V2);
	UnitVector& operator+=(const Vector3D& V);
	UnitVector& Subtract(const Vector3D& V1,const Vector3D& V2);
	UnitVector& operator-=(const Vector3D& V);
	UnitVector& Cross(const Vector3D& V1,const Vector3D& V2);
	UnitVector& Multiply(const Vector3D& V,Scalar Scale);
	UnitVector& operator*=(Scalar Value);
	UnitVector& Multiply(const Vector3D& V1,const Vector3D& V2);
	UnitVector& operator*=(const Vector3D &V);
	UnitVector& Multiply(const Vector3D &Source, const AffineMatrix &M);
	UnitVector& MultiplyByInverse(const Vector3D &Source, const LinearMatrix &M);
	UnitVector& Divide(const Vector3D& V,Scalar Scale);
	UnitVector& operator/=(Scalar Value);
	UnitVector& Combine(const Vector3D& V1,Scalar t1,const Vector3D& V2,Scalar t2);
};
