/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
////																					 ////
////																					 ////
////								  - HRecNotify.cpp -								 ////
////																					 ////
////																					 ////
////				Implémentation des fonctions SCOL de la librairie sonore			 ////
////									 Version  1.0									 ////
////																					 ////
////								  Hilaire Verschuere								 ////
////																					 ////
////																					 ////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////


#include "../Basic/ZooScene.h"
//extern const GUID IID_IDirectSoundNotify ;
DEFINE_HGUID(IID_IDirectSoundCaptureNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16);

//-----------------------------------------------------------------------------
// Name: HRecNotify::HRecNotify()
// Constructor
//-----------------------------------------------------------------------------
HRecNotify::HRecNotify( HRecord* pHRecord )
		   :HThread()	
{
	Event = CreateEvent( NULL, FALSE, FALSE, NULL ) ;
	this->pHRecord = pHRecord ;
}



//-----------------------------------------------------------------------------
// Name: HRecNotify::~HRecNotify()
// Destructor
//-----------------------------------------------------------------------------
HRecNotify::~HRecNotify()
{
	Stop() ;
	SAFE_CLOSE_HANDLE( Event ) ;
}


//-----------------------------------------------------------------------------
// Name: HRecNotify::~HRecNotify()
// Thread routine
//-----------------------------------------------------------------------------
DWORD HRecNotify::ThreadProc()
{
	MSG msg ;
    DWORD	dwResult;

    while( ThreadIsRunning ) 
    {
		dwResult = MsgWaitForMultipleObjects( 1, &Event, FALSE, INFINITE, QS_ALLEVENTS );

        switch( dwResult )
        {
            case WAIT_OBJECT_0 :
                // hNotificationEvent is signaled This means that DirectSound just finished playing 
                // a piece of the buffer, so we need to fill the circular buffer with new sound from the file
                pHRecord->RecordCapturedData() ;
                break;

            case WAIT_OBJECT_0 + 1 :
				while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) 
				{ 
					if( msg.message == WM_QUIT ) ThreadIsRunning = false ;
				}
				break;
        }
    }

    return 0;
}





//-----------------------------------------------------------------------------
// Name: HRecNotify::SetNotify()
// Set notification points to the buffer
//-----------------------------------------------------------------------------
HRESULT HRecNotify::SetNotify( LPDIRECTSOUNDCAPTUREBUFFER m_pBuffer, DWORD dwNotifySize, int nbNotify )
{
	LPDIRECTSOUNDNOTIFY pDSEvt  ;
	DSBPOSITIONNOTIFY*  aPosNotify ;
	
	// Create the notification events, so that we know when to fill
    // the buffer as the sound plays. 

	if( FAILED( m_pBuffer->QueryInterface( IID_IDirectSoundCaptureNotify, (VOID**)&pDSEvt ) ) )
	{
		return ERRMSG( "QueryInterface" );
	}

    aPosNotify = new DSBPOSITIONNOTIFY[ nbNotify ];
    if( aPosNotify == NULL ) return S_FALSE ;
	
    for( DWORD i = 0; i < nbNotify; i++ )
    {
        aPosNotify[i].dwOffset     = dwNotifySize * (i + 1) - 1;
        aPosNotify[i].hEventNotify = Event;             
    }
    
    // Tell DirectSound when to notify us. The notification will come in the from 
    // of signaled events that are handled in WinMain()
    if( FAILED( pDSEvt->SetNotificationPositions( nbNotify, aPosNotify ) ) )
    {
        SAFE_RELEASE( pDSEvt );
        SAFE_DELETE( aPosNotify );
        return ERRMSG( "SetNotificationPositions" );
    }

    SAFE_RELEASE( pDSEvt );
    SAFE_DELETE( aPosNotify );

	return S_OK ;
}