//
// Tools_Sound_System.h
//
// Created by Richard Rice - 19/08/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __TOOLS_SOUND_SYSTEM__
#define __TOOLS_SOUND_SYSTEM__

// Asura Platform-independent
#include "Interface/Asura_Overlay.h"
#include "Interface/Asura_Tree_Dialog.h"

#if !defined ASURA_USE_AUDIO_SYSTEM
#include "Sound/Asura_ProjectSoundIDs.h"  // project-supplied file, needed for sound ID define
#endif

// Tools
#include "Misc/Tools_Modal_Overlay.h"

const char* const szTOOLS_AUDIO_REVERB_FILENAME = "Sounds\\Reverb.asr";

class Asura_Dialog;
class Asura_Tickbox_Dialog;
class Asura_WAVAlign_Dialog;
class Tools_Mixer_Setting;

template<class T> class List;

class Tools_Sound_System
{
public :
	static void Initialise();
	static void Shutdown();

	static void Update();

	static bool IsMusicMixerMuted();
	static bool AreAnyMixersMuted();

	static bool IsMutePhonon(){return s_bMutePhonons;}
	static bool IsMuteStreaming(){return s_bMuteStreaming;}

	static bool IsDontLoadWavs(){return s_bDontLoadWavs;}
	static bool ShouldLoadWavsOnQuitToGame(){return s_bLoadWavsOnQuitToGame;}

	static void AddOverlayControls(class Asura_Overlay* pxOverlay,class Asura_Vector_2& xOffset);

	#ifdef ASURA_USE_AUDIO_SYSTEM
	// Overlay for audio system streaming sounds
	static void CreateStreamingOverlay();
	static void DestroyStreamingOverlay();
	static void ToggleStreamingOverlay();

	static void SetStreamingModified() { s_bStreamingChanged = true; }
	static bool IsStreamingModified() { return s_bStreamingChanged; }
	static void SaveStreaming();

	// Overlay for audio system reverbs
	static void CreateReverbOverlay();
	static void DestroyReverbOverlay();
	static void ToggleReverbOverlay();

	static void SetReverbModified() { s_bReverbChanged = true; }
	static bool IsReverbModified() { return s_bReverbChanged; }
	static void SaveReverb();

	static void ResetReverb( class Asura_Audio_Reverb& xReverb, const u_int uPresetIndex );
	#endif

	//Gets the length of a wav file in seconds
	static float GetSoundLength(const char* szFilename);
	static float GetSoundLength(const Asura_Hash_ID uWave);

#if defined ASURA_USE_AUDIO_SYSTEM
	static bool GetSoundWaveData( Asura_Hash_ID uWave, WAVEFORMATEX& xWaveData, MMCKINFO& xWaveCkInfo );
#else
	static bool GetSoundWaveData( Asura_Sound_ID eSoundID, WAVEFORMATEX& xWaveData, MMCKINFO& xWaveCkInfo );
#endif

private :
	static void AddMixerSetting(const char* szName);
	static void CreateMixerSettings();
	static void LoadMixerSettings();
	static void SaveMixerSettings();
	static void ApplyMixerSettings(bool bTools);

	static void AddToSortedMixerSettings(Tools_Mixer_Setting* pxSetting, int iIndent);


	static bool s_bMuteStreaming;//mute streaming background sounds
	static bool s_bMutePhonons;
	static bool s_bDontLoadWavs;
	static bool s_bLoadWavsOnQuitToGame;

	static List<Tools_Mixer_Setting> s_xMixerSettings;
	static List<Tools_Mixer_Setting*> s_xSortedMixerSettings;
	static bool s_bMuteMixersChanged;

	#ifdef ASURA_USE_AUDIO_SYSTEM
	static bool s_bStreamingChanged;
	static bool s_bReverbChanged;
	#endif

	friend class Tools_OptionsFile;
	
};

class Tools_Mixer_Setting
{
public :
	Tools_Mixer_Setting(const char* szName)
	{
		m_xName = szName;

		m_bMuteInGame = false;
		m_bMuteInTools = false;

		m_iIndent;
	}

	Asura_String m_xName;
	Asura_String m_xParent;

	bool m_bMuteInGame;
	bool m_bMuteInTools;

	int m_iIndent;
};

#ifdef ASURA_USE_AUDIO_SYSTEM

