/*!
	@file RuUIRenderer.h

	Copyright (c) 2004-2008 All rights reserved
*/

#ifndef _RUUIRENDERER_H_
#define _RUUIRENDERER_H_

#include "../Renderer/RuRenderer.h"
#include "../Renderer/RendererNode/RuRendererNode_RenderContext.h"

#pragma managed(push, off)

// ************************************************************************************************************************************************************

class CRuUIRenderer : public IRuObject
{
	ruRTTI_DECLARE
	ruHEAP_DECLARE
	ruCLASSGUID_DECLARE

protected:
	// ???
	CRuStack<IRuObject *>					m_ru2D_RTStack;
	IRuObject*								m_ru2D_CurrentRenderTarget;

	CRuStack<IRuViewport *>					m_ru2D_ViewportStack;
	IRuViewport*							m_ru2D_CurrentViewport;

	// 2D toolkit objects
	CRuStack<REAL>							m_ru2D_Viewport_Width_Stack;
	CRuStack<REAL>							m_ru2D_Viewport_Height_Stack;
	REAL									m_ru2D_Viewport_Width;
	REAL									m_ru2D_Viewport_Height;

	IRuTexture*								m_ru2D_32BitAtlasTexture;
	IRuTexture*								m_ru2D_32BitAtlasTexture_Text;
	CRuTextureAtlas_Aggregate*				m_ru2D_TextureAtlas;							//!< Texture atlas for the 2D toolkit

	INT32									m_ru2D_ActiveTextureHandle;
	UINT32									m_ru2D_ActiveTextureWidth;
	UINT32									m_ru2D_ActiveTextureHeight;

	Ru2D_UVMode								m_ru2D_UVMode;
	Ru2D_EffectType							m_ru2D_EffectType;								//!< Currently selected 2D effect type
	DWORD									m_ru2D_DiffuseColor;							//!< Currently used diffuse color
	UINT8									m_ru2D_StencilID;
	REAL									m_ru2D_Rotation;								//!< Current rotation angle in radians
	INT32									m_ru2D_MaxPrimitiveCount;						//!< Maximum number of primitives in the buffer
	INT32									m_ru2D_PrimitiveCount;							//!< Number of primitives in the buffer
	UINT32									m_ru2D_RefRTWidth;								//!< Render target width
	UINT32									m_ru2D_RefRTHeight;								//!< Render target height
	UINT32									m_ru2D_RefTextureWidth;							//!< Texture width used for UV calculation
	UINT32									m_ru2D_RefTextureHeight;						//!< Texture height used for UV calculation

	CRuMaterial*							m_ru2D_RefMaterial;

	CRuMesh*								m_ru2D_Mesh;									//!< Renderer buffer mesh
	CRuArrayList<CRuProxyMesh *>			m_ru2D_ProxyMeshes;
	CRuMaterial*							m_ru2D_Material;								//!< Renderer buffer material
	REAL*									m_ru2D_MaterialConstants;
	CRuRectangle							m_ru2D_Fan_SrcRegion;							//!< Fan stitcher source region
	CRuRectangle							m_ru2D_Fan_DestRegion;							//!< Fan stitcher destination region
	CRuArrayList<CRuVector3>				m_ru2D_VertexList;								//!< Piecewise submission vertex list

	CRuVector3*								m_ru2D_Mesh_Position;
	DWORD*									m_ru2D_Mesh_Diffuse;
	REAL*									m_ru2D_Mesh_UV0;
	UINT16*									m_ru2D_Mesh_Indices;

public:
											CRuUIRenderer();
	virtual									~CRuUIRenderer();

	virtual BOOL							Ru2D_PushViewport(IRuViewport *viewport);
	virtual BOOL							Ru2D_PopViewport();
	virtual BOOL							Ru2D_ClearViewport(DWORD clearFlags, RUCOLOR color, REAL z, DWORD stencil);

	virtual BOOL							Ru2D_SetViewportScale(REAL width, REAL height);
	virtual BOOL							Ru2D_PushViewportScale(REAL width, REAL height);
	virtual BOOL							Ru2D_PopViewportScale();
	virtual IRuTexture*						Ru2D_GetReservedDXT5Texture();
	virtual BOOL							Ru2D_SetScissorRect(CRuRectangle *scissorRect);
	virtual BOOL							Ru2D_SetUVMode(Ru2D_UVMode uvMode);
	virtual BOOL							Ru2D_SetEffectType(Ru2D_EffectType effectType);
	virtual BOOL							Ru2D_SetEffectParameter(Ru2D_EffectParameter effectParam, DWORD parameter);
	virtual BOOL							Ru2D_SetShaderParameter(RuParameterType paramType, DWORD param);
	virtual BOOL							Ru2D_SetTexture(IRuTexture *texture, BOOL allowBinding = TRUE, RuTextureChannel texChannel = ruTEXCHANNEL_DIFFUSEMAP);
	virtual BOOL							Ru2D_SetRotation(REAL rotation);
	virtual void							Ru2D_Submit(const CRuRectangle &srcRect, const CRuRectangle &destRect);
	virtual void							Ru2D_Submit(INT32 numRects, const CRuRectangle *srcRect, const CRuRectangle *destRect, const DWORD *color);
	virtual void							Ru2D_Flush();

	virtual void							Ru2D_ConvertCoordinates(CRuVector3 &point);
	virtual void							Ru2D_ConvertCoordinates(CRuRectangle &rectangle);
	virtual void							Ru2D_WorldToViewport(CRuCamera *camera, CRuVector3 &point);
	virtual void							Ru2D_WorldToScreen(CRuCamera *camera, CRuVector3 &point);
	virtual void							Ru2D_HomogeneousToViewport(CRuVector3 &point);
	virtual void							Ru2D_HomogeneousToViewport(CRuRectangle &rectangle);
	virtual void							Ru2D_ViewportToHomogeneous(CRuVector3 &point);
	virtual void							Ru2D_ViewportToHomogeneous(CRuRectangle &rectangle);

	virtual void							Ru3D_Submit(CRuMatrix4x4 *worldTransform, IRuMesh *mesh, IRuMaterial *material);

protected:
	CRuMaterial*							Ru2D_AllocateMaterial();
	void									Ru2D_FlushMaterialStack();

	void									Ru2D_RenderBatch();
};

// ************************************************************************************************************************************************************

#pragma managed(pop)

#endif
