#pragma once

#include <d3dx9math.h>
union DXMatrix;

struct DXVector3
{
	float x;
	float y;
	float z;

	DXVector3() {}
	DXVector3(const float _x, const float _y, const float _z);
	DXVector3(const float* const v);
	DXVector3(const DXVector3 &v);

	//casting
	operator float* ();
	operator const float* () const;
	operator D3DXVECTOR3* ();
	operator const D3DXVECTOR3* () const;
	operator D3DXVECTOR3 () const;
	//void operator =(const D3DXVECTOR3&);
	//operator D3DXVECTOR3 const &() const;


    // assignment operators
    DXVector3& operator += (const DXVector3&);
    DXVector3& operator -= (const DXVector3&);
    DXVector3& operator *= (const float);
    DXVector3& operator /= (const float);

	void add(const DXVector3& v) { *this += v; }
	void sub(const DXVector3& v) { *this -= v; }
	void mul(const float s) { *this *= s; }
	void div(const float s) { *this /= s; }

    // unary operators
    DXVector3 operator + () const;
    DXVector3 operator - () const;

    // binary operators
    DXVector3 operator + (const DXVector3&) const;
    DXVector3 operator - (const DXVector3&) const;
    DXVector3 operator * (float) const;
    DXVector3 operator / (float) const;

    friend DXVector3 operator * (float, const DXVector3&);
	
    bool operator == (const DXVector3&) const;
    bool operator != (const DXVector3&) const;

	//calculations
	float Dot(const DXVector3& vec) const;
	float Length(void) const;
	DXVector3 Cross(const DXVector3& v2) const;

	//manipulations
	void Normalize(void);
	void TransformCoord(const DXMatrix& mat);
	void TransformNormal(const DXMatrix& mat);

	//static calc
	static DXVector3 CrossVec(const DXVector3& v1, const DXVector3& v2);
	static DXVector3 NormalizeVec(const DXVector3& vec);
	static DXVector3 Lerp(const DXVector3& a, const DXVector3& b, const float s);
};

#include "DXVector3.inl"
