//
// Asura_PlatformRenderEnvironment.h
//
// Created by KJL - 28/02/2003 10:48:11
//
// Copyright (C) 2003 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif

#ifndef __ASURA_PLATFORMRENDERENVIRONMENT_H__
#define __ASURA_PLATFORMRENDERENVIRONMENT_H__

#include "Core/Asura_HashTree.h"
#include "Rendering/Asura_Direct3D.h"

#pragma pack(push, 2)

struct Asura_Direct3D_Env_Vertex
{
	Asura_Vector_3	m_xPosition;
	u_int			m_uNormal;			// packed, compressed normal, 8 bits per component, 8 left over
	u_int			m_uDiffuseRGBA;
	float			m_fU, m_fV;
	float			m_fU2, m_fV2;
};

#pragma pack(pop)

class Asura_Direct3D_Env_Strip
{
	public:
		// The declaration order is important as it gets saved out! Do NOT change!
		// (see Tools_PC_Export.cpp)

		u_int	m_uNumberOfTriangles;
		u_int	m_uStartVertexIndex;
		int		m_iMaterialIndex;

		u_int	m_uLowestVertex;
		u_int	m_uNumberOfVertices;

		u_int	m_uVertexBufferID;
		int		m_iModuleIndex;
};


class Asura_Direct3D_Env_Mesh
{
	public:
		
		u_int m_uNumberOfStrips;
		u_int m_uStartStripIndex;
		u_int m_uVertexBufferID;
};


class Asura_Direct3D_Env_Zone
{
	friend class Asura_Chunk_ResourceFile_PC_Environment;

public:
	// Public typedefs

	// (SB - 11/12/06) Hook to override render states
	typedef void RenderStateOverride(void);

	// Public functions...
	Asura_Direct3D_Env_Zone  (void);
	~Asura_Direct3D_Env_Zone ();


	// Reset function...
	void	Reset							(void);

	// Render functions...
	void	Render							(void);

	void	RenderModuleShadows				(u_short usModuleIndex);

	bool	IsUsingPrecomputedStrips		(void) const	{ return(m_bUsingPrecomputedStrips); }
	bool	IsUsingPrecomputedData			(void) const	{ return(m_bUsingPrecomputedData); }
#if defined(ASURA_TOOLS)
	void	GenerateTriLists				(void);
#endif	// defined(ASURA_TOOLS)

	// (SB - 11/12/06) Added hook to override render state in rendering functions
	static void SetRenderStateOverride(RenderStateOverride* const pfnRenderStateOverride = NULL) { s_pfnRenderStateOverride = pfnRenderStateOverride; };

private:
	// Private functions...
	// Prevent copy construction and assignment operator
	Asura_Direct3D_Env_Zone& operator = ( const Asura_Direct3D_Env_Zone& xOther );
	Asura_Direct3D_Env_Zone( const Asura_Direct3D_Env_Zone& xOther );

	void	UpdateWater						(void);
	void	UpdateScrollingTextures			(void);

	void	RenderAmbientPass				(void);
	void	RenderDynamicLightsPass			(void);
	void	RenderBasicTextures				(void);
	void	RenderRainAndDetailTextures		(void);
	void	RenderSelfIlluminatingPass		(void);
#ifndef ASURA_TARGET_SM3
	void	RenderReflectivePass			(void);
#endif //#ifndef ASURA_TARGET_SM3
#if defined(ASURA_ALPHA_DECAL_HACK_FOR_PSP)
	void	RenderAlphaDecals				(void);
#endif	// defined(ASURA_ALPHA_DECAL_HACK_FOR_PSP)
	void	RenderFlowingWater				(void);
	void	RenderFog						(void);
	void	RenderAdditiveAlpha				(void);

	// Private variables...
			u_int						m_uTotalNumberOfVertexBuffers;
			u_int						m_uNumberOfMeshes;
			u_int						m_uNumberOfStrips;
			Asura_Direct3D_Env_Mesh*	m_pxMeshes;
			Asura_Direct3D_Env_Strip*	m_pxStrips;

