#include "Mix/Private/Sound/StreamingController.h"
#include "Mix/Private/Sound/StreamingControllerMediator.h"
#include "Mix/Private/Sound/Manager.h"
#include "Mix/IO/IReader.h"

namespace Mix{ namespace Sound{

StreamingController* StreamingController::CreateInstance( Mix::IO::IReader* pReader, Mix::Sound::StreamingControllerMediator* pMediator )
{
	return MIX_LIB_NEW_T( Mix::Memory::SECTION_SOUND, StreamingController, pReader, pMediator );
}

StreamingController::StreamingController( Mix::IO::IReader* pReader, Mix::Sound::StreamingControllerMediator* pMediator ) :
m_pReader( NULL ),
m_pMediator( NULL )
{
	MIX_ASSERT( pReader != NULL );
	MIX_ASSERT( pMediator != NULL );

	MIX_ADD_REF( pReader );
	m_pReader = pReader;

	MIX_ADD_REF( pMediator );
	m_pMediator = pMediator;
}

StreamingController::~StreamingController( void )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_TERMINATE, 0 );
	}

	MIX_RELEASE( m_pMediator );
	MIX_RELEASE( m_pReader );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Sound::IController
////////////////////////////////////////////////////////////////////////////////////////////////////

Float32 StreamingController::GetVolume( void ) const
{
	if( m_pMediator == NULL )
	{
		return 0.0f;
	}

	return m_pMediator->GetVolume();
}

void StreamingController::SetVolume( Float32 volume )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->SetVolume( volume );
	}
}

Float32 StreamingController::GetPanpot( void ) const
{
	if( m_pMediator == NULL )
	{
		return 0.0f;
	}

	return m_pMediator->GetPanpot();
}

void StreamingController::SetPanpot( Float32 panpot )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->SetPanpot( panpot );
	}
}

Boolean StreamingController::IsCloneable( void ) const
{
	if( m_pReader == NULL )
	{
		return False;
	}

	return ( m_pReader->GetSourceType() == Mix::IO::IStream::S_BUFFER );
}

Boolean StreamingController::Clone( Mix::Sound::IController** ppController )
{
	MIX_ASSERT( ppController != NULL );
	MIX_ASSERT( m_pReader != NULL );

	if( m_pMediator == NULL )
	{
		return False;
	}

	return Mix::Sound::GetInternalManagerPtr()->CloneStreamingController( m_pReader, ppController );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Sound::IDevice
////////////////////////////////////////////////////////////////////////////////////////////////////

Boolean StreamingController::IsPlaying( void )
{
	if( m_pMediator == NULL )
	{
		return False;
	}

	return m_pMediator->IsPlaying();
}

void StreamingController::Play( Boolean bLoop )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_STOP, 0 );
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_PLAY, ( bLoop == True )? 1 : 0 );
	}
}

void StreamingController::Stop( void )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_STOP, 0 );
	}
}

void StreamingController::Suspend( void )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_SUSPEND, 0 );
	}
}

void StreamingController::Resume( void )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_RESUME, 0 );
	}
}

Boolean StreamingController::IsDisposed( void )
{
	if( m_pMediator == NULL )
	{
		return True;
	}

	return m_pMediator->Join( 0 );
}

void StreamingController::Dispose( void )
{
	if( m_pMediator != NULL )
	{
		m_pMediator->PushEvent( Mix::Sound::BaseMediator::EVENT_TYPE_TERMINATE, 0 );
		m_pMediator->Join( INFINITE );
	}

	MIX_RELEASE( m_pMediator );
	MIX_RELEASE( m_pReader );
}

const wchar_t* StreamingController::GetFilePath( void ) const
{
	if( m_pReader == NULL )
	{
		return Mix::STR_NULL;
	}

	return m_pReader->GetFilePath();
}

}}
