/***************************************************************************
 *   Copyright (C) 2007 by A.J. Tavakoli                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef QUAT_H
#define QUAT_H

#include "numeric.h"
#include "Vector3.h"
#include "Matrix3.h"
#include "Matrix4.h"

namespace Math3D {

template<class Real>
class Quat {
public:
   Real c[4];

   Quat();
   Quat(Real x, Real y, Real z, Real w);

   // overloaded operators for quaternion multiplication
   Quat operator *(const Quat &q) const;
   const Quat & operator *= (const Quat &q);   
   
   inline Quat conjugate() const { return Quat(-c[0], -c[1], -c[2], c[3]); }
   Real length() const;
   void normalize();
   Quat pow(Real t);
   void toMatrix(Real mat[]) const;
   Matrix3<Real> toMatrix3() const;
   Matrix4<Real> toMatrix4() const;

   static Quat fromAxisAngle(const Vector3<Real>& v, Real angle);
   static Quat fromEulerAngles(Real rotX, Real rotY, Real rotZ);

   inline Real& operator [] (int i)       { return c[i]; }
   inline Real  operator [] (int i) const { return c[i]; }
}; // Quat

template<class Real>
Quat<Real> slerp(const Quat<Real> &q1, const Quat<Real> &q2, Real t);

} // namespace Math3D

#include "Quat.cpp"

#endif
