#include "Vector.h"
#include <math.h>

Vector	zeroVector(0,0,0), x(1,0,0), y(0,1,0), z(0,0,1), xy(1,1,0), xz(1,0,1), yz(0,1,1), xyz(1,1,1);
//Matrix	identityMatrix(1,0,0,0,1,0,0,0,1);

#pragma mark ¥Vector

Vector::Vector()
{
	//x = y = z = 0;
}

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

Vector Vector::RotateAbout(float angle, Vector orig, Vector unitNormal)
{
	Vector fixPart, rotPart, rgtAng;
	Vector rot;
	
	rot = *this-orig;
	fixPart = (rot^unitNormal)*unitNormal;
	rotPart = rot-fixPart;
	rgtAng = rotPart*unitNormal;
	rotPart = cos(angle)*rotPart + sin(angle)*rgtAng;
	return rotPart + fixPart + orig;
}

Vector Vector::Bounce(Vector unitNormal, float vertB, float horizB)
{
	Vector horiz, vert;
	
	vert = (*this^unitNormal)*unitNormal;
	horiz = *this-vert;
	
	return (-vertB*vert)+(horizB*horiz);
}

Vector Vector::operator*( Vector b )
{
	/*Vector cross;
	
	cross.x = y*b.z-z*b.y;
	cross.y = z*b.x-x*b.z;
	cross.z = x*b.y-y*b.x;
	
	return cross;*/
	Vector cross(y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x);
	
	return cross;
}

void Vector::operator*=( float scalar )
{
	x *= scalar;
	y *= scalar;
	z *= scalar;
}

Vector operator*( float scalar, Vector b )
{
	Vector result;
	
	result.x = scalar*b.x;
	result.y = scalar*b.y;
	result.z = scalar*b.z;
	
	return result;
}

Vector Vector::operator*( float scalar )
{
	/*Vector result;
	
	result.x = scalar*x;
	result.y = scalar*y;
	result.z = scalar*z;
	
	return result;*/
	
	Vector result(scalar*x, scalar*y, scalar*z);
	
	return result;
}

float Vector::operator^( Vector b )
{
	float dot;
	
	dot = x*b.x;
	dot += y*b.y;
	dot += z*b.z;
	
	return dot;
}

Vector Vector::operator-( Vector b )
{
	/*Vector result;
	
	result.x = x-b.x;
	result.y = y-b.y;
	result.z = z-b.z;*/
	
	Vector result(x-b.x, y-b.y, z-b.z);
	
	return result;
}

Vector Vector::operator+( Vector b )
{
	/*Vector result;
	
	result.x = x+b.x;
	result.y = y+b.y;
	result.z = z+b.z;
	
	return result;*/
	Vector result(x+b.x, y+b.y, z+b.z);
	
	return result;
}

void Vector::operator+=( Vector b )
{
	x += b.x;
	y += b.y;
	z += b.z;
}

void Vector::operator-=( Vector b )
{
	x -= b.x;
	y -= b.y;
	z -= b.z;
}

Vector Vector::operator/( Vector b )
{
	Vector result;
	
	result.x = x/b.x;
	result.y = y/b.y;
	result.z = z/b.z;
	
	return result;
}

Vector Vector::operator/( float scalar )
{
	Vector result;
	
	result.x = x/scalar;
	result.y = y/scalar;
	result.z = z/scalar;
	
	return result;
}

float Vector::Length()
{
	return sqrt(x*x+y*y+z*z);
}

float Vector::LengthSqr()
{
	return x*x+y*y+z*z;
}

Vector Vector::Unit()
{
	return (1/Length())*(*this);
}

float Vector::DistanceToVector(Vector a)
{
	return (*this-a).Length();
}

/*Matrix Vector::Tilde()
{
	Matrix		omegatilde;
	
	omegatilde.a.x=0;
	omegatilde.b.x=-z;
	omegatilde.c.x=y;
	omegatilde.a.y=z;
	omegatilde.b.y=0;
	omegatilde.c.y=-x;
	omegatilde.a.z=-y;
	omegatilde.b.z=x;
	omegatilde.c.z=0;
	
	return omegatilde;
}*/

