/**
 *
 * \file	vector.h
 *
 * \brief Definition of template class vector.
 *
 * \author	MAxx Headroom
 * \version	0.0
 * \date	17.01.2004 14:40:06
 *
 **/
#ifndef __vector_h__
#define __vector_h__


//#include <fastmath.h>
#include <math.h>


/**
 *
 * \brief This class holds a three dimensional vector.
 *
 **/
//{{{
template <class t>
class vector
{

        public:


                /**
                 * Vectors <b>x</b> component.
                 */
                t X;

                /**
                 * Vectors <b>y</b> component.
                 */
                t Y;

                /**
                 * Vectors <b>z</b> component.
                 */
                t Z;



                vector()
                : X(0.0),
                  Y(0.0),
                  Z(0.0)
                {}

                vector(t x, t y, t z)
                : X(x),
                  Y(y),
                  Z(z)
                {}

                vector(const vector &v)
                : X(v.X),
                  Y(v.Y),
                  Z(v.Z)
                {}

		/**
		 *
		 * \brief Assignment operator.
		 *
		 **/
                const vector &operator=(const vector &v)
                {
                        if (&v != this) {
                                X = v.X;
                                Y = v.Y;
                                Z = v.Z;
                        }
                        return *this;
                }

		/**
		 *
		 * \brief Sets all three components of the vector.
		 *
		 * \param x	First component.
		 * \param y	Second component.
		 * \param z	Third component.
		 *
		 **/
                void set(t x, t y, t z)
                {
                    X = x; Y = y; Z = z;
                }

                /**
                 * \brief Multiplicate actual vector with a scalar.
		 * 
                 * @param s	scalar.
                 */
                const vector operator*(const t s) const
                {
                        return vector<t>(X*s, Y*s, Z*s);
                }

                /**
                 * Multiplication with a vector.
                 */
                const vector operator*(const vector &v) const
                {
                        return vector<t>(Y*v.Z-v.Y*Z,
                                         Z*v.X-v.Z*X,
                                         X*v.Y-v.X*Y);
                }

                /**
                 * Dot product of this vector with v.
                 */
                const t operator^(const vector &v) const
                {
                        return (X*v.X + Y*v.Y + Z*v.Z);
                }

		/**
		 * Cross product of this vector with v.
		 **/
		const vector operator%(const vector &v) const
		{
			return vector<t>(Y*v.Z - Z*v.Y,
					 Z*v.X - X*v.Z,
					 X*v.Y - Y*v.X);
		}

                /**
                 * Add a vector v to this vector.
                 */
                const vector operator+(const vector &v) const
                {
                        return vector<t>(X+v.X, Y+v.Y, Z+v.Z);
                }

                const vector operator+() const
                {
                        return *this;
                }

                const vector &operator+=(const vector v)
                {
                        X += v.X;
                        Y += v.Y;
                        Z += v.Z;
                        return *this;
                }

                const vector operator-(const vector &v) const
                {
                        return vector<t>(X-v.X, Y-v.Y, Z-v.Z);
                }

                const vector operator-() const
                {
                        vector tmp(-X, -Y, -Z);
                        return tmp;
                }

                const vector &operator-=(const vector v)
                {
                        X -= v.X;
                        Y -= v.Y;
                        Z -= v.Z;
                        return *this;
                }


                /**
                 * Rotate vector around x axis.
                 */
                void rotx(t val)
                {
                        t Yold = Y, Zold = Z;
                        Y =   Yold*_fm_cos(val) - Zold*_fm_sin(val);
                        Z =   Yold*_fm_sin(val) + Zold*_fm_cos(val);
                }

                void roty(t val)
                {
                        t Xold = X, Zold = Z;
                        X =   Xold*_fm_cos(val) + Zold*_fm_sin(val);
                        Z = - Xold*_fm_sin(val) + Zold*_fm_cos(val);
                }

                void rotz(t val)
                {
                        t Xold = X, Yold = Y;
                        X =   Xold*_fm_cos(val) - Yold*_fm_sin(val);
                        Y =   Xold*_fm_sin(val) + Yold*_fm_cos(val);
                }

                const vector& normal(void)
                {
                        t l = length();
                        X = X / l;
                        Y = Y / l;
                        Z = Z / l;
			return *this;
                }

                /**
                 * Calculate the length of the vector.
                 */
                t length() {
                        //return _fm_sqrt(X*X + Y*Y + Z*Z);
                        return sqrt(X*X + Y*Y + Z*Z);
                }



};
//}}}


typedef vector<float>   vectorf;
typedef vector<double>  vectord;
typedef vector<short>   vectors;


#endif /* __vector_h__ */


// vim:fdm=marker
