#include <windows.h>
#include <wchar.h>
#include "Header/tak_deco_lib.h"
#include "tak_deco_lib_loader.h"

static HINSTANCE g_hTak = NULL;
TAKAPI takapi;

BOOL LoadTakLib(HINSTANCE hKpi)
{
    HINSTANCE hTak = g_hTak;
    if(hTak){
        return TRUE;
    }
    //hKpi と同じフォルダにある tak_deco_lib.dll をロード
    wchar_t szDllName[MAX_PATH];
    GetModuleFileName(hKpi, szDllName, _countof(szDllName));
    wchar_t* pszPathDelimiter = wcsrchr(szDllName, L'\\');
    if (pszPathDelimiter) {
        pszPathDelimiter[1] = 0;
        wcsncat_s(szDllName, L"tak_deco_lib.dll", _TRUNCATE);
        hTak = LoadLibrary(szDllName);
    }
    if (!hTak) {
        return FALSE;
    }
    *(void**)&takapi.tak_GetLibraryVersion = GetProcAddress(hTak, "tak_GetLibraryVersion");
    //*(void**)&takapi.tak_GetWaveExtensibleSpeakerMask = GetProcAddress(hTak, "tak_GetWaveExtensibleSpeakerMask");
    *(void**)&takapi.tak_GetCodecName = GetProcAddress(hTak, "tak_GetCodecName");
    *(void**)&takapi.tak_SSD_Create_FromStream = GetProcAddress(hTak, "tak_SSD_Create_FromStream");
    *(void**)&takapi.tak_SSD_Destroy = GetProcAddress(hTak, "tak_SSD_Destroy");
    //*(void**)&takapi.tak_SSD_Valid = GetProcAddress(hTak, "tak_SSD_Valid");
    //*(void**)&takapi.tak_SSD_State = GetProcAddress(hTak, "tak_SSD_State");
    //*(void**)&takapi.tak_SSD_GetStateInfo = GetProcAddress(hTak, "tak_SSD_GetStateInfo");
    //*(void**)&takapi.tak_SSD_GetErrorString = GetProcAddress(hTak, "tak_SSD_GetErrorString");
    *(void**)&takapi.tak_SSD_GetStreamInfo = GetProcAddress(hTak, "tak_SSD_GetStreamInfo");
    //*(void**)&takapi.tak_SSD_GetStreamInfo_V22 = GetProcAddress(hTak, "tak_SSD_GetStreamInfo_V22");
    //*(void**)&takapi.tak_SSD_GetFrameSize = GetProcAddress(hTak, "tak_SSD_GetFrameSize");
    //*(void**)&takapi.tak_SSD_GetMD5 = GetProcAddress(hTak, "tak_SSD_GetMD5");
    *(void**)&takapi.tak_SSD_Seek = GetProcAddress(hTak, "tak_SSD_Seek");
    *(void**)&takapi.tak_SSD_ReadAudio = GetProcAddress(hTak, "tak_SSD_ReadAudio");
    //*(void**)&takapi.tak_SSD_GetReadPos = GetProcAddress(hTak, "tak_SSD_GetReadPos");
    //*(void**)&takapi.tak_SSD_GetCurFrameBitRate = GetProcAddress(hTak, "tak_SSD_GetCurFrameBitRate");
    *(void**)&takapi.tak_SSD_GetSimpleWaveDataDesc = GetProcAddress(hTak, "tak_SSD_GetSimpleWaveDataDesc");
    *(void**)&takapi.tak_SSD_ReadSimpleWaveData = GetProcAddress(hTak, "tak_SSD_ReadSimpleWaveData");
    *(void**)&takapi.tak_SSD_GetEncoderInfo = GetProcAddress(hTak, "tak_SSD_GetEncoderInfo");
//    *(void**)&takapi.tak_SSD_GetAPEv2Tag = GetProcAddress(hTak, "tak_SSD_GetAPEv2Tag");

    if (!takapi.tak_GetLibraryVersion ||
        //!takapi.tak_GetWaveExtensibleSpeakerMask ||
        !takapi.tak_GetCodecName ||
        !takapi.tak_SSD_Create_FromStream ||
        !takapi.tak_SSD_Destroy ||
        //!takapi.tak_SSD_Valid ||
        //!takapi.tak_SSD_State ||
        //!takapi.tak_SSD_GetStateInfo ||
        //!takapi.tak_SSD_GetErrorString ||
        !takapi.tak_SSD_GetStreamInfo ||
        //!takapi.tak_SSD_GetStreamInfo_V22 ||
        //!takapi.tak_SSD_GetFrameSize ||
        //!takapi.tak_SSD_GetMD5 ||
        !takapi.tak_SSD_Seek ||
        !takapi.tak_SSD_ReadAudio ||
        //!takapi.tak_SSD_GetReadPos ||
        //!takapi.tak_SSD_GetCurFrameBitRate ||
        !takapi.tak_SSD_GetSimpleWaveDataDesc ||
        !takapi.tak_SSD_ReadSimpleWaveData ||
        !takapi.tak_SSD_GetEncoderInfo ||
//        !takapi.tak_SSD_GetAPEv2Tag ||
        0
        ) {
        ZeroMemory(&takapi, sizeof(takapi));
        FreeLibrary(hTak);
        //g_hTak = NULL;
        return FALSE;
    }
    g_hTak = hTak;

    return TRUE;
}

void UnloadTakLib(void)
{
    if (g_hTak) {
        FreeLibrary(g_hTak);
        g_hTak = NULL;
        ZeroMemory(&takapi, sizeof(takapi));
    }
}
