
//////////////////////////////////////////////////////////////////////////////
//
// Asura_VideoToTexture.h
// Author    : Jason Turner
// Copyright (c) 2008 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef _ASURA_VIDEOTOTEXTURE_H_
#define _ASURA_VIDEOTOTEXTURE_H_

#include "Core/Asura_LinkList.h"
#include "Core/Asura_Maths.h"
#include "Core/Asura_TextureManagement.h"

//
// NOTES
//	Always sync's the video frame to the current audio
//
class Asura_VideoToTexture
{
public:
	enum ASURA_FMV_FLAGS
	{
		ASURA_FMV_FLAG_DEFAULT					= 0,
		ASURA_FMV_FLAG_LOOP						= 0x0001,	// loop the video at the end (state will never get to COMPLETE).
		ASURA_FMV_FLAG_NO_SOUND					= 0x0002,	// Don't play the FMV audio
	};

	enum PLAYER_STATE
	{
		PLAYER_STATE_UNINITIALISED = 0,
		PLAYER_STATE_INITIALISED,
		PLAYER_STATE_FILE_OPENING,
		PLAYER_STATE_FILE_OPENED,
		PLAYER_STATE_PLAYING,
		PLAYER_STATE_PAUSED,
		PLAYER_STATE_COMPLETE,
		PLAYER_STATE_ERROR
	};

	struct VideoInfo
	{
		u_int m_uWidth;		// clip resolution
		u_int m_uHeight;
		float m_fDuration;	// the clip length in seconds
	};

	typedef void (*RENDER_SUBTITLE_CB_FN)(float fTime);

	Asura_VideoToTexture();
	virtual ~Asura_VideoToTexture();

	//
	// Open FMV (szFMVFilename) and render video into iTextureRTIndex placeholder texture.
	// This just opens the file and loads video frames - call Play() to start playback.
	// If iTextureRTIndex = ASURA_TEXTURE_NONE, then render full-screen.
	//
	bool Open(const char* szFMVFilename, const int iTextureRTIndex = ASURA_TEXTURE_NONE, u_int uSoundTrackIndex = 0);

	//
	// Starts playing FMV.
	// OR Resumes playback after pause.
	//
	bool Play();

	// Pause video + sound playback
	bool Pause();

	virtual void Update();
	virtual void Render();

	PLAYER_STATE GetPlayerState ()
	{
		return m_ePlayerState;
	}

	int GetTextureRTIndex()
	{
		return (m_iTextureRTIndex);
	}

	const Asura_String* GetTextureRTName()
	{
		return (Asura_Texture_Management::GetTextureName(m_iTextureRTIndex));
	}

	ASURA_FMV_FLAGS GetPlayFlags()
	{
		return (m_eFlags);
	}

	void SetPlayFlags(ASURA_FMV_FLAGS eFlags)
	{
		m_eFlags = eFlags;
	}

	void SetSubtitleCallback(RENDER_SUBTITLE_CB_FN pfnRenderSubtitleCB)
	{
		m_pfnRenderSubtitleCB = pfnRenderSubtitleCB;
	}

	RENDER_SUBTITLE_CB_FN GetSubtitleCallback()
	{
		return (m_pfnRenderSubtitleCB);
	}

	// Scale the video playback speed by the game time scale.
	// If this is on, the play speed mirrors the game time scale. Also, Pause and SetPlaySpeed won't work.
	void SetUseGameTimeScale(bool bUseGameTimeScale)
	{
		m_bUseGameTimeScale = bUseGameTimeScale;
	}

	//
	// Set the video playback speed.
	//
	// 1 = normal speed
	// 0 = pause
	// 0.5 = half speed
	// -1 = rewind at normal speed (not all platforms support this).
	//
	// NB If SetUseGameTimeScale() is on, this value is ignored
	bool SetPlaySpeed(float fSpeed);

	float GetPlayedTimeInSeconds()
	{
		return Platform_GetPlayedTimeInSeconds();
	}

	Asura_Handle GetSourceVoiceHandle()
	{
		return (m_iSourceVoiceHandle);
	}

	struct SpeakerProperty
	{
		Asura_Vector_3	m_xPosition;
		float 			m_fInnerRange;
		float 			m_fOuterRange;
	};

	// create a position in the world to route FMV sound through
	void CreateSpeaker(SpeakerProperty& xSpeakerProperty);
	Asura_LinkList<SpeakerProperty>& GetSpeakerPropertyList() {return m_xSpeakerPropertyList;};

	// Get info for currently playing video
	// Only valid after player state has opened
	const VideoInfo* GetVideoInfo();

	void RenderDebugInfo();

	static u_int					s_uTotalMemUsed;
	static u_int					s_uTotalVidMemUsed;

private:
	bool CreateSubmixVoices(void);
	bool Platform_Initialise();
	void Platform_Update();
	void Platform_Render();
	void Platform_Shutdown();
	bool Platform_Open(const char* szFMVFilename, const int iTextureRTIndex, u_int uSoundTrackIndex);
	bool Platform_Play();
	bool Platform_Pause();
	bool Platform_SetPlaySpeed(float fSpeed);
	float Platform_GetPlayedTimeInSeconds();

	static u_int					s_uRefCount;

	int								m_iTextureRTIndex;
	void*							m_pPlatformData;	// platform-specific data
	ASURA_FMV_FLAGS 				m_eFlags;
	PLAYER_STATE					m_ePlayerState;

	bool							m_bUseGameTimeScale;
	float							m_fPlayTimeScale;	// relative playback speed

	Asura_LinkList<SpeakerProperty> m_xSpeakerPropertyList;
	Asura_Handle					m_iSourceVoiceHandle;
	Asura_LinkList<Asura_Handle>	m_xSubmixVoices;
	bool							m_bSubmixVoicesCreated;

	RENDER_SUBTITLE_CB_FN			m_pfnRenderSubtitleCB;
	bool							m_bAutoPlay;		// automatically start playing after opening

	Asura_String					m_xFileName;
	VideoInfo						m_xVideoInfo;
};


#endif // _ASURA_VIDEOTOTEXTURE_H_
