#pragma once

#include "kpi_decoder.h"
#include "kpi_impl.h"
#include "kbnsfplug_config.h"
#include "kbnsfplug_nsfconfig.h"

#include "nsfplug_ui.h"
class NSFDialogManager;
class KbNsfplugUIThread;
class WA2InputModule2;
class KbNsfplugDecoder : public KbKpiUnknownImpl<IKpiDecoder>
{
private:
    static KbNsfplugUIThread  *s_pThread;
    static NSFDialogManager *s_pManager;
    static NSFPlayerConfigMem *s_pNsfConfig;
    static NSFplug_Model s_Model;
    static bool s_bResetConfig;
    static bool s_bResetPos;
    KPI_MEDIAINFO  m_MediaInfo;
    IKpiConfig     *m_pConfig;
    xgm::NSFPlayer *m_pNsfPlayer;
    xgm::NSF       *m_pNsf;
    NSFDialogManager *m_pManager;
    NSFplug_Model m_Model;
    bool          m_bTrack; //演奏情報を表示する場合は true
    bool          m_bMemory;//メモリ画面を表示する場合は true
    bool          m_bInfo;  //プロパティを表示する場合は true
    bool          m_bUpdated;
    WA2InputModule2 *m_pWa2;
    UINT64        m_qwCurPos;//現在の再生(デコード)位置
    struct KMP_STATUS{//本体の再生位置を取得するための構造体(非公式)
        DWORD dwStructSize;//=sizeof(KMP_STATUS) //プラグイン側で設定
        DWORD dwAccepted;  //本体が受け入れてば 1//本体側で設定(作成直後にプラグイン側で 0 にする)
        DWORD dwPosition;  //再生位置(ms)        //本体側で設定
        DWORD dwStatus;    //KPI_STATUS_STOP/KPI_STATUS_PLAYING/KPI_STATIS_PAUSE(kpi_player.h)//本体側で設定
    };
    HANDLE         m_hFileMap;//KMP_STATUS を得るためのファイルマップハンドル
    KMP_STATUS    *m_pStatus;
    void __fastcall CheckUpdated(void);
    void __fastcall CreateStatusFileMap(void);
    void __fastcall GetTagInfo(IKpiTagInfo *pTagInfo, DWORD dwTagGetFlags);

public:
    DWORD  __fastcall Open(const KPI_MEDIAINFO *cpRequest, 
                           IKpiFile   *pFile, 
                           IKpiFolder *pFolder,
                           IKpiConfig *pConfig);
    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);
   
    KbNsfplugDecoder(IKpiConfig *pConfig);
    ~KbNsfplugDecoder(void);
    xgm::NSFPlayer* GetPlayer(){return m_pNsfPlayer;}
    int GetOutputTime();
    static void Initialize(IKpiConfig *pConfig);
    static void CreateUIThread(IKpiConfig *pConfig);
    static void UnInitialize(IKpiConfig *pConfig);
    static void OpenDialog(IKpiConfig *pConfig, int id);
    static void ResetConfig(void);
    static void ResetPos(void);
};
