#ifndef _SM_VECTOR4D

#define _SM_VECTOR4D

struct Vector4D
{
  Vector4D() {};
  Vector4D( const float* pf) 
  {
    x=pf[0]; y=pf[1]; z=pf[2]; w=pf[3];
  }

  Vector4D( float _x, float _y, float _z, float _w)
  {
    x=_x;
    y=_y;
    z=_z;
    w=_w;
  }

  // casting
  operator float* ()
  {
    return (&x);
  }
  operator const float* () const
  {
    return (&x);
  }

  // assignment operators
  Vector4D& operator += ( const Vector4D& v)
  {
    x+=v.x;
    y+=v.x;
    z+=v.z;
    w+=v.w;

    return (*this);
  }

  Vector4D& operator -= ( const Vector4D& v)
  {
    x-=v.x;
    y-=v.x;
    z-=v.z;
    w-=v.w;

    return (*this);
  }

  Vector4D& operator *= (const float f)
  {
    x*=f;
    y*=f;
    z*=f;
    w*=f;
    return (*this);
  }

  Vector4D& operator /= (const float f)
  {
    x/=f;
    y/=f;
    z/=f;
    w/=f;
    return (*this);
  }

  // unary operators
  Vector4D operator + () const
  {
    Vector4D v(x,y,z,w);
    return (v);
  }

  Vector4D operator - () const
  {
    Vector4D v(-x,-y,-z,-w);
    return (v);
  }

  // binary operators
  Vector4D operator+( const Vector4D& v) const
  {
    Vector4D r(x+v.x,y+v.y,z+v.z,w+v.w);
    return (r);
  }

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

  Vector4D operator*(const float f) const
  {
    Vector4D v(x*f,y*f,z*f,w*f);
    return (v);
  }

  Vector4D operator/(const float f) const
  {
    Vector4D v(x/f,y/f,z/f,w/f);
    return (v);
  }

  friend Vector4D operator * ( float f, const Vector4D& v)
  {
    Vector4D r(v.x*f,v.y*f,v.z*f,v.w*f);
    return (r);
  }

  bool operator == ( const Vector4D& v) const
  {
    return (x==v.x && y==v.y && z==v.z && w==v.w);
  }

  bool operator != ( const Vector4D& v) const
  {
    return (x!=v.x || y!=v.y || z!=v.z || w!=v.w);
  }

  static float Dot(const Vector4D& vA, const Vector4D& vB)
  {
    return (vA.x*vB.x+vA.y*vB.y+vA.z*vB.z+vA.w*vB.w);
  }

  float x,y,z,w;
};

#endif
