#include <windows.h>
#include <wchar.h>
#include "kbmpg123_config.h"
#include "kbmpg123_decoder.h"

static const wchar_t SEC_GENERAL[] = L"General";
#ifdef _WIN64
static const wchar_t KEY_DECODER[] = L"Decoder_x64";
#else
static const wchar_t KEY_DECODER[] = L"Decoder_x86";
#endif

//////////////////////////////////////////////////////////////////////////////
BOOL __fastcall kbmpg123_EnumConfig(IKpiConfig *pConfig, IKpiConfigEnumerator *pEnumerator)
{
    static const KPI_CFG_SECTION sec[] = {
        {SEC_GENERAL, NULL, L"mpg123.kpi に関する一般的な設定です。"},
        {NULL, NULL, NULL}
    };
    static KPI_CFG_KEY key[] = {
        {KPI_CFG_TYPE_STR, SEC_GENERAL, KEY_DECODER, L"デコーダ",
            NULL, NULL, NULL, //default/min/max
            NULL, NULL, //list/listdesc
            NULL //help
        },
        {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
    };
    wchar_t help[1024];
    wchar_t decoder_list[512];
    decoder_list[0] = 0;
    const char** decoders = mpg123_decoders();
    for (int i = 0; decoders[i]; i++) {
        wchar_t decoder_name[32];
        MultiByteToWideChar(CP_ACP, 0, decoders[i], -1, decoder_name, _countof(decoder_name));
        decoder_name[_countof(decoder_name) - 1] = 0;
        wcsncat_s(decoder_list, decoder_name, _TRUNCATE);
        wcsncat_s(decoder_list, L"\r\n", _TRUNCATE);
    }
    _snwprintf_s(help, _TRUNCATE,
        L"デコーダを選択します。速度と音質に影響します。\r\n"
        L"音質はどれも大差ない筈ですが、お好みで選択して下さい。\r\n"
        L"良く分からない場合は\r\n"
        L"\r\n"
        L"64bit版では AVX、x86-x64(AVX を選択出来ない場合)のいずれか\r\n"
        L"32bit版では SSE、generic(SSE を選択出来ない場合)のいずれか\r\n"
        L"\r\n"
        L"を選択すれば良いでしょう。\r\n"
        L"\r\n"
        L"%s"
        L"\r\n"
        L"のうち、動作中の CPU が対応するものを使用することが出来ます。\r\n"
        L"64bit版と32bit版で選択肢が異なります。\r\n"
        L"", decoder_list);
    key[0].cszHelp = help;

    const char** supported_decoders = mpg123_supported_decoders();
    wchar_t supported_decoder_list[256];
    supported_decoder_list[0] = 0;
    for (int i = 0; supported_decoders[i]; i++) {
        wchar_t decoder_name[32];
        MultiByteToWideChar(CP_ACP, 0, supported_decoders[i], -1, decoder_name, _countof(decoder_name));
        decoder_name[_countof(decoder_name) - 1] = 0;
        if (supported_decoder_list[0]) {
            wcsncat_s(supported_decoder_list, L"\t", _TRUNCATE);
        }
        wcsncat_s(supported_decoder_list, decoder_name, _TRUNCATE);
    }
    wchar_t decoder_default[32];
    KbMpg123Decoder::GetDefaultDecoder(decoder_default, _countof(decoder_default));
    key[0].cszDefault = decoder_default;
    key[0].cszList = supported_decoder_list;

    for (int i = 0; sec[i].cszSection; i++) {
        pEnumerator->EnumSection(&sec[i]);
    }
    for (int i = 0; key[i].cszSection; i++) {
        pEnumerator->EnumKey(&key[i]);
    }
    return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
DWORD __fastcall kbmpg123_ApplyConfig(IKpiConfig *pConfig,
                              const wchar_t *cszSection, //セクション名
                              const wchar_t *cszKey, //キー名
                              INT64  nValue, //変更後の値(BOOL/INT の場合)
                              double dValue, //変更後の値(FLOAT の場合)
                              const wchar_t *cszValue)//変更後の値(文字列)
{
    if (_wcsicmp(cszSection, SEC_GENERAL) == 0 &&
        _wcsicmp(cszKey, KEY_DECODER) == 0) {
        pConfig->SetStr(cszSection, cszKey, cszValue);

        return KPI_CFGRET_RELOAD_DATA;
    }
    return KPI_CFGRET_OK;
}
//////////////////////////////////////////////////////////////////////////////
void __fastcall kbmpg123_GetSettings(IKpiConfig *pConfig, kbmpg123_Settings *pSettings)
{
    pConfig->GetStr(SEC_GENERAL, KEY_DECODER, pSettings->szDecoder, 
                    sizeof(pSettings->szDecoder), L"");
}
//////////////////////////////////////////////////////////////////////////////
