#include "GameTimer.h"
#include "main.h"
void GameTimer::Init(MyDX11Renderer* pRenderer, MyView* pView)
{
    this->pRenderer = pRenderer;
    this->pView = pView;
}

void GameTimer::Draw(bool bShowPlayer2)
{
    if (!bVisiable)
        return;
    auto& tas = *GetSysTexture(L"dmgnum");
    pRenderer->SetTPenDraw(tas.pSRV);
    float offx = pView->window_w - pView->scale * 64;
    float offy = pView->scale * 16;
    if (bShowPlayer2)
    {
        //绘制在中间
        offx = (pView->window_w - 16 * pView->scale) / 2;
    }
    MyRect src, dst;
    //绘制分钟
    AddDrawNum(0, 56, offx, offy, pView->scale, minutes);
    src.Set1(64, 0, 8, 8);
    dst.Set1(offx, offy, 8 * pView->scale, 8 * pView->scale);
    pRenderer->AddRenderCopy(&src, &dst);
    //绘制秒
    AddDrawTwoNum(0, 56, offx + 5 * pView->scale, offy, pView->scale, seconds);
    src.Set1(72, 0, 8, 8);
    dst.Set1(offx + 21 * pView->scale, offy, 8 * pView->scale, 8 * pView->scale);
    pRenderer->AddRenderCopy(&src, &dst);
    //绘制1/10秒
    AddDrawOneNum(0, 56, offx + 26 * pView->scale, offy, pView->scale, units);
    //绘制时钟
    if (counter % 60 < 30)
        src.Set1(48, 0, 8, 8);
    else
        src.Set1(56, 0, 8, 8);
    dst.Set1(offx - 32 * pView->scale, offy, 8 * pView->scale, 8 * pView->scale);
    pRenderer->AddRenderCopy(&src, &dst);
    pRenderer->DrawRenderCopy();
}

void GameTimer::Step()
{
    if (bStop)
        return;
    SetUnit();
    counter++;
}

void GameTimer::Reset()
{
    counter = 0;
    bVisiable = false;
    bStop = true;
    SetUnit();
}

void GameTimer::SetVisible(bool bVisiable)
{
    this->bVisiable = bVisiable;
}

void GameTimer::Stop(bool bStop)
{
    this->bStop = bStop;
}

int GameTimer::GetCounter()
{
    return counter;
}

void GameTimer::SetCounter(int counter)
{
    this->counter = counter;
}

bool GameTimer::Save()
{
    //保存当前数值
    int counterNew = counter;
    bool bNewRecord = false;
    if (Load())
    {
        //更新记录
        if (counterNew < counter)
            bNewRecord = true;
    }
    else
    {
        bNewRecord = true;
    }
    if (bNewRecord)
    {
        counter = counterNew;
        SetUnit();
        //保存计时器数据到游戏目录下
        tinyxml2::XMLDocument xmlDoc;
        auto elem_bossrush = xmlDoc.NewElement("BossRush");
        elem_bossrush->SetAttribute("NikumaruCounter", counterNew);
        xmlDoc.InsertEndChild(elem_bossrush);
        tinyxml2::XMLPrinter xmlPrinter;
        xmlDoc.Print(&xmlPrinter);
        //压缩数据
        std::vector<BYTE> compressData;
        size_t compressData_len;
        ZLibCompressData(&compressData, &compressData_len, xmlPrinter.CStr(), xmlPrinter.CStrSize());
        //写入本地文件
        const wchar_t* filename = L"./290.sav";
        FILE* fp;
        _wfopen_s(&fp, filename, L"wb+");
        if (!fp)
        {
            wchar_t err[MAX_PATH];
            swprintf_s(err, L"保存游戏到本地目录%s失败", filename);
            MessageBoxW(hwnd, err, L"文件写入失败", MB_ICONWARNING);
            return false;
        }
        fwrite(compressData.data(), compressData_len, 1, fp);
        fclose(fp);
        return true;
    }
    return false;
}

bool GameTimer::Load()
{
    const wchar_t* filename = L"./290.sav";
    //读取计时器数据
    FILE* fp;
    _wfopen_s(&fp, filename, L"rb");
    if (!fp)
        return false;
    std::vector<BYTE> cbuff;
    fseek(fp, 0, SEEK_END);
    size_t fileLen = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    cbuff.resize(fileLen);
    fread_s(cbuff.data(), fileLen, fileLen, 1, fp);
    fclose(fp);
    std::vector<BYTE> byte_buff;
    size_t len = 0;
    ZLibUncompressData(&byte_buff, &len, cbuff.data(), fileLen);
    tinyxml2::XMLDocument xmlDoc;
    xmlDoc.Parse((const char*)byte_buff.data());
    //寻找BossRush元素
    tinyxml2::XMLElement* elem = nullptr;
    for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
    {
        if (!strcmp(pElem->Name(), "BossRush"))
        {
            elem = pElem;
            break;
        }
    }
    if (elem)
    {
        //读取BossRush元素
        counter = elem->IntAttribute("NikumaruCounter");
        SetUnit();
        return true;
    }
    return false;
}

void GameTimer::SetUnit()
{
    const int FRAMES_PER_SECOND = 60; // 游戏帧率60FPS
    const int UNITS_PER_SECOND = 10;  // 每秒分为10个单位

    int totalUnits = (counter * UNITS_PER_SECOND) / FRAMES_PER_SECOND;

    units = totalUnits % UNITS_PER_SECOND;
    int totalSeconds = totalUnits / UNITS_PER_SECOND;
    seconds = totalSeconds % 60;
    minutes = totalSeconds / 60;
}

void GameTimer::AddDrawOneNum(float srcX, float srcY, float dstX, float dstY, float scale, int num)
{
    MyRect src, dst;
    src.Set1(srcX + num * 8, srcY, 8, 8);
    dst.Set1(dstX, dstY, 8 * scale, 8 * scale);
    pRenderer->AddRenderCopy(&src, &dst);
}

void GameTimer::AddDrawTwoNum(float srcX, float srcY, float dstX, float dstY, float scale, int num)
{
    // 确保数字在0-99范围内
    num = SDL_clamp(num, 0, 99);
    // 提取十位和个位
    int tens = num / 10;
    int ones = num % 10;
    // 绘制十位数
    AddDrawOneNum(srcX, srcY, dstX, dstY, scale, tens);
    // 绘制个位数 (向右偏移一个数字的宽度)
    AddDrawOneNum(srcX, srcY, dstX + 8 * scale, dstY, scale, ones);
}

void GameTimer::AddDrawNum(float srcX, float srcY, float dstX, float dstY, float scale, int num)
{
    // 将数字转换为字符串
    std::string numStr = std::to_string(num);
    // 计算总宽度（用于右对齐）
    float totalWidth = numStr.length() * 8 * scale;
    MyRect src, dst;
    // 从右到左绘制每个数字
    for (size_t i = 0; i < numStr.length(); ++i) 
    {
        int digit = numStr[i] - '0';  // 将字符转换为数字

        // 计算当前数字的位置（右对齐）
        float xPos = dstX + (i * 8 * scale) - totalWidth;
        // 绘制单个数字
        src.Set1(srcX + digit * 8, srcY, 8, 8);
        dst.Set1(xPos, dstY, 8 * scale, 8 * scale);
        pRenderer->AddRenderCopy(&src, &dst);
    }
}
