/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: HXClientCFuncs.cpp,v 1.16.2.3 2004/07/09 01:49:47 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#include "HXClientCFuncs.h"
#include "HXClientConstants.h"
#include "CHXClientEngine.h"
#include "IHXClientPlayer.h"
#include "CHXClientPlayer.h"
#include "CHXClientDebug.h"

#include "enter_hx_headers.h"
#include "hxwintyp.h"
#include "hxcom.h"
#include "hxcore.h"

#include "hxsmartptr.h"
HX_SMART_POINTER_INLINE( SPIHXClientEngine, IHXClientEngine );
HX_SMART_POINTER_INLINE( SPIHXPlayer, IHXPlayer );
#include "exit_hx_headers.h"

/*!
  @function ClientEngineSetCallbacks
  @param pClientEngineCallbacks
  @abstract set the client engine callbacks
*/
void ClientEngineSetCallbacks( const HXClientEngineCallbacks* pClientEngineCallbacks )
{
	CHXClientEngine::SetClientEngineCallbacks( pClientEngineCallbacks );
}

/*!
  @function ClientPlayerCreate
  @param pClientPlayerToken out parameter for the client token
  @param pWindow struct defining the window for the player to use for video
  @param userInfo custom value to be passed to callback functions
  @param pClientCallbacks struct defining the client callbacks
  @result true on success, false on fail
  @abstract Creates a new player instance
*/
bool ClientPlayerCreate( HXClientPlayerToken* pClientPlayerToken, SHXClientWindow* pWindow, void* userInfo, const HXClientCallbacks* pClientCallbacks )
{
	HX_RESULT result = HXR_OUTOFMEMORY;
	SPIHXClientEngine spIClientEngine;
	if ( CHXClientEngine::CreateEngine( spIClientEngine.AsInOutParam() ) )
	{
		IHXPlayer* pICorePlayer = NULL;
		result = spIClientEngine->CreatePlayer( pICorePlayer );
		if ( SUCCEEDED( result ) )
		{
			IHXClientPlayer* pIClientPlayer = CHXClientPlayer::Create( spIClientEngine.Ptr(), pICorePlayer, ( HXxWindow* ) pWindow, userInfo, pClientCallbacks );
			CHXASSERT( pIClientPlayer );
			pICorePlayer->Release();
			*pClientPlayerToken = pIClientPlayer;
			return true;
		}
	}
	if ( pClientCallbacks->OnErrorOccurred )
	{
		pClientCallbacks->OnErrorOccurred( userInfo, result, 0, NULL, NULL, NULL ); // XXXSEH: Should we fill in the last 4 arguments?
	}
	*pClientPlayerToken = NULL;
	return false;
}

/*!
  @function ClientPlayerClose
  @param clientPlayerToken
  @abstract Close the player
*/
void ClientPlayerClose( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->Release();
	}
}

/*!
  @function ClientPlayerOpenURL
  @param clientPlayerToken
  @param pURL
  @param pMimeType
  @abstract open the given URL, optionally provide mime type of content
*/
bool ClientPlayerOpenURL( HXClientPlayerToken clientPlayerToken, const char* pURL, const char* pMimeType )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? ( ( 0 != SUCCEEDED( pIClientPlayer->OpenURL( pURL, pMimeType ) ) ) ? true : false ) : false;
}

bool ClientPlayerOpenData( HXClientPlayerToken clientPlayerToken, const char* pURL, const char* pMimeType, UInt32 dataLength, bool autoPlay, void** ppOutData )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? ( ( 0 != SUCCEEDED( pIClientPlayer->OpenData( pURL, pMimeType, dataLength, autoPlay, ppOutData ) ) ) ? true : false ) : false;
}

bool ClientPlayerWriteData( HXClientPlayerToken clientPlayerToken, void* pData, UInt32 bufferLength, unsigned char* pBuffer )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? ( ( 0 != SUCCEEDED( pIClientPlayer->WriteData( pData, bufferLength, pBuffer ) ) ) ? true : false ) : false;
}

