#include "OrganyaPlayer.h"
#include "Sound.h"
#include "Organya.h"
#pragma comment(lib,"Winmm.lib")
const wchar_t* gDataPath = L"./data";
float g_orgVolume = 1;
float g_orgFade = 1;
bool OrganyaPlayer::Init()
{
    bool res = InitDirectSound();
    if (!res)
        return false;
    return true;
}

void OrganyaPlayer::Quit()
{
    EndOrganya();
    EndDirectSound();
}

float OrganyaPlayer::GetMusicVolume()
{
    return g_orgVolume;
}

void OrganyaPlayer::SetMusicVolume(float vol)
{
    g_orgVolume = vol;
    //ChangeOrganyaVolume((int)(musicVolume * 100));
}

void OrganyaPlayer::StopMusic()
{
    StopOrganyaMusic();
    pause = true;
    RMU_Pos = GetOrganyaPosition();
    RMU_Music = currentMusic;
}

void OrganyaPlayer::FadeOutMusic(float fadeOutSecond)
{
    //SetOrganyaFadeout();
    fadeInOut = 2;
    fade_counter = 0;
    fade_counter_max = fadeOutSecond * 60;
    pause = true;
    //RMU_Pos = GetOrganyaPosition();
    RMU_Music = currentMusic;
    FadeCounterStep();
}

void OrganyaPlayer::ChangeMusic(std::wstring musicName, float fadeInSecond)
{
    fadeInOut = 1;
    fade_counter = 0;
    fade_counter_max = fadeInSecond * 60;
    FadeCounterStep();
    if (musicName == currentMusic)
    {
        if (pause)
        {
            PlayOrganyaMusic();
            pause = false;
        }
        return;
    }
    //记录最后播放音乐的信息
    RMU_Pos = GetOrganyaPosition();
    RMU_Music = currentMusic;
    StopOrganyaMusic();

    //播放音乐
    pause = false;
    currentMusic = musicName;
    wchar_t wbuff[MAX_PATH];
    swprintf_s(wbuff, L"./data/org/%s.org", currentMusic.c_str());
    LoadOrganya(wbuff);
    SetOrganyaPosition(0);
    PlayOrganyaMusic();
}

void OrganyaPlayer::ResumeMusic(float fadeInSecond)
{
    fadeInOut = 1;
    fade_counter = 0;
    fade_counter_max = fadeInSecond * 60;
    FadeCounterStep();
    if (pause)
    {
        PlayOrganyaMusic();
        pause = false;
        return;
    }
    //播放最后一次切换的音乐
    pause = false;
    currentMusic = RMU_Music;
    wchar_t wbuff[MAX_PATH];
    swprintf_s(wbuff, L"./data/org/%s.org", currentMusic.c_str());
    StopOrganyaMusic();
    LoadOrganya(wbuff);
    SetOrganyaPosition(RMU_Pos);
    PlayOrganyaMusic();
}

bool OrganyaPlayer::IsPlaying()
{
    return !pause;
}

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

void OrganyaPlayer::FadeCounterStep()
{
    if (fadeInOut == 1)
    {
        //FadeIn
        if (fade_counter_max)
            g_orgFade = fade_counter / fade_counter_max;
        else
        {
            g_orgFade = 1;
            fadeInOut = 0;
        }
    }
    else if(fadeInOut == 2)
    {
        //FadeOut
        if (fade_counter_max)
            g_orgFade = (fade_counter_max - fade_counter) / fade_counter_max;
        else
        {
            g_orgFade = 0;
            fadeInOut = 0;
        }
        RMU_Pos = GetOrganyaPosition();
    }
    if (fade_counter == fade_counter_max)
    {
        fadeInOut = 0;
        if(fadeInOut == 2)
            StopMusic();
    }
    fade_counter++;
}

void OrganyaPlayer::FreezeMusic()
{
    if (!freeze)
    {
        freeze = true;
        freeze_Pos = GetOrganyaPosition();
        StopOrganyaMusic();
    }
}

void OrganyaPlayer::ActivateMusic()
{
    if (freeze)
    {
        if (!pm_freeze)
        {
            SetOrganyaPosition(freeze_Pos);
            PlayOrganyaMusic();
        }
        freeze = false;
    }
}

void OrganyaPlayer::PauseMenuFreezeMusic()
{
    if (!pm_freeze)
    {
        pm_freeze = true;
        pm_freeze_Pos = GetOrganyaPosition();
        StopOrganyaMusic();
    }
}

void OrganyaPlayer::PauseMenuActivateMusic()
{
    if (pm_freeze)
    {
        if (!freeze)
        {
            SetOrganyaPosition(pm_freeze_Pos);
            PlayOrganyaMusic();
        }
        pm_freeze = false;
    }
}

void MyLoadWav(const wchar_t* filename, std::vector<BYTE>* filebuff, WAVEFORMATEX* pWfmtx)
{
    HMMIO hwav = nullptr;
    MMCKINFO parent, child;
    WAVEFORMATEX& wfmtx = *pWfmtx;
    int sound_id = -1;
    BYTE* snd_buffer = nullptr;
    BYTE* audio_ptr_1 = nullptr;
    BYTE* audio_ptr_2 = nullptr;
    DWORD audio_length_1 = 0;
    DWORD audio_length_2 = 0;
    ZeroMemory(&parent, sizeof(parent));
    child = parent;

    hwav = mmioOpenW((wchar_t*)filename, NULL, MMIO_READ | MMIO_ALLOCBUF);
    if (!hwav)
    {
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"加载鼓%s失败", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    //开始解码
    parent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
    if (mmioDescend(hwav, &parent, NULL, MMIO_FINDRIFF))
    {
        mmioClose(hwav, 0);
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"%s非WAV文件", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    //解码WAV
    child.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if (mmioDescend(hwav, &child, &parent, 0))
    {
        mmioClose(hwav, 0);
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"%sWAV文件格式错误", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    if (mmioRead(hwav, (char*)&wfmtx, sizeof(wfmtx)) != sizeof(wfmtx))
    {
        mmioClose(hwav, 0);
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"%sWAV文件没有波形格式数据", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    //确保是PCM格式
    if (wfmtx.wFormatTag != WAVE_FORMAT_PCM)
    {
        mmioClose(hwav, 0);
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"%sWAV文件不是PCM格式", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    if (mmioAscend(hwav, &child, 0))
    {
        mmioClose(hwav, 0);
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"%sWAV文件不能Ascend", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    child.ckid = mmioFOURCC('d', 'a', 't', 'a');
    if (mmioDescend(hwav, &child, &parent, MMIO_FINDCHUNK))
    {
        mmioClose(hwav, 0);
        wchar_t err[MAX_PATH];
        swprintf_s(err, L"%sWAV文件没有波形数据", filename);
        MessageBox(nullptr, err, L"Organya模块错误", MB_OK | MB_ICONWARNING);
        return;
    }
    filebuff->resize(child.cksize);
    
    mmioRead(hwav, (char*)filebuff->data(), child.cksize);
    mmioClose(hwav, 0);
}