#pragma once

#include "AxisAngleImpl.h"
#include "Vector.h"
#include <string>
#include <cmath>

//Author Scott Nykl
//An immuatble wrapper around an axis and angle. The axis is always normalized to unit length upon construction.
//The angle is always mapped from the domain (0,180] (degs) or (-PI,PI] (rads). This means the axis will be
//negated if a negative angle is passed in. This design is intentional to ensure that converting
//between AxisAngle -> Quaternion -> DCM -> rodrigues -> etc always come back to the exact same values
//upon returning to an Axis Angle.
//This is a right handed axis where positive rotations are counter clock wise (ccw) about the axis.
namespace Aftr
{

template< typename T >
class AxisAngleT
{
public:
   using value_type = T;

   AxisAngleT() noexcept;

   AxisAngleT( VectorT<T> const& axis, T angleDeg ) noexcept;
   AxisAngleT( AxisAngleT const& toCopy ) noexcept;
   AxisAngleT( VectorT<T> const& rodrigues_rot_vec ) noexcept;
   //AxisAngleT( AxisAngleT&& toMove ) noexcept = delete;
   ~AxisAngleT() = default;
   AxisAngleT<T>& operator=( AxisAngleT const& q ) noexcept;
   //AxisAngleT<T>& operator=( AxisAngleT&& q ) noexcept = delete;

   bool isEqual( AxisAngleT<T> const& b, T epsilon = 0.00001f ) const noexcept;
   
   //Mat4T<T> toRotationMatrix() const;
   
   std::string toString( size_t length = 3) const;
   
   VectorT<T> const& axis() const noexcept; ///< Returns the unit length x,y,z components of this Axis
   T deg() const noexcept; ///< Returns angle, in degrees, about this axis
   T rad() const noexcept; ///< Returns angle, in rad, about this axis
   VectorT<T> toRodrigues() const noexcept; ///< Returns a Rodrigues rotation vector from this axis angle

   /// Returns the Vector (1,0,0) rotated about this instance's axis by this instance's degree.
   /// Helpful when you want to see how this AxisAngle transforms a unit vector.
   VectorT<T> toVec() const noexcept;

private:
   VectorT<T> axis_{ 0,0,1 };
   T deg_{ 0 };


};

} //namespace Aftr
#include "AxisAngle.cpptemplate.h"

