#include <windows.h>

#include "kbGuru2SMF_module.h"
#include "kbGuru2SMF_player.h"
#include "kbGuru2SMF_config.h"

#ifdef _DEBUG
static const DWORD kbGuru2SMF_Version = 0x7FFFFFFF; //デバッグ時は優先度最大
#define KBGURU2SMF_VERSION_STR L"0x7FFFFFFF(Debug)"
#else
static const DWORD kbGuru2SMF_Version = 2;
#define KBGURU2SMF_VERSION_STR L"0.02"
#endif
///////////////////////////////////////////////////////////////////////////////
// {ECE8C197-43F5-437A-9DD4-FF81CC7E52CC}
static const GUID kbGuru2SMF_GUID = 
{ 0xece8c197, 0x43f5, 0x437a, { 0x9d, 0xd4, 0xff, 0x81, 0xcc, 0x7e, 0x52, 0xcc } };

static const wchar_t kbGuru2SMF_Description[] = L"GuruGuruSMF Player v" KBGURU2SMF_VERSION_STR " based on GuruGuruSMF v4.0.7";
static const wchar_t kbGuru2SMF_Copyright[] =  L"kbGuru2SMF.kpi Copyright(C) 2024 Kobarin\r\n"
                                               L"kbGuru2SMF.kpi v0.01 Copyright(C) 2024 You\r\n"
                                               L"GuruGuruSMF Copyright(C) 2003-2021 卯如";
static const DWORD kbGuru2SMF_MultipleInstance = KPI_MULTINST_ONE;
static const DWORD kbGuru2SMF_SupportTagInfo = 0;
static const DWORD kbGuru2SMF_SupportConfig =  1;
static const wchar_t kbGuru2SMF_SupportExts[] = L".mid";
static const wchar_t kbGuru2SMF_MultiSongExts[] = L"";
static const wchar_t kbGuru2SMF_SupportCodecs[] = L"";
static const wchar_t kbGuru2SMF_SupportContainers[] = L"";
static void* kbGuru2SMF_Reserved1 = NULL;
static void* kbGuru2SMF_Reserved2 = NULL;
///////////////////////////////////////////////////////////////////////////////
KbGuru2SMFPlayerModule::KbGuru2SMFPlayerModule(IKpiConfig *pConfig)
    :m_ModuleInfo{
        sizeof(KPI_PLAYER_MODULEINFO),
        KPI_PLAYER_MODULE_VERSION,
        kbGuru2SMF_Version,
        kbGuru2SMF_MultipleInstance,
        kbGuru2SMF_GUID,
        kbGuru2SMF_Description,
        kbGuru2SMF_Copyright,
        kbGuru2SMF_SupportExts,
        kbGuru2SMF_MultiSongExts,
        kbGuru2SMF_Reserved1,
        kbGuru2SMF_Reserved2,
        kbGuru2SMF_SupportTagInfo,
        kbGuru2SMF_SupportConfig,
        0,0,0,0}
{
    m_pConfig = pConfig;
    pConfig->AddRef();
}
///////////////////////////////////////////////////////////////////////////////
KbGuru2SMFPlayerModule::~KbGuru2SMFPlayerModule(void)
{
    m_pConfig->Release();
    GGSFREE();
    GGSUNLOAD();
}
///////////////////////////////////////////////////////////////////////////////
void WINAPI KbGuru2SMFPlayerModule::GetModuleInfo(const KPI_PLAYER_MODULEINFO **ppInfo)
{
    *ppInfo = &m_ModuleInfo;
}
///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbGuru2SMFPlayerModule::Open(const KPI_MEDIAINFO *cpRequest, 
                                        IKpiFile   *pFile,
                                        IKpiFolder *pFolder,
                                        IKpiPlayer **ppPlayer)
{
    kbguru2smf_Settings settings;
    kbguru2smf_GetSettings(m_pConfig, &settings);
    if(GGSINITIALIZE(settings.szDllPath) != GuruGuruSmf::GgsError::NoError){
    //GuruGuruSMF4.dll のロードに失敗
        return 0;
    }
    KbGuru2SMFPlayer *pPlayer = new KbGuru2SMFPlayer(m_pConfig);
    DWORD dwRet = pPlayer->Open(pFile, pFolder);
    if(dwRet == 0){
        pPlayer->Release();
        *ppPlayer = NULL;
    }
    else{
        *ppPlayer = pPlayer;
    }
    return dwRet;
}
///////////////////////////////////////////////////////////////////////////////
BOOL  WINAPI KbGuru2SMFPlayerModule::EnumConfig(IKpiConfigEnumerator *pEnumerator)
{
    return kbguru2smf_EnumConfig(m_pConfig, pEnumerator);
}
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbGuru2SMFPlayerModule::ApplyConfig(const wchar_t *cszSection, //セクション名
                                               const wchar_t *cszKey,     //キー名
                                               INT64 nValue,
                                               double dValue,
                                               const wchar_t *cszValue)     
{
    return kbguru2smf_ApplyConfig(m_pConfig, cszSection, cszKey, nValue, dValue, cszValue);
}
///////////////////////////////////////////////////////////////////////////////
HRESULT WINAPI kpi_CreateInstance(REFIID riid, void **ppvObject, IKpiUnknown *pUnknown)
{
    *ppvObject = NULL;
    if(!IsEqualIID(riid, IID_IKpiPlayerModule)){
        return E_NOINTERFACE;
    }
    IKpiConfig *pConfig = NULL;
    kpi_CreateConfig(pUnknown, &kbGuru2SMF_GUID, NULL, &pConfig);
    IKpiPlayerModule *pPlayerModule = new KbGuru2SMFPlayerModule(pConfig);
    *ppvObject = pPlayerModule;
    pConfig->Release();
    return S_OK;
}
