

#ifndef _SoundManager_H_
#define _SoundManager_H_

#include "STL.h"
#include "SoundGlobal.h"

/////////////////////////////////////////////////////////////////////////////////////////
//	전방 참조

#define DSSCL_NORMAL                0x00000001
#define DSSCL_PRIORITY              0x00000002
#define DSSCL_EXCLUSIVE             0x00000003
#define DSSCL_WRITEPRIMARY          0x00000004

class ISoundObject;
class CSoundBuffer;
class CDirectSound;
class CDirectMusic;
class IStreamHandler;
struct CompareResource;
typedef struct HWND__*	HWND;
typedef unsigned long	DWORD;

/////////////////////////////////////////////////////////////////////////////////////////
//	기본적으로 메모리 사용 한계는 5MB로 잡혀있음.

class CSoundManager
{
public:
	typedef void (*REPORTFUNC)( const char * );

public:
	enum eState
	{
		STATE_USING,
		STATE_UNUSE,
		STATE_DELETED
	};

	struct Resource
	{
		int				used;						//몇 번이나 사용 됐는가?
		DWORD			time;						//사용이 시작 시간 또는 사용이 끝난 시각 또는 폐기된 시각
		ISoundObject *	pSndBuf;
		eState			state;
	};

public:

	typedef map<string, Resource*>	RESOURCES;		//Using, Unuse 리스트들에서 Resource를 참조해야 하므로 여기에 Resource의 포인터로 저장함.
	typedef set<Resource*>			RESLIST;


protected:
	CDirectSound &	m_DSound;
	CDirectMusic &	m_DMusic;

	bool			m_bDSoundEnable;
	bool			m_bDMusicEnable;

	CompareResource *	m_pComparer;

	RESOURCES *		m_pResources;
	RESLIST	*		m_pUsingList;
	RESLIST	*		m_pUnuseList;
	RESLIST	*		m_pDeletedList;

	IStreamHandler*	m_pStreamUpdater;

	REPORTFUNC	ReportFunc;					//디버그용 리포트 함수

protected:
	CSoundManager();

	void		Caching();
	RESLIST *	GetListOfState( eState );
	eState		GetStateOfList( RESLIST * );
	void		MoveResourceTo( Resource &, RESLIST * );
	void		CreateSoundBuffer( Resource &, const char *, bool, bool, int, DWORD );
	Resource &	AddResource( const char * szFilename, bool b3DSound, bool bStream, int, DWORD );
	void		UseResource( Resource & res );
	void		UnuseResource( Resource & res );
	
public:
	//--------------인터페이스---------------//
	static CSoundManager &	GetInstance();
	~CSoundManager();

	void	Create( HWND, DWORD = DSSCL_PRIORITY );
	void	Destroy();

	void			SetMemoryLimit( DWORD limit )			{}
	void			SetReportFunc( REPORTFUNC func )		{ ReportFunc = func; }			//디버그용

	CDirectSound &	GetDirectSound();
	CDirectMusic &	GetDirectMusic()						{ return m_DMusic; }
	DWORD			GetMemoryUse()							{}
	ISoundObject &	GetBuffer( const char * szFilename,
								bool b3DSound = false,
								bool bStream = false,
								int nBuf = 10,
								DWORD dwAddFlag = 0 );
	bool			ReleaseBuffer( ISoundObject & )			{ return false; }

	void			Update();								//StreamBuffer를 하나라도 쓸 경우에만..
	//----------------------------------------//
};


/////////////////////////////////////////////////////////////////////////////////////////

#endif
