///////////////////////////////////////////////////////////////////////////////////////////
// DirectMusic.cpp
//
//  Implementation of the DirectMusic class, which wraps a DirectMusic performance and
// loader object.

#include "StdAfx.h"
#include "DirectMusic.h"
#include "DirectXException.h"

#pragma comment(lib, "amstrmid.lib")

using namespace System::Runtime::InteropServices;

namespace Sunlight
{
    namespace DirectX
    {
        namespace SoundMusic
        {
            DirectMusic::DirectMusic() :
                m_pPerformance(NULL),
                m_pLoader(NULL),
                Channels(64),
                AudioPath(StereoPlusReverb),
                ParentWindow(NULL),
                m_bCreated(false)
            {
            }

            DirectMusic::~DirectMusic()
            {
                if (m_pPerformance)
                {
                    m_pPerformance->CloseDown();
                    m_pPerformance->Release();
                    m_pPerformance = NULL;
                }
                if (m_pLoader)
                {
                    m_pLoader->Release();
                    m_pLoader = NULL;
                }
            }

            // Create the DirectMusic object and initialise the audio path.
            void DirectMusic::Create()
            {
                if (ParentWindow == NULL)
                    throw new ArgumentNullException(S"ParentWindow");

                if (m_bCreated)
                    return;

                IDirectMusicPerformance8 __nogc *pPerf;
                IDirectMusicLoader8 __nogc *pLoader;
                HRESULT h;

                h = ::CoCreateInstance(CLSID_DirectMusicPerformance, NULL, 
                                CLSCTX_INPROC, IID_IDirectMusicPerformance8,
                                (void **)&pPerf);
                if (FAILED(h))
                    Marshal::ThrowExceptionForHR(h);

                m_pPerformance = pPerf;

                h = ::CoCreateInstance(CLSID_DirectMusicLoader, NULL, 
                                CLSCTX_INPROC, IID_IDirectMusicLoader8,
                                (void **)&pLoader);
                if (FAILED(h))
                    Marshal::ThrowExceptionForHR(h);
                
                m_pLoader = pLoader;

                h = m_pPerformance->InitAudio(NULL, NULL, (HWND)ParentWindow->Handle.ToPointer(), 
                    AudioPath, Channels, DMUS_AUDIOF_ALL, NULL);
                if (FAILED(h))
                    throw new Sunlight::DirectX::DirectXException(S"IDirectMusicPerformance8::InitAudio", h);

                m_bCreated = true;
            }

            // Stops all DirectMusic objects currently playing.
            void DirectMusic::StopAll()
            {
                m_pPerformance->Stop(NULL, NULL, 0, 0);
            }
        }
    }
}