#include <Mix/MultipleEvent.h>

namespace Mix{

MultipleEvent::MultipleEvent( BOOL bSignal, Boolean bManualReset, UInt32 count ) :
m_EventCount( 0 )
{
	MIX_ASSERT( count > 0 );

	m_EventCount = count;

	for( UInt32 i = 0; i < MAXIMUM_WAIT_OBJECTS; i++ )
	{
		m_hEventArray[i] = NULL;
	}

	for( UInt32 i = 0; i < m_EventCount; i++ )
	{
		m_hEventArray[i] = ::CreateEvent( NULL, bManualReset, bSignal, NULL );
		MIX_ASSERT( m_hEventArray[i] != NULL );
	}
}

MultipleEvent::~MultipleEvent( void )
{
	for( UInt32 i = 0; i < m_EventCount; i++ )
	{
		::CloseHandle( m_hEventArray[i] );
	}
}

void MultipleEvent::Set( UInt32 index )
{
	MIX_ASSERT( m_EventCount > index );

	::SetEvent( m_hEventArray[index] );
}

void MultipleEvent::Reset( UInt32 index )
{
	MIX_ASSERT( m_EventCount > index );

	::ResetEvent( m_hEventArray[index] );
}

void MultipleEvent::SetAll( void )
{
	for( UInt32 i = 0; i < m_EventCount; i++ )
	{
		::SetEvent( m_hEventArray[i] );
	}
}

void MultipleEvent::ResetAll( void )
{
	for( UInt32 i = 0; i < m_EventCount; i++ )
	{
		::ResetEvent( m_hEventArray[i] );
	}
}

Boolean MultipleEvent::Wait( UInt32 index, UInt32 timeOut )
{
	DWORD ret = ::WaitForSingleObject( m_hEventArray[index], timeOut );
	return ( ret == WAIT_TIMEOUT )? ( False ) : ( True );
}

UInt32 MultipleEvent::WaitAll( Boolean bAll, UInt32 timeOut )
{
	DWORD ret = ::WaitForMultipleObjects( m_EventCount, m_hEventArray, bAll, timeOut );
	return ( ret == WAIT_TIMEOUT )? ( 0xFFFFFFFF ) : ( ret - WAIT_OBJECT_0 );
}

HANDLE MultipleEvent::GetHandle( UInt32 index ) const
{
	MIX_ASSERT( m_EventCount > index );

	return m_hEventArray[index];
}

}
