#pragma once

#include "unitvec.h"

class Normal : public UnitVector
{
public:
	Normal()		{}
	Normal(Scalar x, Scalar y, Scalar z) : UnitVector(x,y,z)	{}
	Normal(const UnitVector& v) : UnitVector(v)					{}

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

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

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

	Normal& Multiply(const Normal &n, const LinearMatrix &m)
	{
		UnitVector::Multiply(n,m);
		return *this;
	}
	Normal& operator*=(const LinearMatrix &M)
	{
		Normal src(*this);
		return Multiply(src,M);
	}

	//
	// These functions will cause the vector to lose its unit length, thus
	// cause any downstream verifies to fail.  We have to be able to only
	// normalize the normal once after all transformations if these are to
	// be of any benefit, so don't use them for now
	Normal& Multiply_Inverse(const Normal &Source, const AffineMatrix &M);
	Normal& Multiply(const Normal &Source, const AffineMatrix &M);

	static Logical TestClass();

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