#pragma once

#include "kpi_decoder.h"
#include "kpi_impl.h"
#include "smf_loader.h"

class VstiHost;
class VstiLoader;
class KbVstiDecoder : public KbKpiUnknownImpl<IKpiDecoder>
{
private:
    enum {
        MAX_PORT_NUM = 8    //最大ポート数
    };
    static CRITICAL_SECTION s_cs;
    static LONG s_lInitialized;//未初期化時は -1、初期化済みの場合は 1
    static VstiLoader* s_pLoader;

    KPI_MEDIAINFO m_MediaInfo;
    SmfLoader     m_loader;
    IKpiConfig   *m_pConfig;
    VstiHost     *m_pVsti[MAX_PORT_NUM];//最大8ポート
    int m_midx; // 今のメッセージインデックス
    int m_mnum; // メッセージ総数
    UINT64 m_time_smp;// 今の再生時間(サンプル単位)
    UINT64 m_tend;    // 終了再生時間
    int m_block_size; // サンプル数
    int m_port_num; // ポート数
    int m_loop_idx; // ループポイントのインデックス(ない場合は-1)
    int m_silent_smp;//無音時間(演奏終了検出用)
    SmfLoader::ResetType m_reset_type;//音源リセット
    bool   m_bShowEditor;//設定画面に対応かつ表示する場合は true
    bool   m_bEditorCreate;//設定画面を作成し終わったら true
    bool   m_bCache;
    double m_dVolume;

    int PlayMidi(void* buffer);
    void __fastcall ShowEditor(void);
    void __fastcall CloseEditor(void);
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);
    DWORD  WINAPI Render(BYTE *pBuffer, DWORD dwSizeSample);
    UINT64 WINAPI Seek(UINT64 qwPosSample, DWORD dwFlag);
    DWORD  WINAPI UpdateConfig(void *pvReserved);// {return 0; }
    static void __fastcall Initialize(void);
    static void __fastcall Uninitialize(void);
    static VstiHost* __fastcall GetVsti(IKpiConfig *pConfig);
    static void __fastcall FreeVsti(VstiHost *pVsti);
    KbVstiDecoder(IKpiConfig *pConfig);
    ~KbVstiDecoder(void);
};