			Direct3D_VertexBuffer**		m_ppxVertexBuffer;
			Direct3D_IndexBuffer**		m_ppxIndexBuffer;

			bool						m_bUsingPrecomputedStrips;
			bool						m_bUsingPrecomputedData;
			bool						m_bUsingOwnVertexBuffer; // JAT 26/01/07 - perhaps these should be a u_int uFlags?

	// Scrolling/water texture members
			float						m_fWaterTextureOffsetU;
			float						m_fWaterTextureOffsetV;
			float						m_fWaterPhaseU;
			float						m_fWaterPhaseV;
			float						m_fScrollTextureOffsetU;
			float						m_fScrollTextureOffsetV;

	// Static Textures
	static	int							s_iAttenuationMap;
	static	int							s_iDetailMap;
	static	int							s_iRainSplashTexture;

	static	D3DPRIMITIVETYPE			s_eCurrentPrimitiveType;

	// (SB - 11/12/06) Hook to override render states
	static RenderStateOverride* s_pfnRenderStateOverride;
};

class Asura_Direct3D_EnvRenderer
{
public:
	// Initialisation functions...
	static 	void 						Initialise					(void);
	static 	void 						Reset						(void);
	static 	void 						Shutdown					(void);

	// Render functions...
	static 	void 						Render						(void);

	static	void						ClearRenderMesh				(void);

	static 	void 						BeginEnvironmentShadows		(const D3DMATRIX& xShadowTransform, float fBaseHeight, float fFalloffPerMetre, float initialAlpha);
	static 	void 						RenderModuleShadows			(u_short usModuleIndex);

	static	bool						IsUsingPrecomputedStrips	(void)								{ return(GetCurrentZone().IsUsingPrecomputedStrips()); }
	static	bool						IsUsingPrecomputedData		(void)								{ return(GetCurrentZone().IsUsingPrecomputedData()); }

#if defined(ASURA_TOOLS)
	static	void						GenerateTriLists			(void)								{ GetCurrentZone().GenerateTriLists(); }
#endif

#if defined(ASURA_USE_STREAMING)					
	// Zone functions...
	static	Asura_Direct3D_Env_Zone*	CreateZone					(const Asura_Hash_ID uHash);
	static	bool						DestroyZone					(const Asura_Hash_ID uHash);

	static	void						CreateAndSetZone			(const Asura_Hash_ID uHash)			{ s_pxCurrentZone = CreateZone(uHash); }
	static	void						SetCurrentZone				(Asura_Direct3D_Env_Zone* pxZone)	{ s_pxCurrentZone = pxZone; }
	static	void						SetCurrentZone				(const Asura_Hash_ID uHash)			{ s_pxCurrentZone = s_xZoneTree.GetDataByHash(uHash); }
	static	Asura_Direct3D_Env_Zone&	GetCurrentZone				(void)								{ return(*s_pxCurrentZone); }
#else
	// Zone functions...
	static	Asura_Direct3D_Env_Zone&	GetCurrentZone				(void)								
	{ 
		return(s_xZone); 
	}
#endif	// defined(ASURA_USE_STREAMING)


private:
#if defined(ASURA_USE_STREAMING)
	// Private variables...
	static	Asura_Direct3D_Env_Zone*						s_pxCurrentZone;		// Currently active handler.
	static	Asura_TemplateHashTree<Asura_Direct3D_Env_Zone>	s_xZoneTree;			// Tree of all of the handlers available.
#else
	// Private variables...
	static	Asura_Direct3D_Env_Zone							s_xZone;				// Single static-instance of a zone.
#endif	// defined(ASURA_USE_STREAMING)

	// Traversal function to clear each zone...
	static	void						ResetZone					(Asura_Hash_ID uHash, Asura_Direct3D_Env_Zone* pxZone);
};

#endif//__ASURA_PLATFORMRENDERENVIRONMENT_H__
