
///////////////////////////////////////////////////////////////////////////////
//
// File   : Tools_FacialAnimation_Face.h
// Author : Andy Tate
// Date   : 8-May-2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __TOOLS_FACIALANIMATION_FACE_H__
#define __TOOLS_FACIALANIMATION_FACE_H__

#if defined(ASURA_USE_FACIAL_ANIMATION_SYSTEM)

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura_List.h"
#include "Core/Asura_String.h"
#include "FacialAnimation/Asura_FacialAnimation_MuscleGroup.h"
#include "FacialAnimation/Asura_FacialAnimation_Face.h"

#include "FacialAnimation/Tools_FacialAnimation_Face_MuscleGroup.h"


////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////

class Asura_Chunk_Stream;
class Asura_FacialAnimation_Face;
struct Tools_FacialAnimation_Face_EyeBone;

////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Class        : Tools_FacialAnimation_Face
// Author       : Andy Tate
// Date         : 8-May-2008
//
// Description  : Tools-class used to point to a particular face.
////////////////////////////////////////////////////////////////////////////////

class Tools_FacialAnimation_Face
{
public:
	// Public typedefs...
	typedef Asura_List<Tools_FacialAnimation_Face_MuscleGroup> MuscleGroupContainer;
	typedef Asura_List_It<Tools_FacialAnimation_Face_MuscleGroup> MuscleGroupIterator;
	typedef Asura_List_ConstIt<Tools_FacialAnimation_Face_MuscleGroup> MuscleGroupConstIterator;

	// Public functions...
	Tools_FacialAnimation_Face(void);
	Tools_FacialAnimation_Face(const Asura_Hash_ID uHash, Asura_Chunk_Stream& xStream);
	~Tools_FacialAnimation_Face();

	Asura_FacialAnimation_Face*	CreateAsuraFace(void) const;
	bool						DestroyAsuraFace(void) const;

	// Animation functions...
	u_int	ReloadAsuraAnimations(void);

	// Muscle-group functions...
	Tools_FacialAnimation_Face_MuscleGroup*	CreateMuscleGroup(const char* szName, const Asura_FacialAnimation_MuscleGroup::ControlType eControlType);
	bool									DestroyMuscleGroup(const char* szName);

	void	SwapMuscleGroups(const Tools_FacialAnimation_Face_MuscleGroup* pxMuscleGroup1, const Tools_FacialAnimation_Face_MuscleGroup* pxMuscleGroup2);

	Tools_FacialAnimation_Face_MuscleGroup*			FindMuscleGroup(const char* szName);
	const Tools_FacialAnimation_Face_MuscleGroup*	FindMuscleGroup(const char* szName) const;

	// Chunk-stream functions...
	void	ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	void	WriteToChunkStream(Asura_Chunk_Stream& xStream) const;

	// Export functions...
	void	AddFilesToExportList(void) const;

	// Accessor functions...
	void				SetName(const char* szName)			{ m_xName = szName; }
	void				SetName(const Asura_String& xName)	{ m_xName = xName; }
	const Asura_String&	GetName(void) const					{ return(m_xName); }

	void				SetFaceTypeName(const char* szName)			{ m_xFaceTypeName = szName; }
	void				SetFaceTypeName(const Asura_String& xName)	{ m_xFaceTypeName = xName; }
	const Asura_String&	GetFaceTypeName(void) const					{ return(m_xFaceTypeName); }

	u_int	GetNumMuscleGroups(void) const	{ return(m_xMuscleGroupContainer.GetNumEntries()); }

	//For setting up the eye values
	void				SetEyeValues(const Asura_FacialAnimation_Face_EyeValues& xEyeValues){m_xEyeValues = xEyeValues;}
	void				AllocateEyeBones(u_int uNumEyeBones);
	Tools_FacialAnimation_Face_EyeBone* GetEyeBone(u_int uIndex);

	bool				HasEyes() const {return m_uNumEyeBones != 0;}

	MuscleGroupContainer&		GetMuscleGroupContainer(void)		{ return(m_xMuscleGroupContainer); }
	const MuscleGroupContainer&	GetMuscleGroupContainer(void) const	{ return(m_xMuscleGroupContainer); }


protected:
	// Protected variables...

	// Protected functions...


private:
	// Private variables...
	Asura_String			m_xName;					// The name of this face.
	Asura_String			m_xFaceTypeName;			// The name of the face-type this face is bound to.
	MuscleGroupContainer	m_xMuscleGroupContainer;	// The data for each of the muscle-groups held by this face.

	static const u_int		s_uChunkVersion;			// Current version used for reading/writing data.

	//details for bones controlled by eye animation
	u_int								m_uNumEyeBones;
	Tools_FacialAnimation_Face_EyeBone*	m_pxEyeBones; 

	Asura_FacialAnimation_Face_EyeValues m_xEyeValues;
	


	// Private functions...
	Tools_FacialAnimation_Face(const Tools_FacialAnimation_Face& xOther);

	Tools_FacialAnimation_Face&	operator=(const Tools_FacialAnimation_Face& xOther);

};   // End of class 'Tools_FacialAnimation_Face'.


struct Tools_FacialAnimation_Face_EyeBone
{
	Asura_String m_xBoneName;

	int m_iBoneIndex;
	float m_fRotSquint;
	float m_fRotClose;
	float m_fAngMin;
	float m_fAngMax;
	union
	{
		u_int m_uFlags;
		struct
		{
			u_int m_bEye:1;//Otherwise an eyelid
			u_int m_bRight:1;		
		};
	};
};


#endif	//defined(ASURA_USE_FACIAL_ANIMATION_SYSTEM)

#endif   // ifndef __TOOLS_FACIALANIMATION_FACE_H__


/// End of file. ///