////////////////////////////////////////////////////////////////////////////////
//
// Tools_Audio_StreamingOverlay
//
// Overlay to interact with streaming sounds, for use with the new audio system.
// Can be opened in two modes: standard modeless, for general management, and
// modal with 'select' buttons for picking waves for cutscenes etc.
//
////////////////////////////////////////////////////////////////////////////////

class Tools_Audio_StreamingOverlay : public Asura_Overlay
{
public:

	Tools_Audio_StreamingOverlay( const bool bSelectionMode );
	virtual ~Tools_Audio_StreamingOverlay();

	virtual void PerFrameUpdate();

	static bool IsOpen() { return s_pxThis != NULL; }

	static Asura_Hash_ID SelectStream();

protected:

	static bool IsLeafNodeSelected();

	static void OnAddFile();
	static void OnCancel();
	static void OnPreviewPlay();
	static void OnPreviewStop();
	static void OnRemoveFile();
	static void OnSelect();
	static void OnSelectionChange();

	Asura_StringDisplay_Dialog* m_pxFilenameCaption;
	Asura_StringDisplay_Dialog* m_pxPathCaption;
	Asura_WAVAlign_Dialog* m_pxWaveform;
	Asura_Tickbox_Dialog* m_pxLoopControl;

	Asura_TreeDialog_Tree m_xFilenameTree;
	Asura_Handle m_iPreviewHandle;
	bool m_bSelectionChanged;
	bool m_bSoundsChanged;

	// Should only be one of these around
	static Tools_Audio_StreamingOverlay* s_pxThis;
	static Asura_Hash_ID s_uModalResult;

private:

	// Disable copy construction and assignment
	Tools_Audio_StreamingOverlay( const Tools_Audio_StreamingOverlay& );
	Tools_Audio_StreamingOverlay& operator=( const Tools_Audio_StreamingOverlay& );
};

////////////////////////////////////////////////////////////////////////////////
//
// Tools_Audio_ReverbOverlay
//
// Interface for editing reverb effects under the new audio system
//
////////////////////////////////////////////////////////////////////////////////

class Tools_Audio_ReverbOverlay : public Asura_Overlay
{
public:

	Tools_Audio_ReverbOverlay();
	virtual ~Tools_Audio_ReverbOverlay();

	virtual void PerFrameUpdate();

	static bool IsOpen() { return s_pxThis != NULL; }

protected:

	enum
	{
		DID_REVERB_PROPERTY, // Anything tagged with this is a per-reverb property
	};

	Asura_Audio_Reverb* GetSelectedReverb();
	void ResetReverbDialogs();
	void UpdateDialogs();

	static void OnCreateReverb();
	static void OnDeleteReverb();
	static void OnResetReverb();
	static void OnSelectionChange();

	Asura_List_Dialog* m_pxReverbListDlg;

	const char** m_pszReverbNames;

	u_int m_uNumReverbNames;
	int m_iSelectedReverb;
	int m_iSelectedPreset;

	bool m_bModified;

	// Should only be one of these around
	static Tools_Audio_ReverbOverlay* s_pxThis;

private:

	// Disable copy construction and assignment
	Tools_Audio_ReverbOverlay( const Tools_Audio_ReverbOverlay& );
	Tools_Audio_ReverbOverlay& operator=( const Tools_Audio_ReverbOverlay& );
};

////////////////////////////////////////////////////////////////////////////////
//
// Tools_Reverb_DropDownList_Dialog
//
// Specialised drop-down list dialog for selecting a reverb
//
////////////////////////////////////////////////////////////////////////////////

class Tools_Reverb_DropDownList_Dialog : public Asura_Hash_DropDownList_Dialog
{
public:

	Tools_Reverb_DropDownList_Dialog( const Asura_Vector_2& xOffset, const int iNumLines,
		Asura_Hash_ID* puHashID, bool* const pbChanged, const char* const szName = NULL );

	static void RefreshReverbs();

protected:

	virtual int GetListValidID() const { return s_iListValidID; }
	virtual u_int GetNumberOfHashValues() const;
	virtual const char* GetNameByIndex( int iIndex ) const;

private:

	static int s_iListValidID;
};

#endif // ASURA_USE_AUDIO_SYSTEM

#endif //__TOOLS_SOUND_SYSTEM__
