#include <windows.h>
#include <stdio.h>
#include "kbwsr_module.h"
#include "kbwsr_config.h"
#include "kbwsr_decoder.h"
//////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
static const DWORD kbwsr_Version = 0x7FFFFFFF;//デバッグ時は優先度最大
#define KBWSR_VERSION_STR L"0x7FFFFFFF(Debug)"
#else
static const DWORD kbwsr_Version = 9;
#define KBWSR_VERSION_STR L"0.09"
#endif

//エミュレーションコアのバージョンが変わったら kbwsr_config.cpp を修正する

static const wchar_t kbwsr_Description[] = L"WonderSwan Sound Decoder v" KBWSR_VERSION_STR " based on foo_input_wsr v0.32";
static const wchar_t kbwsr_Copyright[] =   L"kbwsr.kpi Copyright (C) 2016-2024 Kobarin\n"
                                           L"foo_input_wsr Copyright (C) 2014-2024 Unknown Japanese author\n"
                                           L"in_wsr.dll Copyright (C) 2006 Unknown Japanese author\n"
                                           L"Oswan Copyright (C) toyo\n"
                                           L"mednafen Copyright (C) 2005-2022 Mednafen Team";

// {567714FF-D065-4FA6-A7FD-1DD9E8DA6B92}
static const GUID kbwsr_GUID = 
{ 0x567714ff, 0xd065, 0x4fa6, { 0xa7, 0xfd, 0x1d, 0xd9, 0xe8, 0xda, 0x6b, 0x92 } };

static const DWORD kbwsr_MultipleInstance = KPI_MULTINST_ONE;
static const wchar_t kbwsr_SupportExts[] = L".wsr/.wsc";
static const wchar_t kbwsr_MultiSongExts[] = L".wsr";
static const DWORD kbwsr_SupportTagInfo = KPI_DECODER_MODULEINFO::TAG_EXTRA;
static const DWORD kbwsr_SupportConfig = 1;
static void* kbwsr_Reserved1 = NULL;
static void* kbwsr_Reserved2 = NULL;
//////////////////////////////////////////////////////////////////////////////
KbWsrDecoderModule::KbWsrDecoderModule(IKpiConfig *pConfig)
    :m_ModuleInfo{
        sizeof(KPI_DECODER_MODULEINFO), //cb(=sizeof(KPI_DECODER_MODULEINFO))
        KPI_DECODER_MODULE_VERSION,     //dwModuleVersion(=KPI_DECODER_MODULE_VERSION)
        kbwsr_Version,
        kbwsr_MultipleInstance,
        kbwsr_GUID,
        kbwsr_Description,
        kbwsr_Copyright,
        kbwsr_SupportExts,
        kbwsr_MultiSongExts,
        kbwsr_Reserved1,
        kbwsr_Reserved2,
        kbwsr_SupportTagInfo,
        kbwsr_SupportConfig,
        0, 0, 0, 0                   //reserved
     }
{
    m_szDescription[0] = 0;
    m_pConfig = pConfig;
    pConfig->AddRef();
}
//////////////////////////////////////////////////////////////////////////////
KbWsrDecoderModule::~KbWsrDecoderModule(void)
{
    m_pConfig->Release();
}
//////////////////////////////////////////////////////////////////////////////
void  WINAPI KbWsrDecoderModule::GetModuleInfo(const KPI_DECODER_MODULEINFO **ppInfo)
{
    wchar_t szCore[128];
    kbwsr_GetCoreName(m_pConfig, szCore, _countof(szCore));
    _snwprintf_s(m_szDescription, _TRUNCATE, L"%s / %s", kbwsr_Description, szCore);
    m_ModuleInfo.cszDescription = m_szDescription;
    *ppInfo = &m_ModuleInfo;
}
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbWsrDecoderModule::Open(const KPI_MEDIAINFO *cpRequest,
                                      IKpiFile     *pFile,   //音楽データ
                                      IKpiFolder   *pFolder, //音楽データがあるフォルダ
                                      IKpiDecoder **ppDecoder)
{
    KbWsrDecoder *pDecoder = new KbWsrDecoder(m_pConfig);
    DWORD dwCount = pDecoder->Open(cpRequest, pFile, pFolder);
    if(dwCount == 0){
        *ppDecoder = NULL;
        delete pDecoder;
        return 0;
    }
    *ppDecoder = pDecoder;
    return dwCount;
}
//////////////////////////////////////////////////////////////////////////////
BOOL  WINAPI KbWsrDecoderModule::EnumConfig(IKpiConfigEnumerator* pEnumerator)
{
    return kbwsr_EnumConfig(pEnumerator);
}
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbWsrDecoderModule::ApplyConfig(const wchar_t* cszSection,//セクション名
                                             const wchar_t* cszKey,    //キー名
                                             INT64  nValue, //変更後の値(BOOL/INT の場合)
                                             double dValue, //変更後の値(FLOAT の場合)
                                             const wchar_t* cszValue)//変更後の値(文字列)
{
    return kbwsr_ApplyConfig(m_pConfig, cszSection , cszKey, nValue, dValue, cszValue);
}
/////////////////////////////////////////////////////////////////////////////
HRESULT WINAPI kpi_CreateInstance(REFIID riid, void **ppvObject, IKpiUnknown *pUnknown)
{
    *ppvObject = NULL;
    if(!IsEqualIID(riid, IID_IKpiDecoderModule)){
        return E_NOINTERFACE;
    }
    IKpiConfig* pConfig = NULL;
    kpi_CreateConfig(pUnknown, &kbwsr_GUID, NULL, &pConfig);
    IKpiDecoderModule *pDecoderModule = new KbWsrDecoderModule(pConfig);
    *ppvObject = pDecoderModule;
    pConfig->Release();
    return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
