/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2008.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: include/sgx/graphics/sgxtexture_animation.hpp

*/

#ifndef SGX_GRAPHICS_TEXTURE_ANIMATION_HPP
#define SGX_GRAPHICS_TEXTURE_ANIMATION_HPP	1



class CSGXTextureAnimationFrame {
public:
	tUINT32		m_Region;
	tREAL32		m_Duration;

	CSGXTextureAnimationFrame() :
		m_Region(0),
		m_Duration(0.1f) {
		}

	CSGXTextureAnimationFrame(const tUINT32 region, const tREAL32 duration) :
		m_Region(region),
		m_Duration(duration) {
		}
};

class CSGXTextureAnimationData;
class CSGXTextureAnimationSequence;
class CSGXTextureAnimationState;


/**
The @CSGXTextureAnimationManager provides a mechanism whereby the individual
regions of a texture can be animated in any fashion.
*/
class CSGXTextureAnimationManager {
public:
		typedef enum {
		eForwards = 0,
		eForwardsAndStop = eForwards,
		eBackwards,
		eBackwardsAndStop = eBackwards,

		eForwardsAndLoop,
		eBackwardsAndLoop,

		ePingPongForwards,
		ePingPongBackwards,

	} tAnimationIterator;

	static CSGXTextureAnimationData *		loadData(const sgxString &filename);

	static CSGXTextureAnimationData *		createData();
	static CSGXTextureAnimationSequence *	addSequence(CSGXTextureAnimationData *pData, tAnimationIterator runsas = eForwards);
	static tUINT32							addFrame(CSGXTextureAnimationSequence *pSequence, const CSGXTextureAnimationFrame &frame);
	static tUINT32							addFrame(CSGXTextureAnimationSequence *pSequence, CSGXTextureAnimationFrame *pFrame);
	static CSGXTextureAnimationSequence *	getSequence(const CSGXTextureAnimationData *pData, const tUINT32 seqID);
	static CSGXTextureAnimationSequence *	getSequenceFromIndex(const CSGXTextureAnimationData *pData, const tUINT32 seqIndex);

	// Animation state - this is apply to the texture during render/update to 
	// determine which animation frame should be displayed.
	static CSGXTextureAnimationState *		createState(const CSGXTextureAnimationSequence *pSequence=NULL, const tUINT32 iStartFrame=0);
	static void								updateState(CSGXTextureAnimationState *pState, const tREAL32 telaps);

	static tBOOL							startAnimation(CSGXTextureAnimationState *pState, tBOOL running=TRUE);
	static tBOOL							stopAnimation(CSGXTextureAnimationState *pState);
	static void								playStaticCell(CSGXTextureAnimationState *pState, tUINT32 cell);
	static tUINT32							getCurrentFrame(const CSGXTextureAnimationState *pState);
	static tUINT32							getCurrentCell(const CSGXTextureAnimationState *pState);



};

 
class CSGXTextureAnimationSequence {
public:

	tUINT32												m_ID;
	CSGXTextureAnimationManager::tAnimationIterator		m_RunAs;
	sgxVector<CSGXTextureAnimationFrame *>				m_Frames;

	CSGXTextureAnimationSequence(CSGXTextureAnimationManager::tAnimationIterator runas = CSGXTextureAnimationManager::eForwards) : 
	m_RunAs(runas) {
	}
};

class CSGXTextureAnimationData {
public:
	sgxVector<CSGXTextureAnimationSequence *>	m_Sequences;
	// We could include the CSGXTexture backptr here, but its
	// functionality would not be supported everywhere, so we've
	// missed it out for now
};


class CSGXTextureAnimationState {
public:
	typedef enum {
		eForwards,
		eBackwards,
	} tRunDirection;

	CSGXTextureAnimationData *			m_pAnimationData;
	const CSGXTextureAnimationSequence *m_pCurrentSequence;
	tUINT32								m_CurrentFrame;
	tUINT32								m_CurrentDirection;
	tUINT32								m_iCurrentStaticCell;
	tBOOL								m_bIsRunning;
	tBOOL								m_bStaticCell;
	tREAL32								m_fTimeCum;

private:
	CSGXTextureAnimationState(const CSGXTextureAnimationSequence *pSequence=NULL, const tUINT32 iStartFrame=0);

	friend class CSGXTextureAnimationManager;
};


#endif /* SGX_GRAPHICS_TEXTURE_ANIMATION_HPP */