#pragma mark -
#pragma mark ¥Matrix

Matrix::Matrix()
{
}

/*Matrix::Matrix(Vector a, Vector b, Vector c)
{
	this->a = a;
	this->b = b;
	this->c = c;
}*/

/*Matrix::Matrix(float aa, float ab, float ac, float ba, float bb, float bc, float ca, float cb, float cc)
{
	a.x = aa;
	a.y = ba;
	a.z = ca;
	b.x = ab;
	b.y = bb;
	b.z = cb;
	c.x = ac;
	c.y = bc;
	c.z = cc;
}

Vector Matrix::operator*(Vector vector)
{
	Vector result;
	
	result.x = data[0]*vector.x+b.x*vector.y+c.x*vector.z;
	result.y = a.y*vector.x+b.y*vector.y+c.y*vector.z;
	result.z = a.z*vector.x+b.z*vector.y+c.z*vector.z;
	result.w = a.z*vector.x+b.z*vector.y+c.z*vector.z;
	
	return result;
}

Matrix Matrix::operator*(Matrix matrixB)
{
	Matrix result;
	
	result.a.x = a.x*matrixB.a.x+b.x*matrixB.a.y+c.x*matrixB.a.z;
	result.b.x = a.x*matrixB.b.x+b.x*matrixB.b.y+c.x*matrixB.b.z;
	result.c.x = a.x*matrixB.c.x+b.x*matrixB.c.y+c.x*matrixB.c.z;
	result.a.y = a.y*matrixB.a.x+b.y*matrixB.a.y+c.y*matrixB.a.z;
	result.b.y = a.y*matrixB.b.x+b.y*matrixB.b.y+c.y*matrixB.b.z;
	result.c.y = a.y*matrixB.c.x+b.y*matrixB.c.y+c.y*matrixB.c.z;
	result.a.z = a.z*matrixB.a.x+b.z*matrixB.a.y+c.z*matrixB.a.z;
	result.b.z = a.z*matrixB.b.x+b.z*matrixB.b.y+c.z*matrixB.b.z;
	result.c.z = a.z*matrixB.c.x+b.z*matrixB.c.y+c.z*matrixB.c.z;
	
	return result;
}

Matrix Matrix::operator*(float scalar)
{
	Matrix result;
	
	result.a = scalar*a;
	result.b = scalar*b;
	result.c = scalar*c;
	
	return result;
}

Matrix operator*(float scalar, Matrix m)
{
	Matrix result;
	
	result.a = scalar*m.a;
	result.b = scalar*m.b;
	result.c = scalar*m.c;
	
	return result;
}

Matrix Matrix::operator+(Matrix matrixB)
{
	Matrix result;
	
	result.a = a+matrixB.a;
	result.b = b+matrixB.b;
	result.c = c+matrixB.c;
	
	return result;
}

Matrix Matrix::operator-(Matrix matrixB)
{
	Matrix result;
	
	result.a = a-matrixB.a;
	result.b = b-matrixB.b;
	result.c = c-matrixB.c;
	
	return result;
}

void Matrix::operator+=(Matrix matrixB)
{
	a += matrixB.a;
	b += matrixB.b;
	c += matrixB.c;
}

Matrix Matrix::Transpose()
{
	Matrix result;
	
	result.a.x = a.x;
	result.b.x = a.y;
	result.c.x = a.z;
	result.a.y = b.x;
	result.b.y = b.y;
	result.c.y = b.z;
	result.a.z = b.x;
	result.b.z = c.y;
	result.c.z = c.z;
	
	return result;
}

Matrix Matrix::Orthognalise()
{
	Matrix		result;
	float		sum;
	
	result.a = a.Unit();
	result.b = b.Unit();
	
	result.c = (result.a*result.b).Unit();
	result.b = (result.c*result.a).Unit();
	
	return result;
}*/

