#include <windows.h>
#include <Shlobj.h>
#include <wchar.h>
#include "kpi.h"
#include "kbbassmidi_decoder.h"
#include "kbbassmidi_config.h"

static const wchar_t SEC_GENERAL[] = L"General";
static const wchar_t KEY_SAMPLERATE[] = L"SampleRate";
static const int SAMPLERATE_DEFAULT = 44100;
static const wchar_t KEY_SOUNDFONT_PATH[] = L"SoundFontPath";
static const wchar_t KEY_SOUNDFONT_SELECT[] = L"Select";

static const int     MAX_SOUNDFONT = 20;//登録可能なサウンドフォントの最大数
static const wchar_t SZ_MAX_SOUNDFONT[] = L"20";

static const int     MAX_SOUNDFONT_PATH_LEN = 2048;
static const wchar_t SZ_MAX_SOUNDFONT_PATH_LEN[]= L"2048";

static const wchar_t SZ_SOUNDFONT_PATH_FILTER[] = L"Sound Font(sf2/sf3/sfz)\t*.sf2;*.sf3;*.sfz";
static const wchar_t SZ_SOUNDFONT_PATH_HELP[] = 
    L"サウンドフォントのパスを指定します。\r\n"
    L"| で区切ることで複数のサウンドフォントを指定することが出来ます。\r\n"
    L"複数指定で2つ目以降をファイル名だけで指定すると1つ前と同じフォルダから検索します。\r\n"
    L"(C:\\SoundFont\\foo.sf2|bar.sf2 は C:\\SoundFont\\foo.sf2|C:\\SoundFont\\bar.sf2 と同じ)\r\n"
    L"\r\n"
    L"複数指定で音色が被る場合は先に記述した方が優先されます。\r\n"
    L"\r\n"
    L"良く使うサウンドフォントのパスを SoundFontXX に登録することが出来ます。\r\n"
    L"";