void ClientPlayerCloseData( HXClientPlayerToken clientPlayerToken, void* pData )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->CloseData( pData );
}

bool ClientPlayerGetOpenedURL( HXClientPlayerToken clientPlayerToken, char* pURLBuffer, UInt32 bufferLength, UInt32* pUsedBufferLength )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetOpenedURL( pURLBuffer, bufferLength, pUsedBufferLength ) : false;
}

bool ClientPlayerCanViewSource( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->CanViewSource() : false;
}

void ClientPlayerViewSource( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->ViewSource();
}

bool ClientPlayerCanViewRights( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->CanViewRights() : false;
}

void ClientPlayerViewRights( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->ViewRights();
}

/*!
  @function ClientPlayerAuthenticate
  @param clientPlayerToken
  @param shouldValidateUser
  @param pUsername
  @param pPassword
  @result true on success, false on fail
  @abstract provide credentials for authenticating password-protected content
*/
bool ClientPlayerAuthenticate( HXClientPlayerToken clientPlayerToken, bool shouldValidateUser, const char* pUsername, const char* pPassword )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? ( ( 0 != SUCCEEDED( pIClientPlayer->Authenticate( shouldValidateUser, pUsername, pPassword ) ) ) ? true : false ) : false;
}

/*!
  @function ClientPlayerGetContentState
  @param clientPlayerToken
  @result an integer indicating the current state
  @abstract reports the current state of the player
*/
int ClientPlayerGetContentState( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetContentState() : kContentStateNotLoaded;
}

/*!
  @function ClientPlayerSetStatus
  @param clientPlayerToken
  @param pStatus
  @abstract ???
*/
bool ClientPlayerSetStatus( HXClientPlayerToken clientPlayerToken, const char* pStatus )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->SetStatus( pStatus ) : false;
}

/*!
  @function ClientPlayerPlay
  @param clientPlayerToken
  @abstract begin playback
*/
void ClientPlayerPlay( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->Play();
}

/*!
  @function ClientPlayerPause
  @param clientPlayerToken
  @abstract pause playback
*/
void ClientPlayerPause( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->Pause();
}

/*!
  @function ClientPlayerStop
  @param clientPlayerToken
  @abstract stop playback
*/
void ClientPlayerStop( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->Stop();
}

/*!
  @function ClientPlayerStartSeeking
  @param clientPlayerToken
  @result true on success, false on fail
  @abstract start seeking
*/
bool ClientPlayerStartSeeking( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->StartSeeking() : false;
}

/*!
  @function ClientPlayerSetPosition
  @param clientPlayerToken
  @param position
  @result true on success, false on fail
  @abstract seek the player to the given position
*/
bool ClientPlayerSetPosition( HXClientPlayerToken clientPlayerToken, UInt32 position )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? ( ( 0 != SUCCEEDED( pIClientPlayer->SetPosition( position ) ) ) ? true : false ) : false;
}

/*!
  @function ClientPlayerStopSeeking
  @param clientPlayerToken
  @abstract finish seeking
*/
void ClientPlayerStopSeeking( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->StopSeeking();
}

/*!
  @function ClientPlayerGetPosition
  @param clientPlayerToken
  @result the current position in milliseconds
  @abstract return the current position of playback
*/
UInt32 ClientPlayerGetPosition( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetPosition() : 0;
}

/*!
  @function ClientPlayerGetLength
  @param clientPlayerToken
  @result the length of the content in milliseconds
  @abstract return the length of the presentation
*/
UInt32 ClientPlayerGetLength( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetLength() : 0;
}

/*!
  @function ClientPlayerIsLive
  @param clientPlayerToken
  @result true if live (or simulated live,) false if on-demand
  @abstract return the live state of the presentation
*/
bool ClientPlayerIsLive( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->IsLive() : false;
}

