#ifndef VEC_H
#define VEC_H

/*
** Abstract Vector template, defining dimension-independent operations. Additional operators
** may need to be defined for specific vectors. eg. Cross Product or Perp-Dot Product.
** This class cannot be instantiated, clients should use Vec2, Vec3 or Vec4.
*/

namespace Salamander
{

template <class T>
class Vec
{
public:
	virtual ~Vec() {}

public:
	// Comparison Operators
	virtual bool operator== (const T& v) = 0;		// Equals
	virtual bool operator!= (const T& v) = 0;		// Does not equal

	// Unary Operators
	virtual T operator-() = 0;				// Negate

	// Scalar Operators
	virtual T operator* (double s) = 0;		// Scalar multiply
	virtual T operator/ (double s) = 0;		// Scalar divide

	// Vector Operators
	virtual T operator+ (const T& v) = 0;			// Component add
	virtual T operator- (const T& v) = 0;			// Component subtract
	virtual double operator* (const T& v) = 0;		// Dot product
	virtual T operator/ (const T& v) = 0;			// Component divide

	// Additive Operators
	virtual T& operator*= (double s) = 0;	// Scalar multiply increment
	virtual T& operator/= (double s) = 0;	// Scalar divide increment
	virtual T& operator+= (const T& v) = 0;			// Vector increment
	virtual T& operator-= (const T& v) = 0;			// Vector decrement

	// Properties
	virtual double length() = 0;
	virtual double lengthSquared() = 0;

	// Other operations
	virtual T& normalise() = 0;
	virtual T normal() = 0;

protected:
	/*
	** This is an abstract base class for standard vectors. It must be implemented as a dimension-
	** specific version to be used.
	*/
	Vec() : dirty_(true),
			length_(0.0f),
			lengthSquared_(0.0f) {}

protected:
	bool dirty_;
	double length_;
	double lengthSquared_;

};

}
#endif // VEC_H


