#include "stdafx.h"
#include <windows.h>
#include <wchar.h>
#include "kbnsfplug_module.h"
#include "kbnsfplug_decoder.h"
#include "kbnsfplug_config.h"

//////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
static const DWORD kbnsfplug_Version = 0x7FFFFFFF;//デバッグ時は優先度最大
#define KBNSFPLUG_VERSION_STR L"0x7FFFFFFF(Debug)"
#else
static const DWORD kbnsfplug_Version = 10;
#define KBNSFPLUG_VERSION_STR L"0.10"
#endif

static const wchar_t kbnsfplug_Description[] = L"NSFplug Decoder v" KBNSFPLUG_VERSION_STR " based on NSFPlay/NSFplug v2.7 beta";
static const wchar_t kbnsfplug_Copyright[] =   L"kbnsfpllug.kpi Copyright(C) 2024 Kobarin\n"
                                               L"NSFplug v2.7 beta Copyright(C) Brad Smith\n"
                                               L"NSFplug(2006/05/05) Copyright(C) Mitsutaka Okazaki";

// {26FA305F-7635-46F2-ABEF-6E14FA5D012C}
static const GUID kbnsfplug_GUID = 
{ 0x26fa305f, 0x7635, 0x46f2, { 0xab, 0xef, 0x6e, 0x14, 0xfa, 0x5d, 0x1, 0x2c } };

static const DWORD kbnsfplug_MultipleInstance = KPI_MULTINST_INFINITE;
static const wchar_t kbnsfplug_SupportExts[] = L".nsf/.nsfe";
static const wchar_t kbnsfplug_MultiSongExts[] = L".nsf/.nsfe";
static const DWORD kbnsfplug_SupportTagInfo = KPI_DECODER_MODULEINFO::TAG_EXTRA;
static const DWORD kbnsfplug_SupportConfig = 1;
static void* kbnsfplug_Reserved1 = NULL;
static void* kbnsfplug_Reserved2 = NULL;

extern HINSTANCE g_hKpi;
//////////////////////////////////////////////////////////////////////////////
KbNsfplugDecoderModule::KbNsfplugDecoderModule(IKpiConfig *pConfig)
    :m_ModuleInfo{
        sizeof(KPI_DECODER_MODULEINFO), //cb(=sizeof(KPI_DECODER_MODULEINFO))
        KPI_DECODER_MODULE_VERSION,     //dwModuleVersion(=KPI_DECODER_MODULE_VERSION)
        kbnsfplug_Version,
        kbnsfplug_MultipleInstance,
        kbnsfplug_GUID,
        kbnsfplug_Description,
        kbnsfplug_Copyright,
        kbnsfplug_SupportExts,
        kbnsfplug_MultiSongExts,
        kbnsfplug_Reserved1,
        kbnsfplug_Reserved2,
        kbnsfplug_SupportTagInfo,
        kbnsfplug_SupportConfig,
        0, 0, 0, 0                   //reserved
     }
{
    pConfig->AddRef();
    m_pConfig = pConfig;
    //KbNsfplugDecoder::Initialize(pConfig);//必要になったらDecoder内部で呼ぶのでここでは呼ばない
}
//////////////////////////////////////////////////////////////////////////////
KbNsfplugDecoderModule::~KbNsfplugDecoderModule(void)
{
    KbNsfplugDecoder::UnInitialize(m_pConfig);
    m_pConfig->Release();
}
//////////////////////////////////////////////////////////////////////////////
void  WINAPI KbNsfplugDecoderModule::GetModuleInfo(const KPI_DECODER_MODULEINFO **ppInfo)
{
    *ppInfo = &m_ModuleInfo;
}
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbNsfplugDecoderModule::Open(const KPI_MEDIAINFO *cpRequest,
                                      IKpiFile     *pFile,   //音楽データ
                                      IKpiFolder   *pFolder, //音楽データがあるフォルダ
                                      IKpiDecoder **ppDecoder)
{
    KbNsfplugDecoder *pDecoder = new KbNsfplugDecoder(m_pConfig);
    DWORD dwCount = pDecoder->Open(cpRequest, pFile, pFolder, m_pConfig);
    if(dwCount == 0){
        *ppDecoder = NULL;
        delete pDecoder;
        return 0;
    }
    *ppDecoder = pDecoder;
    return dwCount;
}
/////////////////////////////////////////////////////////////////////////////
BOOL  WINAPI KbNsfplugDecoderModule::EnumConfig(IKpiConfigEnumerator *pEnumerator)
{
    return kbnsfplug_EnumConfig(pEnumerator);
}
/////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbNsfplugDecoderModule::ApplyConfig(const wchar_t *cszSection,//セクション名
                             const wchar_t *cszKey,    //キー名
                             INT64  nValue, //変更後の値(BOOL/INT の場合)
                             double dValue, //変更後の値(FLOAT の場合)
                             const wchar_t *cszValue)////変更後の値(文字列)
{
    return kbnsfplug_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;
    kpi_CreateConfig(pUnknown, &kbnsfplug_GUID, NULL, &pConfig);
    IKpiDecoderModule *pDecoderModule = new KbNsfplugDecoderModule(pConfig);
    *ppvObject = pDecoderModule;
    pConfig->Release();
    return S_OK;
}
/////////////////////////////////////////////////////////////////////////////

