
#include "cgMath.h"

namespace gravity
{

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

	cgVector4::cgVector4( const float * f )
	{
		x = (*f);
		y = (*f) + 1;
		z = (*f) + 1;
		w = (*f) + 1;
	}

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

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

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

	cgVector4& cgVector4::operator += ( const cgVector4& v )
	{
		(*this) = (*this) + v;

		return (*this);
	}

	cgVector4& cgVector4::operator -= ( const cgVector4& v )
	{
		(*this) = (*this) - v;

		return (*this);
	}

	cgVector4& cgVector4::operator *= ( float s )
	{
		(*this) = (*this) * s;

		return (*this);
	}

	cgVector4& cgVector4::operator /= ( float s )
	{
		(*this) = (*this) / s;

		return (*this);
	}

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

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

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

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

	cgVector4 cgVector4::operator * ( float s ) const
	{
		return cgVector4(x * s, y * s, z * s, w * s);
	}

	cgVector4 cgVector4::operator / ( float s ) const
	{
		return (s == 0.0f) ? cgVector4(0.0f, 0.0f, 0.0f, 0.0f) : cgVector4(x / s, y / s, z / s, w / s);
	}

	cgVector4 operator * ( float s, const cgVector4& v )
	{
		return v * s;
	}

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

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

	void cgVector4::add(const cgVector4 *v)
	{
		x += v->x;
		y += v->y;
		z += v->z;
		w += v->w;
	}

	void cgVector4::baryCentric(const cgVector4 *v1, const cgVector4 *v2, float f, float g)
	{

	}

	void cgVector4::catmullRom(const cgVector4 *v1, const cgVector4 *v2, const cgVector4 *v3, float s)
	{
		
	}

	void cgVector4::cross(const cgVector4 *v)
	{
		
	}

	float cgVector4::dot(const cgVector4 *v)
	{
		return (x * v->x) + (y * v->y) + (z * v->z) + (w * v->w);
	}

	void cgVector4::hermite(const cgVector4 *v1, const cgVector4 *v2, const cgVector4 *v3, float s)
	{

	}

	float cgVector4::lenght()
	{
		return sqrt(x * x + y * y + z * z + w * w);
	}

	float cgVector4::lenghtSqr()
	{
		return x * x + y * y + z * z + w * w;
	}

	void cgVector4::lerp(const cgVector4 *v, float s)
	{
		x = x + s * (v->x - x);
		y = y + s * (v->y - y);
		z = z + s * (v->z - z);
		w = w + s * (v->w - w);
	}

	void cgVector4::maximize(const cgVector4 *v)
	{
		x = (x > v->x) ? x : v->x;
		y = (y > v->y) ? y : v->y;
		z = (z > v->z) ? z : v->z;
		w = (w > v->w) ? w : v->w;
	}

	void cgVector4::minimize(const cgVector4 *v)
	{
		x = (x < v->x) ? x : v->x;
		y = (y < v->y) ? y : v->y;
		z = (z < v->z) ? z : v->z;
		w = (w < v->w) ? w : v->w;
	}

	void cgVector4::normalize()
	{
		float l = lenght();

		x *= l;
		y *= l;
		z *= l;
		w *= l;
	}

	void cgVector4::scale(float s)
	{
		x *= s;
		y *= s;
		z *= s;
		w *= s;
	}

	void cgVector4::subtract(const cgVector4 *v)
	{
		x -= v->x;
		y -= v->y;
		z -= v->z;
		w -= v->w;
	}

	void cgVector4::transform(const cgMatrix *m)
	{
		
	}

}