#include <windows.h>
#include "kbqt_config.h"

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

#include "kbqt_module.h"
#include "kbqt_player.h"

#ifdef _DEBUG
static const DWORD kbqt_Version = 0x7FFFFFFF; //デバッグ時は優先度最大
#define KBQT_VERSION_STR L"0x7FFFFFFF(Debug)"
#else
static const DWORD kbqt_Version = 6;
#define KBQT_VERSION_STR L"0.06"
#endif
///////////////////////////////////////////////////////////////////////////////
// {ADF526EB-7750-44BE-BFD5-42DC04FCBB89}
static const GUID kbqt_GUID = 
{ 0xadf526eb, 0x7750, 0x44be, { 0xbf, 0xd5, 0x42, 0xdc, 0x4, 0xfc, 0xbb, 0x89 } };

static const wchar_t kbqt_Description[] = L"QuickTime Movie Player v" KBQT_VERSION_STR;
static const wchar_t kbqt_Copyright[] = L"Copyright(C) 2016-2021 Kobarin";
static const DWORD kbqt_MultipleInstance = KPI_MULTINST_INFINITE;
static const DWORD kbqt_SupportTagInfo = 0;
static const DWORD kbqt_SupportConfig = 1;
//static const wchar_t kbqt_SupportExts[] = L".mov/.qt/.mid";
static const wchar_t kbqt_MultiSongExts[] = L"";
static void* kbqt_Reserved1 = NULL;
static void* kbqt_Reserved2 = NULL;

///////////////////////////////////////////////////////////////////////////////
KbQtPlayerModule::KbQtPlayerModule(IKpiConfig *pConfig)
    :m_ModuleInfo{
        sizeof(KPI_PLAYER_MODULEINFO),
        KPI_PLAYER_MODULE_VERSION,
        kbqt_Version,
        kbqt_MultipleInstance,
        kbqt_GUID,
        kbqt_Description,
        kbqt_Copyright,
        NULL, //kbqt_SupportExts,
        kbqt_MultiSongExts,
        kbqt_Reserved1,
        kbqt_Reserved2,
        kbqt_SupportTagInfo,
        kbqt_SupportConfig,
        0,0,0,0}
{
    //KbQtPlayer::InitQt();//時間がかかるので必要になってから呼ぶようにする
    m_pConfig = pConfig;
    pConfig->AddRef();
    m_ModuleInfo.cszSupportExts = kbqt_GetSupportExts(pConfig);
}
///////////////////////////////////////////////////////////////////////////////
KbQtPlayerModule::~KbQtPlayerModule(void)
{
    KbQtPlayer::DeinitQt();
    m_pConfig->Release();
}
///////////////////////////////////////////////////////////////////////////////
void WINAPI KbQtPlayerModule::GetModuleInfo(const KPI_PLAYER_MODULEINFO **ppInfo)
{
    *ppInfo = &m_ModuleInfo;
}
///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbQtPlayerModule::Open(const KPI_MEDIAINFO *cpRequest,
                                    IKpiFile   *pFile,
                                    IKpiFolder *pFolder,
                                    IKpiPlayer **ppPlayer)
{
    KbQtPlayer *pPlayer = new KbQtPlayer;
    DWORD dwRet = pPlayer->Open(pFile, pFolder);
    if(dwRet){
        *ppPlayer = pPlayer;
        return 1;
    }
    else{
        pPlayer->Release();
        *ppPlayer = NULL;
        return 0;
    }
}
///////////////////////////////////////////////////////////////////////////////
BOOL  WINAPI KbQtPlayerModule::EnumConfig(IKpiConfigEnumerator *pEnumerator)
{
    return kbqt_EnumConfig(m_pConfig, pEnumerator);   
}
//////////////////////////////////////////////////////////////////////////////
DWORD WINAPI KbQtPlayerModule::ApplyConfig(const wchar_t *cszSection, //セクション名
                                           const wchar_t *cszKey,     //キー名
                                           INT64 nValue,
                                           double dValue,
                                           const wchar_t *cszValue)     
{
    return kbqt_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, &kbqt_GUID, NULL, &pConfig);
    IKpiPlayerModule *pPlayerModule = new KbQtPlayerModule(pConfig);
    *ppvObject = pPlayerModule;
    pConfig->Release();//KbQtPlayerModule 内で AddRef しているので必ず必要
    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: {
        DisableThreadLibraryCalls(hModule);
#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
        break;
    }
    case DLL_PROCESS_DETACH: {
        break;
    }
    }
    return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