/*!
  @function ClientPlayerGetTitle
  @param clientPlayerToken
  @result the title of the current presentation
  @abstract return the presentation's title
*/
const char* ClientPlayerGetTitle( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetTitle() : NULL;
}

/*!
  @function ClientPlayerGetContextURL
  @param clientPlayerToken
  @result the context URL of the current presentation
  @abstract return the context URL
*/
const char* ClientPlayerGetContextURL( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetContextURL() : NULL;
}

/*!
  @function ClientPlayerHasVisualContent
  @param clientPlayerToken
  @result true if video is present, else false
  @abstract determine if the current presentation has video or not
*/
bool ClientPlayerHasVisualContent( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->HasVisualContent() : false;
}

/*!
  @function ClientPlayerGetIdealSize
  @param clientPlayerToken
  @param pSiteIdealWidth out parameter for natural width of presentation
  @param pSiteIdealHeight out parameter for natural height of presentation
  @abstract obtain the natural width & height of the presentation
*/
void ClientPlayerGetIdealSize( HXClientPlayerToken clientPlayerToken, SInt32* pSiteIdealWidth, SInt32* pSiteIdealHeight )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->GetIdealSize( pSiteIdealWidth, pSiteIdealHeight );
	}
	else
	{
		*pSiteIdealWidth = 0;
		*pSiteIdealHeight = 0;
	}
}

/*!
  @function ClientPlayerGetClipBandwidth
  @param clientPlayerToken
  @result integer indicating current bits per second of the presentation
  @abstract obtain the current presentation's bandwidth
*/
SInt32 ClientPlayerGetClipBandwidth( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetClipBandwidth() : 0;
}

/*!
  @function ClientPlayerSetSize
  @param clientPlayerToken
  @param siteWidth
  @param siteHeight
  @abstract resize the video to the specified dimensions
*/
void ClientPlayerSetSize( HXClientPlayerToken clientPlayerToken, SInt32 siteWidth, SInt32 siteHeight )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->SetSize( siteWidth, siteHeight );
}

/*!
  @function ClientPlayerGetSourceCount
  @param clientPlayerToken
  @result the number of sources in the presentation
  @abstract obtain the number of sources in the current presentation
*/
UInt16 ClientPlayerGetSourceCount( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetSourceCount() : 0;
}

/*!
  @function ClientPlayerGetGroupCount
  @param clientPlayerToken
  @result the number of groups in the presentation
  @abstract obtain the number of groups in the current presentation
*/
UInt16 ClientPlayerGetGroupCount( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetGroupCount() : 0;
}

/*!
  @function ClientPlayerGetCurrentGroup
  @param clientPlayerToken
  @result the index of the current group
  @abstract obtain the index of the currently playing group
*/
UInt16 ClientPlayerGetCurrentGroup( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetCurrentGroup() : 0;
}

/*!
  @function ClientPlayerGetGroupURL
  @param clientPlayerToken
  @param groupIndex
  @param pURLBuffer
  @param bufferLength
  @param pUsedBufferLength
  @result true on success, false on fail
  @abstract obtain the url of the specified group
*/
bool ClientPlayerGetGroupURL( HXClientPlayerToken clientPlayerToken, UInt16 groupIndex, char* pURLBuffer, UInt32 bufferLength, UInt32* pUsedBufferLength )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetGroupURL( groupIndex, pURLBuffer, bufferLength, pUsedBufferLength ) : false;
}

/*!
  @function ClientPlayerGetGroupTitle
  @param clientPlayerToken
  @param groupIndex
  @param pTitleBuffer
  @param bufferLength
  @param pUsedBufferLength
  @result true on success, false on fail
  @abstract obtain the title of the specified group
*/
bool ClientPlayerGetGroupTitle( HXClientPlayerToken clientPlayerToken, UInt16 groupIndex, char* pTitleBuffer, UInt32 bufferLength, UInt32* pUsedBufferLength )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetGroupTitle( groupIndex, pTitleBuffer, bufferLength, pUsedBufferLength ) : false;
}