extern HINSTANCE g_hKpi;
static void GetKeySoundFont(wchar_t *pszKey, int size, int nNum)
{
    if(nNum > 0){
        _snwprintf_s(pszKey, size, _TRUNCATE, L"SoundFont%02d", nNum);
    }
    else{
        pszKey[0] = 0;
    }
}
//////////////////////////////////////////////////////////////////////////////
BOOL __fastcall kbbassmidi_EnumConfig(IKpiConfig *pConfig, IKpiConfigEnumerator *pEnumerator)
{
    static const KPI_CFG_SECTION sec[] = {
        {SEC_GENERAL, NULL, L"kbbassmidi.kpi に関する一般的な設定です。"},
        {NULL, NULL, NULL}
    };
    KPI_CFG_KEY key[] = {
        {KPI_CFG_TYPE_INT, SEC_GENERAL, KEY_SAMPLERATE, L"再生周波数",
            L"44100", NULL, NULL, //default/min/max
            L"44100\t48000\t88200\t96000\t176400\t192000\t-44100\t-48000\t-88200\t-96000\t-176400\t-192000", NULL, //list/listdesc
            L"本体からの要求が 0 のときの再生周波数\r\n"
            L"負の値を指定すると本体からの要求を無視します。\r\n"
            L""
        }, //help
        {KPI_CFG_TYPE_FILE, SEC_GENERAL, KEY_SOUNDFONT_PATH, L"サウンドフォント",
            L"", SZ_SOUNDFONT_PATH_FILTER, SZ_MAX_SOUNDFONT_PATH_LEN, //default/min/max
            NULL, //list
            NULL, //listdesc
            SZ_SOUNDFONT_PATH_HELP
        }, //help
        {KPI_CFG_TYPE_INT, SEC_GENERAL, KEY_SOUNDFONT_SELECT, L"サウンドフォントの選択",
            L"0", L"0", SZ_MAX_SOUNDFONT, //default/min/max
            NULL, //list
            NULL, //listdesc
            L"0 以外を指定するとサウンドフォントを SoundFontXX で指定するパスに設定します。\r\n"
            L"(XX が指定する番号)\r\n"
            L"適用後、本設定は 0 に戻ります。\r\n"
            L""
        }, //help

        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
    };
    for(int i = 0; sec[i].cszSection; i++){
        pEnumerator->EnumSection(&sec[i]);
    }
    for(int i = 0; key[i].cszSection; i++){
        pEnumerator->EnumKey(&key[i]);
    }
    KPI_CFG_KEY key_soundfont = {
        KPI_CFG_TYPE_FILE, SEC_GENERAL, KEY_SOUNDFONT_PATH, NULL,
            L"", SZ_SOUNDFONT_PATH_FILTER, SZ_MAX_SOUNDFONT_PATH_LEN, //default/min/max
            NULL, //list
            NULL, //listdesc
            SZ_SOUNDFONT_PATH_HELP,//L"サウンドフォントのパスを指定します。\r\n"
            //L"" //help
    };
    wchar_t szKeySoundFont[128];
    int i; 
    for(i = 1; i <= MAX_SOUNDFONT; i++){
        GetKeySoundFont(szKeySoundFont, _countof(szKeySoundFont), i);
        key_soundfont.cszKey = szKeySoundFont;
        pEnumerator->EnumKey(&key_soundfont);
    }
    return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
DWORD __fastcall kbbassmidi_ApplyConfig(IKpiConfig *pConfig,
                              const wchar_t *cszSection, //セクション名
                              const wchar_t *cszKey, //キー名
                              INT64  nValue, //変更後の値(BOOL/INT の場合)
                              double dValue, //変更後の値(FLOAT の場合)
                              const wchar_t *cszValue)//変更後の値(文字列)
{
    if(wcscmp(cszSection, SEC_GENERAL) == 0){
        pConfig->SetStr(cszSection, cszKey, cszValue);
        if(wcscmp(cszKey, KEY_SAMPLERATE) == 0){//再生周波数
            return KPI_CFGRET_RELOAD_DATA;
        }
        if(wcscmp(cszKey, KEY_SOUNDFONT_PATH) == 0){//サウンドフォントのパス
            return KPI_CFGRET_RELOAD_KPI;
        }
        if(wcscmp(cszKey, KEY_SOUNDFONT_SELECT) == 0){//サウンドフォントの選択
        //最後に KEY_SOUNDFONT_PATH を設定する
            return KPI_CFGRET_OK;
        }
        if(cszKey[0] == 0){//サウンドフォントの選択が 0 以外ならサウンドフォントのパスを更新
            int nSelect = pConfig->GetInt(SEC_GENERAL, KEY_SOUNDFONT_SELECT, 0);
            if(nSelect == 0){//何もしない
                return KPI_CFGRET_OK;
            }
            pConfig->SetInt(SEC_GENERAL, KEY_SOUNDFONT_SELECT, 0);//0 に戻す
            wchar_t szKey[128];
            wchar_t szPath[MAX_PATH];
            GetKeySoundFont(szKey, _countof(szKey), nSelect);
            if(szKey[0]){
                pConfig->GetStr(SEC_GENERAL, szKey, szPath, sizeof(szPath), L"");
                if(szPath[0]){
                    pConfig->SetStr(SEC_GENERAL, KEY_SOUNDFONT_PATH, szPath);
                    return KPI_CFGRET_RELOAD_KPI;
                }
            }
        }
        return KPI_CFGRET_OK;
    }
    return KPI_CFGRET_OK;
}
//////////////////////////////////////////////////////////////////////////////
void __fastcall kbbassmidi_GetSettings(IKpiConfig *pConfig, kbbassmidi_Settings *pSettings)
{
    pSettings->nSampleRate = pConfig->GetInt(SEC_GENERAL, KEY_SAMPLERATE, SAMPLERATE_DEFAULT);
    switch(pSettings->nSampleRate){
        case 44100: case 48000: case 88200: case 96000: case 176400: case 192000:
        case -44100: case -48000: case -88200: case -96000: case -176400: case -192000: break;
        default: pSettings->nSampleRate = SAMPLERATE_DEFAULT; break;
    }
    pConfig->GetStr(SEC_GENERAL, KEY_SOUNDFONT_PATH, pSettings->szSoundFont, sizeof(pSettings->szSoundFont), L"");
}
//////////////////////////////////////////////////////////////////////////////
