#include "Vector3.h"
#include "math.h"

using namespace std;

Vector3::Vector3()
{
	data[0]=0;
	data[1]=0;
	data[2]=0;
}

Vector3::Vector3(float x, float y, float z)
{
	data[0]=x;
	data[1]=y;
	data[2]=z;
}

float* Vector3::getData()
{
	return (float*)data;
}

float Vector3::length() const
{
	return sqrt(data[0]*data[0] + data[1]*data[1] + data[2]*data[2]);
}

Vector3& Vector3::normalize()
{
	float tempLength = length();
	data[0] = data[0]/tempLength;
	data[1] = data[1]/tempLength;
	data[2] = data[2]/tempLength;
	return *this;
}

void Vector3::print() const
{
	cout << '(' << data[0] << ", " << data[1] << ", " << data[2] << ")" <<endl;
}

float Vector3::dot(Vector3 other) const
{
	return (data[0]*other[0] + data[1]*other[1] + data[2]*other[2]);
}

Vector3 Vector3::cross(Vector3 other) const
{
	return Vector3(	data[1]*other[2] - data[2]*other[1], 
					data[2]*other[0] - data[0]*other[2], 
					data[0]*other[1] - data[1]*other[0]);
}

//Vector3 Vector3::operator=(Vector3 other) const
//{
//	return Vector3(other[0],other[1],other[2]);
//}

bool Vector3::operator==(Vector3 other) const
{
	return (data[0] == other[0]) && (data[1] == other[1]) && (data[2] == other[2]);
}

float& Vector3::operator[](int ind)
{
	return data[ind];
}

Vector3 Vector3::operator*(float scale) const
{
	return Vector3(data[0]*scale, data[1]*scale, data[2]*scale);
}

Vector3& Vector3::operator*=(float scale)
{
	data[0] = data[0]*scale;
	data[1] = data[1]*scale;
	data[2] = data[2]*scale;
	return *this;
}

Vector3 Vector3::operator*(Vector3 other) const
{
	return Vector3(data[0]*other[0], data[1]*other[1], data[2]*other[2]);
}

Vector3& Vector3::operator*=(Vector3 other)
{
	data[0] = data[0]*other[0];
	data[1] = data[1]*other[1];
	data[2] = data[2]*other[2];
	return *this;
}

Vector3 Vector3::operator/(float scale) const
{
	return Vector3(data[0]/scale, data[1]/scale, data[2]/scale);
}

Vector3& Vector3::operator/=(Vector3 other)
{
	data[0] = data[0]/other[0];
	data[1] = data[1]/other[1];
	data[2] = data[2]/other[2];
	return *this;
}

Vector3 Vector3::operator+(Vector3 add) const
{
	return Vector3(data[0]+add[0], data[1]+add[1], data[2]+add[2]);
}

Vector3& Vector3::operator+=(Vector3 other)
{
	data[0] = data[0]+other[0];
	data[1] = data[1]+other[1];
	data[2] = data[2]+other[2];
	return *this;
}

Vector3 Vector3::operator-(Vector3 sub) const
{
	return Vector3(data[0]-sub[0], data[1]-sub[1], data[2]-sub[2]);
}

Vector3& Vector3::operator-=(Vector3 other)
{
	data[0] = data[0]-other[0];
	data[1] = data[1]-other[1];
	data[2] = data[2]-other[2];
	return *this;
}

Vector3 Vector3::operator^(Vector3 other) const
{
	return cross(other);
}

float Vector3::operator|(Vector3 other) const
{
	return dot(other);
}

Vector3 Vector3::operator-() const
{
	return Vector3(-data[0], -data[1], -data[2]);
}

string Vector3::toString() const
{
	char str[100];
	_snprintf_s(str, 100, _TRUNCATE,  "(%f,%f,%f)", data[0],data[1],data[2]);
	return string(str);
}

Vector3::~Vector3(void)
{}
