//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//
//=============================================================================//

#ifndef ICLIENTSHADOWMGR_H
#define ICLIENTSHADOWMGR_H

#ifdef _WIN32
#pragma once
#endif

#include "IGameSystem.h"
#include "IClientEntityInternal.h"
#include "engine/ishadowmgr.h"
#include "IVRenderView.h"
#include "toolframework/IToolEntity.h"

//-----------------------------------------------------------------------------
// Forward decls
//-----------------------------------------------------------------------------
struct FlashlightState_t;


//-----------------------------------------------------------------------------
// Handles to a client shadow
//-----------------------------------------------------------------------------
enum ShadowReceiver_t
{
	SHADOW_RECEIVER_BRUSH_MODEL = 0,
	SHADOW_RECEIVER_STATIC_PROP,
	SHADOW_RECEIVER_STUDIO_MODEL,
};

//-----------------------------------------------------------------------------
// A struct to keep info about the project texture unlit for hl2wars
// Allocate the shadow texture somewhere static
//-----------------------------------------------------------------------------
struct ProjectTextureUnlitInfo_t
{
	ProjectTextureUnlitInfo_t::ProjectTextureUnlitInfo_t()
	{
		m_PTUnlitShadow = NULL;
		m_PTUnlitMaxs = Vector( 32.0f, 32.0f, 32.0f);
		m_PTUnlitMins = Vector( -32.0f, -32.0f, 0.0f);
		m_cR = 255;
		m_cG = 255;
		m_cB = 255;
		m_cA = 255;
		m_fPTShadowDistance = 50.0f;
		m_vOrigin = Vector(0, 0, 0);
		m_Angle = QAngle(0, 0, 0);
	}

	CMaterialReference *m_PTUnlitShadow;
	Vector m_PTUnlitMaxs;
	Vector m_PTUnlitMins;
	Vector m_vOrigin;
	QAngle m_Angle;
	unsigned char m_cR; 
	unsigned char m_cG;
	unsigned char m_cB;
	unsigned char m_cA;
	int m_fPTShadowDistance;
};
//-----------------------------------------------------------------------------
// The class responsible for dealing with shadows on the client side
//-----------------------------------------------------------------------------
abstract_class IClientShadowMgr : public IGameSystemPerFrame
{
public:
	// Create, destroy shadows
	virtual ClientShadowHandle_t CreateShadow( ClientEntityHandle_t entity, int flags ) = 0;
	virtual void DestroyShadow( ClientShadowHandle_t handle ) = 0;

	// Create flashlight.
	// FLASHLIGHTFIXME: need to rename all of the shadow stuff to projectedtexture and have flashlights and shadows as instances.
	virtual ClientShadowHandle_t CreateFlashlight( const FlashlightState_t &lightState ) = 0;
	virtual void UpdateFlashlightState( ClientShadowHandle_t shadowHandle, const FlashlightState_t &lightState ) = 0;
	virtual void DestroyFlashlight( ClientShadowHandle_t handle ) = 0;

	// Create Projected Texture Unlit
	virtual ClientShadowHandle_t CreatePTUnlit( const ProjectTextureUnlitInfo_t &info, ClientEntityHandle_t entity, int flags ) = 0;
	virtual void UpdatePTUnlitState( ClientShadowHandle_t shadowHandle, const ProjectTextureUnlitInfo_t &info, bool force = false ) = 0;
	virtual void DestroyPTUnlit( ClientShadowHandle_t handle ) = 0;
	
	// Indicate that the shadow should be recomputed due to a change in
	// the client entity
	virtual void UpdateProjectedTexture( ClientShadowHandle_t handle, bool force = false ) = 0;

	// Used to cause shadows to be re-projected against the world.
	virtual void AddToDirtyShadowList( ClientShadowHandle_t handle, bool force = false ) = 0;
	virtual void AddToDirtyShadowList( IClientRenderable *pRenderable, bool force = false ) = 0;

	// deals with shadows being added to shadow receivers
	virtual void AddShadowToReceiver( ClientShadowHandle_t handle,
		IClientRenderable* pRenderable, ShadowReceiver_t type ) = 0;

	virtual void RemoveAllShadowsFromReceiver( 
		IClientRenderable* pRenderable, ShadowReceiver_t type ) = 0;

	// Re-renders all shadow textures for shadow casters that lie in the leaf list
	virtual void ComputeShadowTextures( const CViewSetup &view, int leafCount, LeafIndex_t* pLeafList ) = 0;

	// Frees shadow depth textures for use in subsequent view/frame
	virtual void UnlockAllShadowDepthTextures() = 0;
	
	// Renders the shadow texture to screen...
	virtual void RenderShadowTexture( int w, int h ) = 0;

	// Sets the shadow direction + color
	virtual void SetShadowDirection( const Vector& dir ) = 0;
	virtual const Vector &GetShadowDirection() const = 0;
	
	virtual void SetShadowColor( unsigned char r, unsigned char g, unsigned char b ) = 0;
	virtual void SetShadowDistance( float flMaxDistance ) = 0;
	virtual void SetShadowBlobbyCutoffArea( float flMinArea ) = 0;
	virtual void SetFalloffBias( ClientShadowHandle_t handle, unsigned char ucBias ) = 0;

	// Marks the render-to-texture shadow as needing to be re-rendered
	virtual void MarkRenderToTextureShadowDirty( ClientShadowHandle_t handle ) = 0;

	// Advance the frame
	virtual void AdvanceFrame() = 0;

	// Set and clear flashlight target renderable
	virtual void SetFlashlightTarget( ClientShadowHandle_t shadowHandle, EHANDLE targetEntity ) = 0;

	// Set flashlight light world flag
	virtual void SetFlashlightLightWorld( ClientShadowHandle_t shadowHandle, bool bLightWorld ) = 0;

	virtual void SetShadowsDisabled( bool bDisabled ) = 0;

	virtual void ComputeShadowDepthTextures( const CViewSetup &pView ) = 0;

};


//-----------------------------------------------------------------------------
// Singleton
//-----------------------------------------------------------------------------
extern IClientShadowMgr* g_pClientShadowMgr;

#endif // ICLIENTSHADOWMGR_H
