#pragma once

#include <windows.h>
#include "kpi_decoder.h"
#include "kpi_impl.h"
#include "baseclasses/streams.h"
#include "kbdshow_decoder_base.h"

//#define ENABLE_ROT
#ifdef _DEBUG
#define ENABLE_ROT
#endif

namespace kpifile_source_filter{
    class MemSourceFilter;
}
interface IVMRWindowlessControl9;
interface IMFVideoDisplayControl;

class KbDShowRenderer: public CBaseRenderer
{
private:
    HANDLE m_hEventWrite;
    HANDLE m_hEventWritten;
    HANDLE m_hEventExit;
    BYTE  *m_pBuffer;
    DWORD  m_dwBufSize;
    DWORD  m_dwPointer;
    DWORD  m_dwBlockAlign;
    HRESULT m_hr;
    HRESULT EndOfStream(){SetEvent(m_hEventExit); return CBaseRenderer::EndOfStream(); }

public:
    KbDShowRenderer(void);
    ~KbDShowRenderer(void);
    HRESULT WaitForRenderTime(){return S_OK;}

   // HRESULT DoRenderSample(IMediaSample* pMediaSample);//{return S_OK;};
    HRESULT DoRenderSample(IMediaSample* pMediaSample){return S_OK;};
    HRESULT Receive(IMediaSample* pMediaSample);
    HRESULT CheckMediaType(const CMediaType*);
    DWORD  __fastcall Render(BYTE* pBuffer, DWORD dwSizeSample);
    void   __fastcall GetInfo(int *pnSampleRate, int *pnChannels, int *pnBitsPerSample);
    STDMETHODIMP Stop(){SetEvent(m_hEventExit);return CBaseRenderer::Stop();}
    void   __fastcall Reset(void){ResetEvent(m_hEventExit);ResetEvent(m_hEventWrite);ResetEvent(m_hEventWritten);}
};
class KbDShowDecoder :  public KbDShowDecoderBase//public KbKpiUnknownImpl<IKpiDecoder>
{
private:
    enum{
        COMMAND_CREATEWINDOW = 0,
        COMMAND_SEEK,
        COMMAND_RUN,
        COMMAND_QUIT,
        COMMAND_SETVIDEOPOS,
    };
#ifdef ENABLE_ROT
    DWORD  m_dwRegister;
    DWORD  m_dwRegisterV;
#endif
    IReferenceClock     *m_pClock;
    KbDShowRenderer     *m_pRenderer;
    kpifile_source_filter::MemSourceFilter *m_pSource;
    kpifile_source_filter::MemSourceFilter *m_pSourceV;
    IGraphBuilder       *m_pGraphBuilder;
    IGraphBuilder       *m_pGraphBuilderV;
    IMediaControl       *m_pMediaControl;
    IMediaControl       *m_pMediaControlV;
    IVideoWindow        *m_pVideoWindow;
    IVMRWindowlessControl  *m_pVmr7;//VMR7
    IVMRWindowlessControl9 *m_pVmr9;//VMR9
    IMFVideoDisplayControl *m_pEvr; //EVR
    wchar_t              m_szVrName[128];
    DWORD                m_dwBlockAlign;
    int                  m_nClockMode;
    bool                 m_bStart;
    bool                 m_bWindowInitialized;
    void __fastcall CreateVideoWindow(void);
    void __stdcall ThreadProc(void);//DirectShow のオブジェクトへのアクセスは全てこのスレッド内で
    void __fastcall MessageLoop(void);
    LRESULT CALLBACK VideoWindowProcInternal(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static void __fastcall DeleteRegKeyEnableOverlays(void);
public:
    BOOL __fastcall Open(const KPI_MEDIAINFO *cpRequest,
                         IKpiConfig *pConfig, 
                         IKpiFile *pFile, 
                         IKpiFolder *pFolder);
    DWORD  WINAPI Select(DWORD dwNumber,
                         const KPI_MEDIAINFO **ppMediaInfo,
                         IKpiTagInfo *pTagInfo,
                         DWORD dwTagGetFlags);
    DWORD  WINAPI Render(BYTE *pBuffer, DWORD dwSizeSample);
    UINT64 WINAPI Seek(UINT64 qwPosSample, DWORD dwFlag);
    DWORD  WINAPI UpdateConfig(void *pvReserved);
    KbDShowDecoder(void);
    ~KbDShowDecoder(void);
};