/*!
  @function ClientPlayerSetCurrentGroup
  @param clientPlayerToken
  @param groupIndex
  @result true on success, false on fail
  @abstract skip to the specified group index
*/
bool ClientPlayerSetCurrentGroup( HXClientPlayerToken clientPlayerToken, UInt16 groupIndex )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? ( ( 0 != SUCCEEDED( pIClientPlayer->SetCurrentGroup( groupIndex ) ) ) ? true : false ) : false;
}

/*!
  @function ClientPlayerDrawSite
  @param clientPlayerToken
  @param pSiteRect
  @abstract force the player to redraw the given rect
*/
void ClientPlayerDrawSite( HXClientPlayerToken clientPlayerToken, const SHXClientRect* pSiteRect )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->DrawSite( ( const HXxRect* ) pSiteRect );
}

/*!
  @function ClientPlayerSetVolume
  @param clientPlayerToken
  @param volume
  @abstract set the player's volume
*/
void ClientPlayerSetVolume( HXClientPlayerToken clientPlayerToken, UInt16 volume )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer ) pIClientPlayer->SetVolume( volume );
}

/*!
  @function ClientPlayerGetVolume
  @param clientPlayerToken
  @result the player's volume (0-100)
  @abstract obtain the player's volume
*/
UInt16 ClientPlayerGetVolume( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetVolume() : 0;
}

/*!
  @function ClientPlayerMute
  @param clientPlayerToken
  @param shouldMute
  @abstract mute/unmute the player
*/
void ClientPlayerMute( HXClientPlayerToken clientPlayerToken, bool shouldMute )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->Mute( shouldMute );
	}
}

/*!
  @function ClientPlayerIsMuted
  @param clientPlayerToken
  @result true if muted, false if not
  @abstract determine if the player is muted
*/
bool ClientPlayerIsMuted( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->IsMuted() : false;
}

/*!
  @function ClientPlayerEnableEQ
  @param clientPlayerToken
  @param enable
  @abstract enable/disable the equalizer
*/
void ClientPlayerEnableEQ( HXClientPlayerToken clientPlayerToken, bool enable )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->EnableEQ( enable );
	}
}

/*!
  @function ClientPlayerIsEQEnabled
  @param clientPlayerToken
  @result true if enabled, else false
  @abstract determine if the equalizer is enabled
*/
bool ClientPlayerIsEQEnabled( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->IsEQEnabled() : false;
}

/*!
  @function ClientPlayerSetEQGain
  @param clientPlayerToken
  @param band
  @param gain
  @abstract set the specified equalizer band to the given gain
*/
void ClientPlayerSetEQGain( HXClientPlayerToken clientPlayerToken, int band, SInt32 gain )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->SetEQGain( band, gain );
	}
}

/*!
  @function ClientPlayerGetEQGain
  @param clientPlayerToken
  @param band
  @result the given band's gain
  @abstract determine the given equalizer band's gain
*/
SInt32 ClientPlayerGetEQGain( HXClientPlayerToken clientPlayerToken, int band )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetEQGain( band ) : 0;
}

/*!
  @function ClientPlayerSetEQPreGain
  @param clientPlayerToken
  @param preGain
  @abstract set the equalizer's pre-gain
*/
void ClientPlayerSetEQPreGain( HXClientPlayerToken clientPlayerToken, SInt32 preGain )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->SetEQPreGain( preGain );
	}
}

/*!
  @function ClientPlayerGetEQPreGain
  @param clientPlayerToken
  @result the pre-gain
  @abstract obtain the equalizer's pre-gain
*/
SInt32 ClientPlayerGetEQPreGain( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetEQPreGain() : 0;
}

/*!
  @function ClientPlayerEnableEQAutoPreGain
  @param clientPlayerToken
  @abstract enable/disable the equalizer pre-gain
*/
void ClientPlayerEnableEQAutoPreGain( HXClientPlayerToken clientPlayerToken, bool enable )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->EnableEQAutoPreGain( enable );
	}
}

