
#include "cgMath.h"

namespace gravity
{

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

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

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

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

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

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

		return (*this);
	}

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

		return (*this);
	}

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

		return (*this);
	}

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

		return (*this);
	}

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

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

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

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

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

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

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

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

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

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

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

	}

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

	void cgVector3::cross(const cgVector3 *v)
	{
		x = y * v->z - z * v->y;
		y = z * v->x - x * v->z;
		z = x * v->y - y * v->x;
	}

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

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

	}

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

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

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

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

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

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

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

	void cgVector3::project(const cgViewport *pViewport, const cgMatrix *pProjection, const cgMatrix *pView, const cgMatrix *pWorld)
	{

	}

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

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

	cgVector4* cgVector3::transform(const cgMatrix *m)
	{
		return &cgVector4();
	}

	void cgVector3::transformCoord(const cgMatrix *m)
	{

	}

	void cgVector3::transformNormal(const cgMatrix *m)
	{

	}

	void cgVector3::unproject(const cgViewport *pViewport, const cgMatrix *pProjection, const cgMatrix *pView, const cgMatrix *pWorld)
	{

	}

}