/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Quaternions.
 *//*
 * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef MATH_QUATERNION_HH
#define MATH_QUATERNION_HH 1

#include <iostream>
#include "math/types_trig.hh"
#include "math/vertex.hh"
#include "math/matrix.hh"
#include "math/funcs_osg.hh"
#include <osg/Quat>

namespace math {

////////////////////////////////////////////////////////////////////////////////
/// @brief Quaternion defines a rotation (no position).
///
class Quaternion : public osg::Quat
{
public:
    Quaternion( void )
    :   osg::Quat()
    {
    }

    Quaternion( const osg::Quat& quat )
    :   osg::Quat(quat)
    {
    }

    // NOTE: THIS DISCARDS POSITION!
    Quaternion( const Matrix& m )
    :   osg::Quat()
    {
        this->set( m );
    }

    /// Rotate this quaternion around an axis.
    void Rotate( const uint axis, const Radian rad )
    {
        osg::Quat rotation;
        rotation.makeRotate( rad, Axis2Vec3(axis) );
        (*static_cast<osg::Quat*>(this)) *= rotation;  // *= is faster
    }
};

std::istream& operator>>( std::istream& strm, Quaternion& quat );
std::ostream& operator<<( std::ostream& strm, const Quaternion& quat );

////////////////////////////////////////////////////////////////////////////////
/// @brief Quaternion with a position.
///
/// QuaternionPosition has 7 elements (Matrix has 16).
///
class QuaternionPosition
{
public:
    QuaternionPosition( void );
    QuaternionPosition( const Quaternion& quat, const Vector3& pos );
    QuaternionPosition( const Matrix& matrix );

public:
    Quaternion      mQuat;
    Vector3         mPos;
};

//------------------------------------------------------------------------------
// prototypes:

Quaternion
Interpolate( const Quaternion& q0, const Quaternion& q1, const fp fraction );

QuaternionPosition
Interpolate( const QuaternionPosition& qp0, const QuaternionPosition& qp1, const fp fraction );

} // namespace math

#endif // MATH_QUATERNION_HH
