#pragma once

#include "kpi_decoder.h"
#include "kpi_impl.h"
#include "kbgsf_config.h"
#include "xsfdrv.h"

class KbGsfDecoder : public KbKpiUnknownImpl<IKpiDecoder>
{
private:
    static KbGsfDecoder *s_pActive;
    KPI_MEDIAINFO  m_MediaInfo;
    kbgsf_Settings m_Settings;
    IXSFDRV    *m_xsfdrv;
    IKpiFile   *m_pFile;
    IKpiFolder *m_pFolder;
    HINSTANCE   m_hXSFDrv;
    UINT64      m_qwCurSample;
    UINT64      m_qwEndSample;
    double      m_volume;
    bool        m_fUTF8;
    static int PASCAL XSFGETLIBCALLBACK(void *lpWork, LPSTR lpszFilename, void **ppBuffer, DWORD *pdwSize)
    {
        return ((KbGsfDecoder*)lpWork)->GetLib(lpszFilename, ppBuffer, pdwSize);
    }
    int GetLib(LPSTR lpszFilename, void **ppBuffer, DWORD *pdwSize);
    bool LoadDrv(void);
    bool Load(const BYTE *buf, size_t size);
public:
    DWORD __fastcall Open(const KPI_MEDIAINFO *cpRequest,
                          IKpiFile *pFile,
                          IKpiFolder *pFolder);
    DWORD  WINAPI Select(DWORD dwNumber,
                         const KPI_MEDIAINFO **ppMediaInfo,
                         IKpiTagInfo *pTagInfo,
                         DWORD dwTagGetFlags);
    UINT64 WINAPI Seek(UINT64 qwPosSample, DWORD dwFlag);
    DWORD  WINAPI Render(BYTE *pBuffer, DWORD dwSizeSample);
    DWORD  WINAPI UpdateConfig(void *pvReserved){return 0;}
    static void __fastcall Init(IKpiConfig *pConfig);
    static void __fastcall Deinit(void);
    KbGsfDecoder(IKpiConfig *pConfig);
    ~KbGsfDecoder(void);
};
