#pragma once

#include <streams.h>
#include "../CSimpleFilter/CSimpleFilter.h"

#define FLAC__NO_DLL
#include "stream_decoder.h"

#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "../lib/strmbase.lib")
#pragma comment(lib, "../lib/CSimpleFilter.lib")
#pragma comment(lib, "ogg_static.lib")
#pragma comment(lib, "libFLAC_static.lib")

static const GUID CLSID_DecodeFlac = 
{ 0xac0a8547, 0x178a, 0x49be, { 0xb2, 0x66, 0x3d, 0x6f, 0x8e, 0x32, 0x38, 0x3a } };

static const GUID MEDIASUBTYPE_FLAC_FRAMED =
{ 0x1541c5c0, 0xcddf, 0x477d, { 0xbc, 0x0a, 0x86, 0xf8, 0xae, 0x7f, 0x83, 0x54 } };
class CDecodeFlac : public CSimpleTransform
{
public:
   DECLARE_IUNKNOWN

   CDecodeFlac(LPUNKNOWN, HRESULT *);
   ~CDecodeFlac();

   static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);

   HRESULT OnConnectInPin(const CMediaType *);
   HRESULT OnConnectOutPin(const CMediaType *, int, CMediaType *, int *);
   HRESULT OnTransform(IMediaSample *, IMediaSample *);

   HRESULT OnStart();
   HRESULT OnSeek();

private:

   static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *, FLAC__byte [], size_t *, void *);
   static void metadata_callback(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *);
   static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *);
   static void error_callback(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *);

   WAVEFORMATEX m_outFormat;
   REFERENCE_TIME m_rtCurrent;
   FLAC__StreamDecoder *m_pDecoder;

   BYTE *m_pInBufferPointer;
   int m_nInBufferLength;
   BYTE *m_pOutBufferPointer;
   int m_nOutBufferLength;

   bool m_bMetaData;
   int m_nMaxBlockSize;
};
