#include "MusicPlayer.h"

MusicPlayer* g_musicPlayer = nullptr;

MusicPlayer::MusicPlayer()
{
    g_musicPlayer = this;
}

MusicPlayer::~MusicPlayer()
{
    for (auto& p : loadedMusic)
    {
        auto& m = p.second;
        Mix_FreeMusic(m);
    }
    g_musicPlayer = nullptr;
}

void MusicPlayer::Init()
{
}

float MusicPlayer::GetMusicVolume()
{
    return musicVolume;
}

void MusicPlayer::SetMusicVolume(float vol)
{
    musicVolume = vol;
    Mix_VolumeMusic((int)(musicVolume * MIX_MAX_VOLUME));
}

void MusicPlayer::StopMusic()
{
    Mix_PauseMusic();
    setFadeOut = true;
    RMU_Pos = Mix_GetMusicPosition(GetMusic(currentMusic));
    RMU_Music = currentMusic;
    RMU_Music_inLoop = currentMusic_inLoop;
}

void MusicPlayer::FadeOutMusic(float fadeOutSecond)
{
    Mix_FadeOutMusic((int)(fadeOutSecond * 1000));
    setFadeOut = true;
    RMU_Pos = Mix_GetMusicPosition(GetMusic(currentMusic));
    RMU_Music = currentMusic;
    RMU_Music_inLoop = currentMusic_inLoop;
}

void MusicFinished()
{
    if (g_musicPlayer->setFadeOut)
        return;
    auto mus = g_musicPlayer->GetMusicLoop(g_musicPlayer->currentMusic);
    if (mus)
        g_musicPlayer->currentMusic_inLoop = true;
    else
        mus = g_musicPlayer->GetMusic(g_musicPlayer->currentMusic);
    Mix_PlayMusic(mus, -1);
    Mix_VolumeMusic((int)(g_musicPlayer->musicVolume * MIX_MAX_VOLUME));
}

void MusicPlayer::ChangeMusic(std::wstring musicName, float fadeInSecond)
{
    setFadeOut = false;
    if (musicName == currentMusic)
    {
        if (Mix_PausedMusic())
            Mix_ResumeMusic();
        else if (!Mix_PlayingMusic())
        {
            if (fadeInSecond > 0)
                Mix_FadeInMusic(GetMusic(currentMusic), 1, (int)(fadeInSecond * 1000));
            else
                Mix_PlayMusic(GetMusic(currentMusic), 1);
        } 
        return;
    }
   //记录最后播放音乐的信息
    RMU_Pos = Mix_GetMusicPosition(GetMusic(currentMusic));
    RMU_Music = currentMusic;
    RMU_Music_inLoop = currentMusic_inLoop;
    //播放音乐
    currentMusic = musicName;
    currentMusic_inLoop = false;
    if (fadeInSecond > 0)
        Mix_FadeInMusic(GetMusic(currentMusic), 1, (int)(fadeInSecond * 1000));
    else
        Mix_PlayMusic(GetMusic(currentMusic), 1);
    Mix_VolumeMusic((int)(musicVolume * MIX_MAX_VOLUME));
    Mix_HookMusicFinished(MusicFinished);
}

void MusicPlayer::ResumeMusic(float fadeInSecond)
{
    setFadeOut = false;
    if (Mix_PausedMusic())
    {
        Mix_ResumeMusic();
        return;
    }
    //播放最后一次切换的音乐
    currentMusic = RMU_Music;
    currentMusic_inLoop = RMU_Music_inLoop;
    if (currentMusic_inLoop)
    {
        //播放循环部分
        if (fadeInSecond > 0)
            Mix_FadeInMusic(GetMusicLoop(currentMusic), -1, (int)(fadeInSecond * 1000));
        else
            Mix_PlayMusic(GetMusicLoop(currentMusic), -1);
    }
    else
    {
        //播放循环部分
        if (fadeInSecond > 0)
            Mix_FadeInMusic(GetMusic(currentMusic), 1, (int)(fadeInSecond * 1000));
        else
            Mix_PlayMusic(GetMusic(currentMusic), 1);
    }
    Mix_VolumeMusic((int)(musicVolume * MIX_MAX_VOLUME));
    Mix_SetMusicPosition(RMU_Pos);
}

bool MusicPlayer::IsPlaying()
{
    return Mix_PlayingMusic();
}

const wchar_t* MusicPlayer::GetLastPlayMusic()
{
    return currentMusic.c_str();
}

Mix_Music* MusicPlayer::GetMusic(std::wstring musicName)
{
    auto iter = loadedMusic.find(musicName);
    if (iter == loadedMusic.end())
    {
        wchar_t wbuff[MAX_PATH];
        swprintf_s(wbuff, L"./data/music/%s.ogg", musicName.c_str());
        std::vector<char> utf8;
        UTF16ToUTF8(wbuff, &utf8);
        auto m = Mix_LoadMUS(utf8.data());
        if (!m)
        {
            swprintf_s(wbuff, L"./data/music/%s.flac", musicName.c_str());
            std::vector<char> utf8;
            UTF16ToUTF8(wbuff, &utf8);
            m = Mix_LoadMUS(utf8.data());
        }
        loadedMusic.insert(std::make_pair(musicName, m));
        return m;
    }
    else
        return iter->second;
}

Mix_Music* MusicPlayer::GetMusicLoop(std::wstring musicName)
{
    wchar_t wbuff[MAX_PATH];
    swprintf_s(wbuff, L"%s_loop", musicName.c_str());
    auto iter = loadedMusic.find(wbuff);
    if(iter == loadedMusic.end())
    {
        wchar_t wbuff2[MAX_PATH];
        //尝试加载loop部分
        //确认文件是否存在
        FILE* fp = nullptr;
        Mix_Music* m = nullptr;
        swprintf_s(wbuff2, L"./data/music/%s_loop.ogg", musicName.c_str());
        _wfopen_s(&fp, wbuff2, L"rb");
        if (!fp)
        {
            //如果不存在
            //查看flac是否存在
            swprintf_s(wbuff2, L"./data/music/%s_loop.flac", musicName.c_str());
            _wfopen_s(&fp, wbuff2, L"rb");
            if (!fp)
            {
                return nullptr;
            }
            else
            {
                //文件存在
                fclose(fp);
                //加载音乐文件
                std::vector<char> utf8;
                UTF16ToUTF8(wbuff2, &utf8);
                m = Mix_LoadMUS(utf8.data());
            }
        }
        else
        {
            //文件存在
            fclose(fp);
            //加载音乐文件
            std::vector<char> utf8;
            UTF16ToUTF8(wbuff2, &utf8);
            m = Mix_LoadMUS(utf8.data());
        }
        loadedMusic.insert(std::make_pair(wbuff, m));
        return m;
    }
    else
        return iter->second;
}
