#include "vector4.h"

#include "auxmath.h"

const evector4 ux4(1.0,0.0,0.0,0.0);
const evector4 uy4(0.0,1.0,0.0,0.0);
const evector4 uz4(0.0,0.0,1.0,0.0);
const evector4 uw4(0.0,0.0,0.0,1.0);
const evector4 u04(0.0,0.0,0.0,0.0);

const evector4f ux4f(1.0,0.0,0.0,0.0);
const evector4f uy4f(0.0,1.0,0.0,0.0);
const evector4f uz4f(0.0,0.0,1.0,0.0);
const evector4f uw4f(0.0,0.0,0.0,1.0);
const evector4f u04f(0.0,0.0,0.0,0.0);


std::ostream &operator<<(std::ostream &stream,const evector4 &vec)
{
  stream << "("<<vec.x<<","<<vec.y<<","<<vec.z<<","<<vec.w<<")";
  return(stream);
}


evector4::evector4(): x(0.0), y(0.0), z(0.0),w(0.0)
{
}

evector4::evector4(const evector4& a): x(a.x),y(a.y),z(a.z),w(a.w)
{
}

//evector4::evector4(float fx, float fy, float fz): x(fx),y(fy),z(fz)
//{
//}

evector4::evector4(double fx, double fy, double fz,double fw): x(fx),y(fy),z(fz),w(fw)
{
}

double evector4::len() const
{
  return(sqrt(x*x+y*y+z*z+w*w));
}

void evector4::normalize()
{
  double l = 1.0/len();
  x = x*l;
  y = y*l;
  z = z*l;   
  w = w*l;   
}  

evector4 evector4::unit() const
{
  double l = 1.0/len();
  return(evector4(x*l,y*l,z*l,w*l));
}

evector4 evector4::proj(const evector4& a) const
{
  return((*this)*((*this)*a));
}

double evector4::operator *(const evector4& a) const
{
  return(a.x*x + a.y*y + a.z*z + a.w*w);
}

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

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

evector4 evector4::operator *(double a) const
{
  return(evector4(x*a,y*a,z*a,w*a));
}

evector4 evector4::operator /(double a) const
{
  double t = 1.0/a;
  return(evector4(x*t,y*t,z*t,w*t));
}

evector4& evector4::operator =(const evector4& a)
{
  x=a.x; y=a.y; z=a.z; w=a.w; return(*this);
}

evector4& evector4::operator +=(const evector4& a)
{
  x+=a.x;
  y+=a.y;
  z+=a.z;
  w+=a.w;
  return(*this);
}

evector4& evector4::operator -=(const evector4& a)
{
  x-=a.x;
  y-=a.y;
  z-=a.z;
  w-=a.w;
  return(*this);
}


evector4fp::evector4fp(): px(0x00) {}
evector4fp::evector4fp(float *vf): px(vf) {}


std::ostream &operator<<(std::ostream &stream,const evector4fp &vec)
{
  stream << "("<<vec.px[0]<<","<<vec.px[1]<<","<<vec.px[2]<<","<<vec.px[3]<<")";
  return(stream);
}

evector4f operator*(float v,const evector4fp &vec)
{
  return(vec*v);
}


evector4f::evector4f(): evector4fp(new float[4])
{
}

evector4f::evector4f(const evector4fp& a)
{
  px=new float[4];
  px[0]=a.px[0];
  px[1]=a.px[1];
  px[2]=a.px[2];
  px[3]=a.px[3];
}

//evector4::evector4(float fx, float fy, float fz): x(fx),y(fy),z(fz)
//{
//}

evector4f::evector4f(float fx, float fy, float fz,float fw)
{
  px=new float[4];
  px[0]=fx; px[1]=fy; px[2]=fz; px[3]=fw;
}

evector4f::~evector4f()
{
  delete[] px;
}

float evector4fp::len() const
{
  return(sqrt(px[0]*px[0]+px[1]*px[1]+px[2]*px[2]+px[3]*px[3]));
}

void evector4fp::normalize()
{
  float l = 1.0/len();
  px[0]*=l;
  px[1]*=l;
  px[2]*=l;
  px[3]*=l;
}  

evector4f evector4fp::unit() const
{
  float l = 1.0/len();
  return(evector4f(px[0]*l,px[1]*l,px[2]*l,px[3]*l));
}

evector4f evector4fp::proj(const evector4fp& a) const
{
  return((*this)*((*this)*a));
}

float evector4fp::operator *(const evector4fp& a) const
{
  return(a.px[0]*px[0] + a.px[1]*px[1] + a.px[2]*px[2] + a.px[3]*px[3]);
}

evector4f evector4fp::operator +(const evector4fp& a) const
{
  return(evector4f(px[0]+a.px[0],px[1]+a.px[1],px[2]+a.px[2],px[3]+a.px[3]));
}

evector4f evector4fp::operator -(const evector4fp& a) const
{
  return(evector4f(px[0]-a.px[0],px[1]-a.px[1],px[2]-a.px[2],px[3]-a.px[3]));
}

evector4f evector4fp::operator *(float a) const
{
  return(evector4f(px[0]*a,px[1]*a,px[2]*a,px[3]*a));
}

evector4f evector4fp::operator /(float a) const
{
  float t = 1.0/a;
  return(evector4f(px[0]*t,px[1]*t,px[2]*t,px[3]*t));
}

evector4fp& evector4fp::operator =(const evector4fp& a)
{
  px[0]=a.px[0]; px[1]=a.px[1]; px[2]=a.px[2]; px[3]=a.px[3]; return(*this);
}

evector4fp& evector4fp::operator +=(const evector4fp& a)
{
  px[0]+=a.px[0];
  px[1]+=a.px[1];
  px[2]+=a.px[2];
  px[3]+=a.px[3];
  return(*this);
}

evector4fp& evector4fp::operator -=(const evector4fp& a)
{
  px[0]-=a.px[0];
  px[1]-=a.px[1];
  px[2]-=a.px[2];
  px[3]-=a.px[3];
  return(*this);
}

#include "vector3.h"

evector3 evector4::xyz() const
{
	return(evector3(x, y, z));
}