//
// Asura_ModuleReverb_System.h
//
// Created by Richard Rice - 12/03/2003
// 
// Copyright (C) 2003 Rebellion, All Rights Reserved.
//


#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef _ASURA_MODULEREVERB_SYSTEM_H_
#define _ASURA_MODULEREVERB_SYSTEM_H_

// Includes
#include "Core/Asura_HashTree.h"

// Forward declarations
class Asura_Vector_3;


//If this value is used for a module's reverb setting , then the environment default
//valuse should be used for that module instead
#define ASURA_REVERB_USE_DEFAULT -1

////////////////////////
// Asura_ModuleReverb //
////////////////////////
class Asura_ModuleReverb
{
public :
	int m_iReverbType;
};


////////////////////////////////
// Asura_ModuleReverb_Handler //
////////////////////////////////
class Asura_ModuleReverb_Handler
{
public:
	Asura_ModuleReverb_Handler()
	: m_iNumberOfModules(0)
	, m_pxModuleReverbArray(0)
	{
		m_xDefaultReverb.m_iReverbType = 0;
	}

	~Asura_ModuleReverb_Handler();

	void Reset();

	void AllocateModuleData(int iNumberOfModules);

	void SetDefaultReverbType(int iReverbType) { m_xDefaultReverb.m_iReverbType = iReverbType; }
	int  GetDefaultReverbType() const          { return m_xDefaultReverb.m_iReverbType; }

	void SetModuleReverbType(int iModule, int iReverbType);
	int  GetModuleReverbType(int iModule) const;

	bool HasModuleDataBeenAllocated() const { return (m_pxModuleReverbArray != 0); }

	// Pass in a position. Searches for a module containing the position.
	// Returns reverb of the module and bool indicating whether we found a module or not.
	const Asura_ModuleReverb* GetReverbSettings(const Asura_Vector_3* pxPosition, bool& bFoundModule) const;

	int GetNumberOfModules() const { return m_iNumberOfModules; }

	#ifdef ASURA_TOOLS
	void DeleteModule(int iModuleIndex);
	#endif //ASURA_TOOLS

private:
	//default reverb setting for those modules that don't overide it
	Asura_ModuleReverb m_xDefaultReverb;

	//reverb settings per module
	int m_iNumberOfModules;
	Asura_ModuleReverb* m_pxModuleReverbArray;
};


///////////////////////////////
// Asura_ModuleReverb_System //
///////////////////////////////
class Asura_ModuleReverb_System
{
public:
	static void Initialise();
	static void Shutdown();
	static void Reset();

	static void AllocateModuleData(int iNumberOfModules)          { GetCurrentHandler().AllocateModuleData(iNumberOfModules); }

	static void SetDefaultReverbType(int iReverbType)             { GetCurrentHandler().SetDefaultReverbType(iReverbType); }
	static int  GetDefaultReverbType()                            { return GetCurrentHandler().GetDefaultReverbType(); }

	static void SetModuleReverbType(int iModule, int iReverbType) { GetCurrentHandler().SetModuleReverbType(iModule, iReverbType); }
	static int  GetModuleReverbType(int iModule)                  { return GetCurrentHandler().GetModuleReverbType(iModule); }

	static bool HasModuleDataBeenAllocated()                      { return GetCurrentHandler().HasModuleDataBeenAllocated(); }

	static const Asura_ModuleReverb* GetReverbSettings(const Asura_Vector_3* pxPosition);

	static int GetNumberOfModules() { return GetCurrentHandler().GetNumberOfModules(); }

	#ifdef ASURA_TOOLS
	static void DeleteModule(int iModuleIndex) { GetCurrentHandler().DeleteModule(iModuleIndex); }
	#endif //ASURA_TOOLS


#if defined(ASURA_USE_STREAMING)
	// Handler functions...
	static	Asura_ModuleReverb_Handler*	CreateHandler(const Asura_Hash_ID uHash);
	static	bool						DestroyHandler(const Asura_Hash_ID uHash);

	static	void						CreateAndSetHandler(const Asura_Hash_ID uHash)           { s_pxCurrentHandler = CreateHandler(uHash); }
	static	void						SetCurrentHandler(Asura_ModuleReverb_Handler* pxHandler) { s_pxCurrentHandler = pxHandler; }
	static	void						SetCurrentHandler(const Asura_Hash_ID uHash)			 { s_pxCurrentHandler = s_xHandlerTree.GetDataByHash(uHash); }
	static	Asura_ModuleReverb_Handler&	GetCurrentHandler()										 { return (*s_pxCurrentHandler); }
	static	Asura_ModuleReverb_Handler*	GetHandler(const Asura_Hash_ID uHash)					 { return s_xHandlerTree.GetDataByHash(uHash); }
	static	bool						IsInitialised(void)										 { return(s_xHandlerTree.GetNumberOfNodes() > 0); }
#else
	// Handler functions...
	static	Asura_ModuleReverb_Handler&	GetCurrentHandler()	{ return s_xHandler; }
	static	bool						IsInitialised(void) { return(true); }
#endif	// defined(ASURA_USE_STREAMING)

private:
#if defined(ASURA_USE_STREAMING)
	static	Asura_ModuleReverb_Handler* s_pxCurrentHandler; // Currently active handler.
	static	Asura_TemplateHashTree<Asura_ModuleReverb_Handler> s_xHandlerTree; // Tree of all of the handlers available.
#else
	static	Asura_ModuleReverb_Handler s_xHandler; // Single static-instance of a zone.
#endif	// defined(ASURA_USE_STREAMING)
};


#endif //_ASURA_MODULEREVERB_SYSTEM_H_
