/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 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 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (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.  
 *  
 * 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 ***** */

// rta includes 
#include "ihxtprofile.h"
#ifdef _MAC_MACHO
#include <Carbon/Carbon.h>
#endif
#include "ihxtbase.h"				

// reader includes
#include <stdio.h>	
#include <sys/stat.h>
#include "InWAVReader.h"		

// local includes
#include "InWAVFilter.h"	
#include "assert.h"


/////////////////////////////////////////////////////////////////////////
// Method:
//	CRSInWAVFilter ( Probably leave as is )
// Purpose:
//	Constructor
//
//	STEP 1 - Change class name in all methods to reflect your plugin filter's class name 
CRSInWAVFilter::CRSInWAVFilter( )
	: m_pAllocator( NULL )
	, m_bFormatReady( FALSE )
{
}

/////////////////////////////////////////////////////////////////////////
// Method:
//	CRSInWAVFilter ( Probably leave as is )
// Purpose:
//	Destructor
CRSInWAVFilter::~CRSInWAVFilter( )
{
	HX_RELEASE( m_pAllocator );

	// call closure code
	ReaderClose();
}

/////////////////////////////////////////////////////////////////////////
// Method:
//	SetFactory ( Leave almost as is )
// Purpose:
//	receives RSMA factory from GM 
STDMETHODIMP CRSInWAVFilter::SetFactory( IHXCommonClassFactory* pFactory )
{
	if (!pFactory)
		return HXR_POINTER;

	// Obtain an entrypoint to the log system
	IUnknown* pIUnk;
	if( SUCCEEDED( pFactory->CreateInstance( IID_IHXTLogWriter, (void**)&pIUnk )) )
	{
		// 2 - add method to low level class to set the log writer which can be used in all derived classes
		IHXTLogWriter* pILogWriter = NULL;
		pIUnk->QueryInterface(IID_IHXTLogWriter, (void**)&pILogWriter);
		HX_RELEASE(pIUnk);
		
		if( pILogWriter )
		{
			SetLogWriter( pILogWriter );
			HX_RELEASE( pILogWriter );
		}
	}
	return HXR_OK;
}

/////////////////////////////////////////////////////////////////////////
// Method:
//	SetAllocator  ( Probably leave as is )
// Purpose
//	Set the allocator for a particular output 
STDMETHODIMP CRSInWAVFilter::SetAllocator ( UINT32 ulOutputStreamID, IHXTSampleAllocator* pAllocator )
{
	if ( ulOutputStreamID != 0 || pAllocator == NULL )	
	{
		assert( FALSE );
		return HXR_INVALID_PARAMETER;		
	}
	HX_RELEASE(m_pAllocator);
	m_pAllocator = pAllocator;
	m_pAllocator->AddRef();

	return HXR_OK;	
}


/////////////////////////////////////////////////////////////////////////
// Method:
//	Prime ( Probably leave as is )
// Purpose:
//	Notification that the filter is about to receive data
STDMETHODIMP CRSInWAVFilter::Prime( UINT32 ulOutputStreamID )
{
	if (ulOutputStreamID != 0)
	{
		return HXR_INVALID_PARAMETER;
	}
	
	if ( !m_bFormatReady )
	{
		return HXR_ENC_IMPROPER_STATE;
	}

	HX_RESULT res = HXR_OK;
	if (SUCCEEDED(res))
	{
		// don't allow property changes after this point
		if( m_pLogWriter )
			m_pLogWriter->LogMessage( kRealNetworks, LC_SDK_DIAG, FILEOUT, NO_TRANSLATE, "Prime method called on rn-avfile-wavuncompressed.");
	}
	else
	{
		if( m_pLogWriter )
			m_pLogWriter->LogMessage( kRealNetworks, LC_SDK_ERROR, FILEOUT, NO_TRANSLATE, "WAV Reader failed Prime Method");
	}
	return  res;	
}


/////////////////////////////////////////////////////////////////////////
// Method:
//	ReadSample ( Change to support reading from your input file )
// Purpose:
//  Normally - reads data from file ( or pulls from a queue)
//
// STEP 2 - Fill in to obtain data from the input file
// 
STDMETHODIMP CRSInWAVFilter::ReadSample ( UINT32 uStreamID, IHXTMediaSample** /*Out*/ ppSample )
{
	HX_RESULT res = HXR_OK;
	
	IHXTMediaSample* pOutSample;
	m_pAllocator->GetMediaSampleOfSize( m_uOneWAVFrameSize, &pOutSample );

	HXT_TIME TimeStart;
	HXT_TIME TimeEnd;
	UINT32 uBytesRead = ReadFile( pOutSample->GetDataStartForWriting(), m_uOneWAVFrameSize , &TimeStart, &TimeEnd );

	pOutSample->SetDataSize( uBytesRead );
	pOutSample->SetTime( TimeStart, TimeEnd );	

	if (!uBytesRead)
	{
		pOutSample->SetSampleFlags( pOutSample->GetSampleFlags() | HXT_SAMPLE_ENDOFSTREAM );
		if( m_pLogWriter )
		{
			m_pLogWriter->LogMessage( kRealNetworks, LC_APP_INFO, FILEOUT, NO_TRANSLATE, "WAV reader sending end of stream sample.");
		}
	}
	*ppSample = pOutSample;
	return res;
}

/////////////////////////////////////////////////////////////////////////
// Method:
//	TearDown
// Purpose:
//	Notification that filter should teardown
//
//  STEP 3 - Fill in whatever is needed to properly teardown filter
// 
STDMETHODIMP CRSInWAVFilter::Teardown( UINT32 uStream )
{
	if (uStream != 0)
	{
		return HXR_INVALID_PARAMETER;
	}
	// call transform teardown operations 
	if( m_pLogWriter )
	{
		m_pLogWriter->LogMessage( kRealNetworks, LC_APP_DIAG, FILEOUT, NO_TRANSLATE, "Shutting down WAV reader");
	}
	
	// close down all objects 
	ReaderClose();
	return  HXR_OK;	
}


/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// The following methods will most likely never need to be changed
// so you can leave them as is
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////
// Method:
//	SetGraphServices ( Probably leave as is )
// Purpose:
//	obtain services from the service broker such as event sink  (if not used return HXR_OK)
STDMETHODIMP CRSInWAVFilter::SetGraphServices( IHXTServiceBroker *pServiceBroker )
{
	return HXR_OK;
}


/////////////////////////////////////////////////////////////////////////
// Method:
//	DiscardCachedSamples
// Purpose:
//	Notification that the filter should discard any cached samples - return HXR_OK if not used
STDMETHODIMP CRSInWAVFilter::DiscardCachedSamples( UINT32 ulOutputStreamID )
{
	if (ulOutputStreamID != 0)
	{
		return HXR_INVALID_PARAMETER;
	}
	return  HXR_OK;	
}


/////////////////////////////////////////////////////////////////////////
// Method:
//	QueryInterface ( Leave as is )
// Purpose:
//	QI for filter interfaces 
STDMETHODIMP CRSInWAVFilter::QueryInterface( REFIID riid, void** ppvObj )
{
	if (IsEqualIID(riid, IID_IUnknown))
	{
		AddRef();
		*ppvObj = (IUnknown*) (IHXTFilter*) this;
		return HXR_OK;
	}
	else if (IsEqualIID(riid, IID_IHXTFilter))
	{
		AddRef();
		*ppvObj = (IHXTFilter*) this;
		return HXR_OK;
	}
	else if (IsEqualIID(riid, IID_IHXTInputFilter))
	{
		AddRef();
		*ppvObj = (IHXTInputFilter*) this;
		return HXR_OK;
	}
	*ppvObj = NULL;
	return HXR_NOINTERFACE;
}





