#include <windows.h>

#ifdef _DEBUG
#define LEAK_CHECK //メモリリーク検出（しない場合はコメントアウト）
#endif
#ifdef LEAK_CHECK
#include <crtdbg.h>
#endif

#include "kbflac_module.h"
#include "kbflac_decoder.h"

#ifdef _DEBUG
static const DWORD kbflac_Version = 0x7FFFFFFF;//デバッグ時は優先度最大
#define KBFLAC_VERSION_STR "0x7FFFFFFF(Debug)"
#else
static const DWORD kbflac_Version = 30;
#define KBFLAC_VERSION_STR "0.30"
#endif

static const wchar_t kbflac_Description[] = L"FLAC Decoder v" KBFLAC_VERSION_STR " based on libFLAC 1.4.3/libogg 1.3.5";
static const wchar_t kbflac_Copyright[] =   L"kbflac.kpi Copyright (C) 2002-2024 Kobarin\n"
                                            L"libFLAC Copyright (C) 2001-2023 Josh Coalson, Xiph.Org\n"
                                            L"libogg Copyright (C) 2000-2021 Xiph.Org";

static const GUID kbflac_GUID = 
{ 0x3e90d812, 0xcd7b, 0x4689, { 0x9a, 0x59, 0x44, 0x34, 0xc5, 0x84, 0x77, 0x55 } };

static const DWORD kbflac_MultipleInstance = KPI_MULTINST_INFINITE;//同時に何個でも作成可能
                                            //KPI_MULTINST_ZERO;  //常に別プロセス起動
                                            //KPI_MULTINST_ONE;   //2個目以降は別プロセス起動
                                            //KPI_MULTINST_UNIQUE;//プロセスをまたいでも１つまで
                                            //KPI_MULTINST_ZERO + N;//(N+1)個目以降は別プロセス起動
                                            //↑どれか１つを選択
static const wchar_t kbflac_SupportExts[] = L".flac";
static const wchar_t kbflac_MultiSongExts[] = L"";
static const DWORD kbflac_SupportTagInfo = KPI_DECODER_MODULEINFO::TAG_TITLE | //未対応ならコメントアウト
                                           KPI_DECODER_MODULEINFO::TAG_EXTRA | //未対応ならコメントアウト
                                           0;
static const DWORD kbflac_SupportConfig = 0;
static void* kbflac_Reserved1 = NULL;
static void* kbflac_Reserved2 = NULL;

//////////////////////////////////////////////////////////////////////////////
KbFlacDecoderModule::KbFlacDecoderModule(void)
    :m_ModuleInfo{
        sizeof(KPI_DECODER_MODULEINFO), //cb(=sizeof(KPI_DECODER_MODULEINFO))
        KPI_DECODER_MODULE_VERSION,     //dwModuleVersion(=KPI_DECODER_MODULE_VERSION)
        kbflac_Version,
        kbflac_MultipleInstance,
        kbflac_GUID,
        kbflac_Description,
        kbflac_Copyright,
        kbflac_SupportExts,
        kbflac_MultiSongExts,
        kbflac_Reserved1,
        kbflac_Reserved2,
        kbflac_SupportTagInfo,
        kbflac_SupportConfig,
        0, 0, 0, 0                      //reserved
     }
{
}
//////////////////////////////////////////////////////////////////////////////
KbFlacDecoderModule::~KbFlacDecoderModule(void)
{
}
//////////////////////////////////////////////////////////////////////////////
void  WINAPI KbFlacDecoderModule::GetModuleInfo(const KPI_DECODER_MODULEINFO **ppInfo)
{
    *ppInfo = &m_ModuleInfo;
}
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbFlacDecoderModule::Open(const KPI_MEDIAINFO *cpRequest,
    IKpiFile     *pFile,   //音楽データ
    IKpiFolder   *pFolder, //音楽データがあるフォルダ
    IKpiDecoder **ppDecoder)
{
    *ppDecoder = new KbFlacDecoder(pFile, pFolder);
    return 1;
}
/////////////////////////////////////////////////////////////////////////////
HRESULT WINAPI kpi_CreateInstance(REFIID riid, void **ppvObject, IKpiUnknown *pUnknown)
{
    *ppvObject = NULL;
    if(!IsEqualIID(riid, IID_IKpiDecoderModule)){
        return E_NOINTERFACE;
    }
    IKpiDecoderModule *pDecoderModule = new KbFlacDecoderModule();
    *ppvObject = pDecoderModule;
    return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
//DllMain
/////////////////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH: {
#ifdef LEAK_CHECK
        //メモリリーク検出
        int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
        //tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
        tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
        //tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF;
        _CrtSetDbgFlag(tmpDbgFlag);
#endif
        DisableThreadLibraryCalls(hModule);
        break;
    }
    case DLL_PROCESS_DETACH: {
        break;
    }
    }
    return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
