
#include "cgMath.h"

namespace gravity
{

	cgQuaternion::cgQuaternion()
	{
		x = 0.0f;
		y = 0.0f;
		z = 0.0f;
		w = 1.0f;
	}

	cgQuaternion::cgQuaternion( const float * f )
	{
		x = (*f);
		y = (*f) + 0x1;
		z = (*f) + 0x2;
		w = (*f) + 0x3;
	}

	cgQuaternion::cgQuaternion( float x, float y, float z, float w )
	{
		this->x = x;
		this->y = y;
		this->z = z;
		this->w = w;
	}

	cgQuaternion::operator float* ()
	{
		return (float*) this;
	}

	cgQuaternion::operator const float* () const
	{
		return (const float*) this;
	}

	void cgQuaternion::operator = ( const cgQuaternion& q )
	{
		x = q.x;
		y = q.y;
		z = q.z;
		w = q.w;
	}

	void cgQuaternion::operator = ( float s )
	{
		x = s;
		y = s;
		z = s;
		w = s;
	}

	cgQuaternion& cgQuaternion::operator += ( const cgQuaternion& q )
	{
		(*this) = (*this) + q;
		return (*this);
	}

	cgQuaternion& cgQuaternion::operator -= ( const cgQuaternion& q )
	{
		(*this) = (*this) - q;
		return (*this);
	}

	cgQuaternion& cgQuaternion::operator *= ( const cgQuaternion& q )
	{
		(*this) = (*this) * q;
		return (*this);
	}

	cgQuaternion& cgQuaternion::operator *= ( float s )
	{
		(*this) = (*this) * s;
		return (*this);
	}

	cgQuaternion& cgQuaternion::operator /= ( float s )
	{
		if ( s == 0.0f )
		{
			(*this) = 0.0f;
			return (*this);
		}

		(*this) = (*this) / s;
		return (*this);
	}

	cgQuaternion cgQuaternion::operator + () const
	{
		return cgQuaternion(x, y, z, w);
	}

	cgQuaternion cgQuaternion::operator - () const
	{
		return cgQuaternion(-x, -y, -z, -w);
	}

	cgQuaternion cgQuaternion::operator + ( const cgQuaternion& q ) const
	{
		return cgQuaternion(x + q.x, y + q.y, z + q.z, w + q.w);
	}

	cgQuaternion cgQuaternion::operator - ( const cgQuaternion& q ) const
	{
		return cgQuaternion(x - q.x, y - q.y, z - q.z, w - q.w);
	}

	cgQuaternion cgQuaternion::operator * ( const cgQuaternion& q ) const
	{
		/*w = w1w2 - x1x2 - y1y2 - z1z2
		x = w1x2 + x1w2 + y1z2 - z1y2
		y = w1y2 + y1w2 + z1x2 - x1z2
		z = w1z2 + z1w2 + x1y2 - y1x2*/

		return (*this);
	}

	cgQuaternion cgQuaternion::operator * ( float s ) const
	{
		if ( s == 0.0f )
		{
			return cgQuaternion();
		}

		return cgQuaternion(x * s, y * s, z * s, w * s);
	}

	cgQuaternion cgQuaternion::operator / ( float s ) const
	{
		if ( s == 0.0f )
		{
			return cgQuaternion();
		}

		return cgQuaternion(x / s, y / s, z / s, w / s);
	}

	cgQuaternion operator * ( float s, const cgQuaternion& q )
	{
		return q * s;
	}

	bool cgQuaternion::operator == ( const cgQuaternion& q ) const
	{
		return (x == q.x && y == q.y && z == q.z && w == q.w) ? true : false;
	}

	bool cgQuaternion::operator != ( const cgQuaternion& q ) const
	{
		return (x != q.x || y != q.y || z != q.z || w != q.w) ? true : false;
	}

}