#pragma once

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

#include "ogg.h"

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

#define CONTAINER_RAW     100
#define CONTAINER_RAW_WAV 101
#define CONTAINER_RAW_AAC 102
#define CONTAINER_RAW_OGG 103

#define CONTAINER_RAW_MP4 1012

// ogg用
#define PACKET_HEADER_BIT            0x01
#define PACKET_HEADER_IDENTIFICATION 0x01
#define PACKET_HEADER_COMMENT        0x03
#define PACKET_HEADER_SETUP          0x05

// {4B1ABFC2-E95F-4CB3-BEC8-657E6D896A70}
static const GUID CLSID_EcoDecoWriter = 
{ 0x4b1abfc2, 0xe95f, 0x4cb3, { 0xbe, 0xc8, 0x65, 0x7e, 0x6d, 0x89, 0x6a, 0x70 } };

// {FB4A5A46-0BB7-4c75-ADA1-E0241EC94E9E}
static const GUID IID_IEcoDecoWriterInterface =
{ 0xfb4a5a46, 0x0bb7, 0x4c75, { 0xad, 0xa1, 0xe0, 0x24, 0x1e, 0xc9, 0x4e, 0x9e } };

// {1BB79127-E01D-4F40-9257-BBC622437FB7}
static const GUID IID_IEcoDecoInterface =
{ 0x1bb79127, 0xe01d, 0x4f40, { 0x92, 0x57, 0xbb, 0xc6, 0x22, 0x43, 0x7f, 0xb7 } };

static const GUID MEDIASUBTYPE_AAC     = { 0x000000ff, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
static const GUID MEDIASUBTYPE_MP3     = { 0x00000055, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
static const GUID MEDIASUBTYPE_Vorbis  = { 0xcddca2d5, 0x6d75, 0x4f98, { 0x84, 0x0e, 0x73, 0x7b, 0xed, 0xd5, 0xc6, 0x3b } };
static const GUID MEDIASUBTYPE_AVI_AC3 = { 0x00002000, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
// -----------------------------------------------------------------------------------------------------------------------------------
typedef struct tagVORBISFORMAT
{
	WORD  nChannels;
	long  nSamplesPerSec;
	long  nMinBitsPerSec;
	long  nAvgBitsPerSec;
	long  nMaxBitsPerSec;
	float fQuality;
} VORBISFORMAT;
// --------------------------------------------------------------------------------------------------------------------
__interface IEcoDecoInterface : public IUnknown
{
public:
   HRESULT SetWait(int);
   HRESULT GetInFormat(WAVEFORMATEX *);
   HRESULT GetTransformedBytes(LONGLONG *);
};
// ------------------------------------------------------------------------------------------------------------------------
__interface IEcoDecoWriterInterface : public IUnknown
{
public:
   int GetOutputMode(void);
   void SetOutputMode(int);
   HRESULT CheckMode(bool);
   HRESULT SetReplaygain(bool, bool);
};
// ------------------------------------------------------------------------------------------------------------------------
class CEcoDecoWriter : public CSimpleWriter , public IEcoDecoInterface , public IEcoDecoWriterInterface
{
public:
   DECLARE_IUNKNOWN

   // コンストラクタとデストラクタ
   CEcoDecoWriter(LPUNKNOWN, HRESULT *);
   ~CEcoDecoWriter();

   // オブジェクト作成関数
   static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);

   // CSimpleWriterの純粋仮想メソッド
   HRESULT OnConnectInPin(const CMediaType *);

   // CSimpleWriterのオーバーライド
   HRESULT OnReceive(HANDLE, IMediaSample *);
   HRESULT OnStart(HANDLE);
   HRESULT OnStop(HANDLE, bool);
   STDMETHODIMP OnQueryInterface(REFIID, void **);

   // IEcoDecoInterface
   HRESULT SetWait(int);
   HRESULT GetInFormat(WAVEFORMATEX *);
   HRESULT GetTransformedBytes(LONGLONG *);

   // IEcoDecoWriterInterface
   int GetOutputMode(void);
   void SetOutputMode(int);
   HRESULT CheckMode(bool);
   HRESULT SetReplaygain(bool, bool);

private:

   // ユーザ関数
   void MakeAdtsHeader(void);
   HRESULT WriteWavHeader(HANDLE);
   HRESULT WriteOggPage(HANDLE, IMediaSample *, bool);

   // ユーザ変数
   int m_nWait;
   LONGLONG m_llInputSize;

   int m_nOutputType;
   WAVEFORMATEX m_inFormat;

   bool m_bCheckMode;
   bool m_bUseTrackgain;
   bool m_bUseAlbumgain;

   // wav用
   LONGLONG m_llWriteDataSize;

   // aac用
   BYTE m_adtsHeader[7];

   // ogg用
   int m_nPacketNumber;
   ogg_stream_state m_os;
   VORBISFORMAT m_volbisFormat;
};
// -----------------------------------------------------------------------------------------------------------------------------------
