#pragma once

#include "kpi_decoder.h"
#include "kpi_impl.h"
#include "mp4ff/mp4ff.h"

class KbMp4Decoder : public KbKpiUnknownImpl<IKpiDecoder>
{
protected:
    mp4ff_callback_t m_callback;
    mp4ff_t *m_pMp4ff;
    UINT64   m_qwLastSample;   //デコード最終サンプル位置(m_dwSkipSample を含まない)
    UINT64   m_qwCurrentSample;//現在のサンプル位置(読み飛ばした分は数えない)
    int      m_nNumSampleId;
    int      m_nCurrentSampleId;
    int      m_nTrack;
    IKpiFile      *m_pFile;  //AddRef/Release は必要に応じて派生クラスで行う
    KPI_MEDIAINFO  m_MediaInfo;
    KbMp4Decoder(void);
    virtual ~KbMp4Decoder(void) {}//m_pFile/m_pFolder の Release は派生クラスで行う
public:
    //KbMp4Decoder 固有の仮想関数
    virtual DWORD __fastcall Open(const KPI_MEDIAINFO *cpRequest,
                                  IKpiFile   *pFile,
                                  IKpiFolder *pFolder) = 0;
    //ファイルを開く(派生クラスで実装)(1ファイル1曲が前提)
    virtual void __fastcall GetTagInfo(IKpiTagInfo *pTagInfo,
                                       DWORD dwTagGetFlags);
    //IKpiDecoder 派生
    DWORD  WINAPI Select(DWORD dwNumber,
                         const KPI_MEDIAINFO **ppMediaInfo,
                         IKpiTagInfo *pTagInfo,
                         DWORD dwTagGetFlags);
    //1ファイル1曲が前提で選曲(曲番号チェック、GetTagInfo 呼び出しの自動化)
    UINT64 WINAPI Seek(UINT64 qwPosSample, DWORD dwFlag);
    //以下は派生クラスで実装
    //UINT64 WINAPI Seek(UINT64 qwPosSample, DWORD dwFlag);
    //DWORD  WINAPI Render(BYTE *pBuffer, DWORD dwSizeSample);
};

inline uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
{
    IKpiFile *pFile = (IKpiFile*)user_data;
    return pFile->Read(buffer, length);
}
inline uint32_t seek_callback(void *user_data, uint64_t position)
{//戻り値の意味が不明(使ってない？)
    IKpiFile *pFile = (IKpiFile*)user_data;
    pFile->Seek(position, FILE_BEGIN);
    return 0;
}
