/***************************************************************
 * PrVector6.h
 *
 * This class provides a 6x1 vector.
 *
 ****************************************************************/

/*
 * modification history
 *----------------------
 *
 * 04/10/98: K.C. Chang: added zero(), elementAt().
 * 11/20/97: K.C. Chang: added inline methods.
 * 11/10/97: K.C. Chang: created.
 */

#ifndef _PrVector6_h
#define _PrVector6_h

#include "PrGlobalDefn.h"
#include <assert.h>
#include "PrVector3.h"

class PrMatrix6;

class PrVector6
{
  public:
    PrVector6() {}  // initialized to [0,0,0,0,0,0]
    PrVector6(const PrVector6 &v);
    PrVector6(const PrVector3 &v1,const PrVector3 &v2);
    PrVector6(Float x0,Float x1,Float x2,Float x3,Float x4,Float x5);
    ~PrVector6() {}

    PrVector6 &operator=(const PrVector6 &v);

    void zero();

    PrVector3 &operator[](int i);
    const PrVector3 &operator[](int i) const;

    Float &elementAt(int i);
    const Float &elementAt(int i) const;
    Float &elem(int i);
    const Float &elem(int i) const;
 
    PrVector6 operator-() const;
    void negate(PrVector6 &dest) const;

    PrVector6 operator+(const PrVector6 &v) const;
    void add(const PrVector6 &v,PrVector6 &dest) const;

    const PrVector6 operator-(const PrVector6 &v) const;
    void subtract(const PrVector6 &v,PrVector6 &dest) const;

    PrVector6 operator*(Float s) const;
    void multiply(Float s,PrVector6 &dest) const;

    PrVector6 operator*(const PrVector6 &v) const;
    void multiply(const PrVector6 &v,PrVector6 &dest) const;

    PrVector6 &operator+=(const PrVector6 &v);
    PrVector6 &operator-=(const PrVector6 &v);
    PrVector6 &operator*=(Float s);

    PrMatrix6 multiplyTransposed(const PrVector6 &v) const;
    void multiplyTransposed(const PrVector6 &v,PrMatrix6 &dest) const;

    Float dot(const PrVector6 &v) const;

    Float magnitude() const;

    void display(char *name=NULL);

  private:
    PrVector3 vec3_[2];
};

// inline methods

inline PrVector6::PrVector6(const PrVector3 &v1,const PrVector3 &v2)
{
    vec3_[0] = v1;
    vec3_[1] = v2;
}

inline PrVector6::PrVector6(const PrVector6 &v)
{
    vec3_[0] = v.vec3_[0];
    vec3_[1] = v.vec3_[1];
}

inline PrVector6::PrVector6(Float x0,Float x1,Float x2,Float x3,Float x4,Float x5)
{
    vec3_[0].values(x0,x1,x2);
    vec3_[1].values(x3,x4,x5);
}

inline PrVector6 &PrVector6::operator=(const PrVector6 &v)
{
    if (this != &v)
      {
	  vec3_[0] = v.vec3_[0];
	  vec3_[1] = v.vec3_[1];
      }
    return (*this);
}

inline void PrVector6::zero()
{
    vec3_[0].values(0.0,0.0,0.0);
    vec3_[1].values(0.0,0.0,0.0);
}

inline PrVector3 &PrVector6::operator[](int i)
{
    assert(i>=0 && i<2);
    return vec3_[i];
}

inline const PrVector3 &PrVector6::operator[](int i) const
{
    assert(i>=0 && i<2);
    return vec3_[i];
}

inline Float &PrVector6::elementAt(int i)
{
    assert(i>=0 && i<6);
    if (i<3)
      return vec3_[0][i];
    else
      return vec3_[1][i-3];
}

inline const Float &PrVector6::elementAt(int i) const
{
    assert(i>=0 && i<6);
    if (i<3)
      return vec3_[0][i];
    else
      return vec3_[1][i-3];
}

inline Float &PrVector6::elem(int i)
{
   return elementAt( i );
}

inline const Float &PrVector6::elem(int i) const
{
   return elementAt( i );
}


#endif // _PrVector6_h
