// ------------------------------------------------------------------------------------ //
//																						//
//	File: Asura_GUIMenu_Widget_AnimatingImage.h											//
//																						//
//	Description: animating image widget class											//
//																						//
//	Created: Steve Keen - 9/11/06														//
//																						//
//	Copyright (C) 2006 Rebellion (Derby), All Rights Reserved.							//
// ------------------------------------------------------------------------------------ //

#ifndef __ASURA_GUIMENU_WIDGET_ANIMATINGIMAGE_H__
#define __ASURA_GUIMENU_WIDGET_ANIMATINGIMAGE_H__

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifdef ASURA_USE_GUI_MENU_SYSTEM
#include "Asura_GUIMenu_Element_Base.h"
#include "Asura_GUIMenu_Widget_Base.h"

struct Asura_GUIMenu_UV;

// -- Structs -------------------------------------------------------------------------
struct ANIMIMAGE_FRAME
{
	Asura_Hash_ID				uHashTextureName;
#ifdef ASURA_GUIMENU_STORE_NAMES
	Asura_String				xTextureName;
#endif

	u_int						uTexureID;
	Asura_Bounding_Rectangle	xRect;
	Asura_GUIMenu_UV			axUV[2];
};

struct ANIMIMAGE_SEQUENCE
{
	u_short	uMaxNumberFrames;
	u_short uCurrentNumFrames;
	u_int*	puSequenceFrameId;
	float	fFPS;

};

// -- Enums ---------------------------------------------------------------------------

enum Asura_GUIMenu_AnimImage_Mode
{
	ASURA_GUIMENU_ANIMMODE_NONE = 0,
	ASURA_GUIMENU_ANIMMODE_ONESHOT,
	ASURA_GUIMENU_ANIMMODE_LOOP,
	ASURA_GUIMENU_ANIMMODE_PINGPONG,
	ASURA_GUIMENU_ANIMMODE_EOL	// end of list
};

enum Asura_GUIMenu_AnimatingImage_Message
{
	ASURA_GUIMENU_ANIMIMAGE_NONE = 0,
	ASURA_GUIMENU_ANIMIMAGE_PLAY,				// data passed is the sequence number
	ASURA_GUIMENU_ANIMIMAGE_PLAY_BACKWARDS,	// data passed is the sequence number
	ASURA_GUIMENU_ANIMIMAGE_STOP,				// stops the animation at end of current loop
	ASURA_GUIMENU_ANIMIMAGE_END_OF_MESSAGES
};

// -- Defines -------------------------------------------------------------------------
#define ASURA_GUIMENU_MAX_ANIMIMAGE_FRAMES	8
#define ASURA_GUIMENU_MAX_ANIMIMAGE_SEQUENCES	4

#define ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_START	16

#define ASURA_CHUNK_WIDGET_ANIMIMAGE_VERSION 0

// -- Structures ----------------------------------------------------------------------

// -- Class ---------------------------------------------------------------------------

class Asura_GUIMenu_Widget_AnimatingImage : public Asura_GUIMenu_Widget_Base
{
	// -- Functions -----------------------------------------------------------------------
public:
	enum Asura_GUIMenu_Inherit_Flag_Widget_AnimImage_Type
	{
		ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_FPS_SCALE		= (1<<(ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_START+0)),
		ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_FRAME_DATA		= (1<<(ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_START+0)),
		ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_SEQUENCE_DATA	= (1<<(ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_START+0)),

		//ASURA_GUIMENU_WIDGET_ANIMIMAGE_OVERIDE_MAX is here to stop another programmer adding past bit flag 31
		ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_MAX				= (1<<(ASURA_GUIMENU_WIDGET_ANIMIMAGE_LOCAL_FLAG_START+15))
	};

	Asura_GUIMenu_Widget_AnimatingImage();
	virtual ~Asura_GUIMenu_Widget_AnimatingImage();

	virtual void 				Update( float fElapsedTime);	//, u_int uButtons, POINT ptMousePos);
	virtual void 				Render( u_int uState);
	virtual void				Copy( const Asura_GUIMenu_Root* pxSource );

	// -- UI Message handler functions --
	virtual bool				OnInit( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnDeInit( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnDataChange( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnDataRequest( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnClicked( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnRollIn( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnRollOut( const Asura_Message_GUIMenu_Notify* pxMessage);
	virtual bool				OnEnable( const Asura_Message_GUIMenu_Notify* pxMessage);

	u_int						AddFrame( u_int uTexID, float u0, float v0, float u1, float v1, Asura_Bounding_Rectangle xRect);
	u_int						GetFrameCount( void) const;//	{	return m_uFrameCount;	}
	const ANIMIMAGE_FRAME*		GetFrame( u_int uIndex) const;

	virtual bool				AddToThisContainer( Asura_GUIMenu_Root* pxObject);

	float						GetFPSScale( void);//	{	return m_fFPSScale;	}
	void						SetFPSScale( float fFPSScale);

	void						StartAnim( u_int uSequence, u_short uAnimMode, u_short uRepeatCount = 0xffff);
	void						StartAnimReversed( u_int uSequence, u_short uAnimMode, u_short uRepeatCount = 0xffff);
	void						StopAnim( void);

	void						SetReverseDirection( bool bIsReversed);
	short						GetAnimDirection( void)	{	return m_iAnimDirection;	}

	u_int						CreateSequence( u_short uMaxNumFrames, float fFPS);
	bool						DestroySequence( u_int uSequenceIndex);
	bool						AddFrameToSequence( u_int uSequence, u_int uFrameIndex);
	bool						IsValidAnimSequence( short iSequence) const;

	const ANIMIMAGE_SEQUENCE*	GetSequence( short iSequence) const;

#ifdef ASURA_TOOLS
	virtual void				UpdateLocalDataFromStyle( void);

	virtual	void				WriteToChunkStream( Asura_Chunk_Stream& xStream) const;
	virtual void				ExportToXML(Tools_GUIMenu_XMLExporter* pxExporter) const;
#endif // ASURA_TOOLS
	virtual void				ReadFromChunkStream( Asura_Chunk_Stream& xStream, Asura_GUIMenu_Root* pxParentObject, u_int uChunkVersion);
protected:
	void						SetupDefaultElements( void);

private:

	// -- Variables -----------------------------------------------------------------------
public:

protected:
	float						m_fFPSScale;
	float						m_fTimeLapse;

	ANIMIMAGE_FRAME				m_axFrameInfo[ASURA_GUIMENU_MAX_ANIMIMAGE_FRAMES];
	u_int						m_uFrameCount;

	ANIMIMAGE_SEQUENCE			m_axAnimSequence[ASURA_GUIMENU_MAX_ANIMIMAGE_SEQUENCES];
	u_int						m_uCurrentFrame;

	u_short						m_uAnimMode;
	short						m_iPingPongDir;

	u_short						m_uStoredRepeatCount;	// 0xffff means infinite
	u_short						m_uCurrentRepeatCount;	// 0xffff means infinite

	short						m_iAnimDirection;
	short						m_iCurrentAnimSequence;

private:
	typedef Asura_GUIMenu_Widget_Base PARENT;
};
#endif // ASURA_USE_GUI_MENU_SYSTEM
#endif // __ASURA_GUIMENU_WIDGET_ANIMATINGIMAGE_H__
