// based on code by omen/Dimension^Platoon 

#ifndef __CONTQUATC_H__
#define __CONTQUATC_H__


#include "PajaTypes.h"
#include "KeyC.h"
#include "QuatC.h"
#include "FileIO.h"
#include "ControllerC.h"

class KeyQuatC
{
public:
	KeyQuatC();
	virtual ~KeyQuatC();

	virtual const PajaTypes::QuatC&	get_value() const;
	virtual void					set_value( const PajaTypes::QuatC& rQUat );

	virtual const PajaTypes::QuatC&	get_in_tan() const;
	virtual void					set_in_tan( const PajaTypes::QuatC& rQuat );

	virtual const PajaTypes::QuatC&	get_out_tan() const;
	virtual void					set_out_tan( const PajaTypes::QuatC& rQuat );

	virtual const PajaTypes::Vector3C&	get_axis() const;
	virtual void					set_axis( const PajaTypes::Vector3C& rAxis );

	virtual PajaTypes::float32		get_angle() const;
	virtual void					set_angle( PajaTypes::float32 f32Angle );

	virtual PajaTypes::int32		get_spin() const;
	virtual void					set_spin( PajaTypes::int32 i32Spin );

	virtual PajaTypes::int32		get_time();
	virtual void					set_time( PajaTypes::int32 i32Time );

	// TCB and ease
	virtual PajaTypes::float32	get_ease_in();
	virtual PajaTypes::float32	get_ease_out();
	virtual PajaTypes::float32	get_tens();
	virtual PajaTypes::float32	get_cont();
	virtual PajaTypes::float32	get_bias();
	virtual void				set_ease_in( PajaTypes::float32 f32Val );
	virtual void				set_ease_out( PajaTypes::float32 f32Val );
	virtual void				set_tens( PajaTypes::float32 f32Val );
	virtual void				set_cont( PajaTypes::float32 f32Val );
	virtual void				set_bias( PajaTypes::float32 f32Val );

	virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

private:
	PajaTypes::QuatC	m_rVal;
	PajaTypes::QuatC	m_rInTan;
	PajaTypes::QuatC	m_rOutTan;
	PajaTypes::Vector3C	m_rAxis;
	PajaTypes::float32	m_f32Angle;
	PajaTypes::int32	m_i32Spin;
	PajaTypes::float32	m_f32EaseIn, m_f32EaseOut;
	PajaTypes::float32	m_f32Tens, m_f32Cont, m_f32Bias;
	PajaTypes::int32	m_i32Time;
};


class ContQuatC
{
public:
	ContQuatC( PajaTypes::uint32 ui32Type = Composition::KEY_SMOOTH );
	virtual ~ContQuatC();

	virtual PajaTypes::int32	get_key_count();
	virtual KeyQuatC*			get_key( PajaTypes::int32 i32Index );
	virtual void				del_key( PajaTypes::int32 i32Index );
	virtual KeyQuatC*			add_key();

	virtual void				set_start_ort( PajaTypes::uint32 ui32Ort );
	virtual void				set_end_ort( PajaTypes::uint32 ui32Ort );
	virtual PajaTypes::uint32	get_start_ort() const;
	virtual PajaTypes::uint32	get_end_ort() const;

	virtual PajaTypes::int32	get_min_time() const;
	virtual PajaTypes::int32	get_max_time() const;

	virtual void				sort_keys();
	virtual void				prepare();

	virtual PajaTypes::QuatC	get_value( PajaTypes::int32 i32Time ) const;

	virtual void				set_type( PajaTypes::uint32 ui32Type );
	virtual PajaTypes::uint32	get_type() const;

	virtual PajaTypes::uint32	save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32	load( FileIO::LoadC* pLoad );

protected:
	// tool methods
	PajaTypes::float32			ease( PajaTypes::float32 f32U, PajaTypes::float32 f32A, PajaTypes::float32 f32B ) const;
	void						comp_ab( KeyQuatC* pPrev, KeyQuatC* pCur, KeyQuatC* pNext );

private:

	std::vector<KeyQuatC*>		m_rKeys;
	PajaTypes::uint32			m_ui32StartOrt;
	PajaTypes::uint32			m_ui32EndOrt;
	PajaTypes::uint32			m_ui32Type;			// interpolation type
};

#endif