/*!
  @function ClientPlayerIsEQAutoPreGainEnabled
  @param clientPlayerToken
  @result true if enabled, else false
  @abstract determine if equalizer pre-gain is enabled or disabled
*/
bool ClientPlayerIsEQAutoPreGainEnabled( HXClientPlayerToken clientPlayerToken )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->IsEQAutoPreGainEnabled() : false;
}

/*!
  @function ClientPlayerSetEQReverb
  @param clientPlayerToken
  @param roomSize
  @param reverb
  @abstract set the equalizer reverb
*/
void ClientPlayerSetEQReverb( HXClientPlayerToken clientPlayerToken, SInt32 roomSize, SInt32 reverb )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->SetEQReverb( roomSize, reverb );
	}
}

/*!
  @function ClientPlayerGetEQReverb
  @param clientPlayerToken
  @param pRoomSize
  @param pReverb
  @abstract obtain the equalizer reverb
*/
void ClientPlayerGetEQReverb( HXClientPlayerToken clientPlayerToken, SInt32* pRoomSize, SInt32* pReverb )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->GetEQReverb( pRoomSize, pReverb );
	}
}

/*!
  @function ClientPlayerGetVideoAttribute
  @param clientPlayerToken
  @param attributeKey
  @param pAttributeValue
  @result true on success, false on fail
  @abstract obtain the specified video attribute
*/
bool ClientPlayerGetVideoAttribute( HXClientPlayerToken clientPlayerToken, int attributeKey, float* pAttributeValue )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetVideoAttribute( attributeKey, pAttributeValue ) : false;
}

/*!
  @function ClientPlayerSetVideoAttribute
  @param clientPlayerToken
  @param attributeKey
  @param attributeValue
  @result true on success, false on fail
  @abstract set the specified video attribute
*/
bool ClientPlayerSetVideoAttribute( HXClientPlayerToken clientPlayerToken, int attributeKey, float attributeValue )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->SetVideoAttribute( attributeKey, attributeValue ) : false;
}

/*!
  @function ClientPlayerGetStatistic
  @param clientPlayerToken
  @param pStatisticKey
  @param pValueBuffer
  @param bufferLength
  @param pValueType
  @param pUsedBufferLength
  @result true on success, false on fail
  @abstract obtain the type and value of the specified player statistic
*/
bool ClientPlayerGetStatistic( HXClientPlayerToken clientPlayerToken, const char* pStatisticKey, unsigned char* pValueBuffer, UINT32 bufferLength, int* pValueType, UINT32* pUsedBufferLength )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->GetStatistic( pStatisticKey, pValueBuffer, bufferLength, pValueType, pUsedBufferLength ) : false;
}

/*!
  @function ClientPlayerAddStatisticObserver
  @param clientPlayerToken
  @param pStatisticKey
  @param pStatisticsCallbacks
  @param observerInfo
  @result true on success, false on fail
  @abstract set a watch on a statistic
*/
bool ClientPlayerAddStatisticObserver( HXClientPlayerToken clientPlayerToken, const char* pStatisticKey, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	return pIClientPlayer ? pIClientPlayer->AddStatisticObserver( pStatisticKey, pStatisticsCallbacks, observerInfo ) : false;
}

/*!
  @function ClientPlayerRemoveStatisticObserver
  @param clientPlayerToken
  @param pStatisticKey
  @param pStatisticsCallbacks
  @param observerInfo
  @abstract remove a watch on the specified statistic
*/
void ClientPlayerRemoveStatisticObserver( HXClientPlayerToken clientPlayerToken, const char* pStatisticKey, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo )
{
	IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
	if ( pIClientPlayer )
	{
		pIClientPlayer->RemoveStatisticObserver( pStatisticKey, pStatisticsCallbacks, observerInfo );
	}
}
