#include "Swapchain.h"
#include "Client.h"
#include "Mod/Mod.h"
#include "Utils/TimeUtils.h"
#include "Utils/ImGuiRenderUtils.h"
#include "Utils/MathUtils.h"
#include "Utils/ColorUtils.h"
#include "Utils/MoveUtils.h"

#include "Mod/Interface.h"
#include "Mod/ClickGui.h"
#include "Mod/SessionInfo.h"
#include "Mod/Keystrokes.h"
#include "Mod/TargetInfo.h"

#include "Datas/UserDatas.h"
#include "Datas/ProgressDatas.h"

auto Hooks::Swapchain::initFonts() -> void {
    if (!Client::fontInited) {
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::PTSans_Regular_compressed_data, Fonts::PTSans_Regular_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::PTSans_Bold_compressed_data, Fonts::PTSans_Bold_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::PTSans_Italic_compressed_data, Fonts::PTSans_Italic_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::PTSans_BoldItalic_compressed_data, Fonts::PTSans_BoldItalic_compressed_size, 40.f);

        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::Minecraft_Regular_compressed_data, Fonts::Minecraft_Regular_compressed_size, 40.f);
        //ImGui::GetIO().Fonts->AddFontFromFileTTF(_("data\\fonts\\Mojangles.ttf"), 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::Minecraft_Bold_compressed_data, Fonts::Minecraft_Bold_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::Minecraft_Italic_compressed_data, Fonts::Minecraft_Italic_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::Minecraft_BoldItalic_compressed_data, Fonts::Minecraft_BoldItalic_compressed_size, 40.f);

        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::ProximaNova_Regular_compressed_data, Fonts::ProximaNova_Regular_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::ProximaNova_Bold_compressed_data, Fonts::ProximaNova_Bold_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::ProximaNova_Italic_compressed_data, Fonts::ProximaNova_Italic_compressed_size, 40.f);
        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::ProximaNova_BoldItalic_compressed_data, Fonts::ProximaNova_BoldItalic_compressed_size, 40.f);

        ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(Fonts::Icon_Font_compressed_data, Fonts::Icon_Font_compressed_size, 40.f);

        Client::fontInited = true;
    }
}

auto Hooks::Swapchain::handleMods() -> void {
    for (Mod* mod : Client::modlist) {
        if (!mod->enabled && mod->onlyenabled) continue;
        
        mod->onImGuiRender();
    }
}

auto Hooks::Swapchain::handleRenderings() -> void {
    auto interfaceMod = Client::findMod<Interface>(_("Interface"));

    if (false)
    {
        static float animation = 0.f;
        animation = Utils::Math::animate(Client::selectedClient == -1 ? 1.f : 0.f, animation, Client::deltaTime * (Client::selectedClient == -1 ? 1.f : 2.f));
        Client::cancelInputs = Client::selectedClient == -1;

        ImVec4 rect = ImVec4(0, 0, Client::syncwindowsize.x, Client::syncwindowsize.y);
        Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());

        Utils::ImGuiRender::setBlurStreangth(10.f * animation);
        Utils::ImGuiRender::fillBlurRectangle(rect);

        Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.9f * animation));
        Utils::ImGuiRender::fillRectangle(rect);

        Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * 1)]);
        Utils::ImGuiRender::setSize(2.f * animation);

        ImVec2 pos = ImVec2(Client::syncwindowsize.x / 2 - Utils::ImGuiRender::getTextSize(_("Welcome to valkyrie")).x / 2, Client::syncwindowsize.y / 2);

        static float secondanimation = 0.f;
        if (animation > 0.9f) {
            secondanimation = Utils::Math::animate(1.f, secondanimation, Client::deltaTime * 2.f);
            pos.y = Client::syncwindowsize.y / 2 - (300.f * secondanimation);
        }

        for (char s : std::string(_("Welcome to valkyrie"))) {
            std::stringstream ss;
            ss << s;

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
            Utils::ImGuiRender::setSize(2.f);
            ImVec2 size = Utils::ImGuiRender::getTextSize(ss.str());
            Utils::ImGuiRender::drawText(ss.str(), pos);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.6f * animation));
            Utils::ImGuiRender::setThickness(120.f * animation);
            Utils::ImGuiRender::setSize(5.f);
            Utils::ImGuiRender::drawShadow(ImVec2(pos.x, pos.y + (size.y / 2)));
            pos.x += size.x;
        }

        ImVec4 valkyrieRect = ImVec4(Client::syncwindowsize.x / 2 - 200.f, Client::syncwindowsize.y / 2 - 200.f, Client::syncwindowsize.x / 2 + 200.f, Client::syncwindowsize.y / 2 + 200.f);
        Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.f));
        Utils::ImGuiRender::setSecondColor(ImColor(1.f, 0.f, 0.f, 1.f * animation));
        Utils::ImGuiRender::setRound(20.f);
        Utils::ImGuiRender::fillGradientOpaqueRectangle(valkyrieRect);

        static bool grabbed = false;
        auto clientinstance = Client::clientinstance;
        if (clientinstance) {
            if (!Datas::User::logged)
                clientinstance->releaseMouse();
        }
        else if (!grabbed && Datas::User::logged) {
            if (Client::screenName == _("hud_screen")) {
                clientinstance->grabMouse();
            }
            grabbed = true;
        }
    }

    //if (Client::selectedClient == -1) return;

    {
        static float animation = 0.f;
        animation = Utils::Math::animate(Datas::User::logged ? 0.f : 1.f, animation, Client::deltaTime * (Datas::User::logged ? 2.f : 1.f));
        Client::cancelInputs = !Datas::User::logged;

        ImVec4 rect = ImVec4(0, 0, Client::syncwindowsize.x, Client::syncwindowsize.y);
        Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());

        Utils::ImGuiRender::setBlurStreangth(10.f * animation);
        Utils::ImGuiRender::fillBlurRectangle(rect);

        Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.9f * animation));
        Utils::ImGuiRender::fillRectangle(rect);

        Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * 1)]);
        Utils::ImGuiRender::setSize(2.f * animation);

        ImVec2 pos = ImVec2(Client::syncwindowsize.x / 2 - Utils::ImGuiRender::getTextSize(_("Starting Valkyrie 4.1")).x / 2, Client::syncwindowsize.y / 2);

        for (char s : std::string(_("Starting Valkyrie 4.1"))) {
            std::stringstream ss;
            ss << s;

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
            Utils::ImGuiRender::setSize(2.f * animation);
            ImVec2 size = Utils::ImGuiRender::getTextSize(ss.str());
            Utils::ImGuiRender::drawText(ss.str(), pos);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.6f * animation));
            Utils::ImGuiRender::setThickness(120.f * animation);
            Utils::ImGuiRender::setSize(5.f);
            Utils::ImGuiRender::drawShadow(ImVec2(pos.x, pos.y + (size.y / 2)));
            pos.x += size.x;
        }

        /*
        ImVec4 barrect = ImVec4(Client::syncwindowsize.x / 2 - (200.f * animation), Client::syncwindowsize.y / 2 + (100.f * animation), Client::syncwindowsize.x / 2 + (200.f * animation), Client::windowsize.y / 2 + (125.f * animation));
        ImVec4 nowrect = ImVec4(barrect.x, barrect.y, barrect.x + ((400.f * animation) * Datas::Progress::value), barrect.w);
        Utils::ImGuiRender::setThickness(4.f * animation);
        Utils::ImGuiRender::setRound(10.f * animation);
        Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
        Utils::ImGuiRender::drawRectangle(ImVec4(barrect.x - (4.f * animation), barrect.y - (4.f * animation), barrect.z + (4.f * animation), barrect.w + (4.f * animation)));
        Utils::ImGuiRender::fillRectangle(nowrect);
        if (Datas::Progress::start) {
            Datas::Progress::value = Utils::Math::animate(1.f, Datas::Progress::value, Client::deltaTime * 2.f);
        }*/

        static bool grabbed = false;
        auto clientinstance = Client::clientinstance;
        if (clientinstance) {
            if (!Datas::User::logged)
                clientinstance->releaseMouse();
        }
        else if (!grabbed && Datas::User::logged) {
            if (Client::screenName == _("hud_screen")) {
                clientinstance->grabMouse();
            }
            grabbed = true;
        }
    }

    if (!interfaceMod) return;

    // Notifications
    {
        long long now = Utils::Time::getMs();

        Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
        Utils::ImGuiRender::setRound(10.f);
        Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(interfaceMod->bold ? 1 : 0) + (4 * interfaceMod->font)]);

        int index = 1;
        for (Client::Notification& notification : Client::notifications) {
            if (notification.start == 0) notification.start = now;
            Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.4f * notification.animation));

            Utils::ImGuiRender::setSize(1.3f);
            ImVec2 titlesize = Utils::ImGuiRender::getTextSize(notification.title);
            Utils::ImGuiRender::setSize(1.2f);
            ImVec2 messagesize = Utils::ImGuiRender::getTextSize(notification.message);

            bool return_ = now - notification.start >= (1000.f * notification.duration);
            notification.animation = Utils::Math::animate(return_ ? 0.f : 1.f, notification.animation, Client::deltaTime * 2.5f);

            notification.pos.x = Client::windowsize.x - ((200.f + 10.f) * notification.animation);
            if (notification.pos.y == ImVec2().y)
                notification.pos.y = Client::windowsize.y - ((titlesize.y + messagesize.y) + 10.f) * index;

            notification.pos.y = Utils::Math::animate(Client::windowsize.y - ((titlesize.y + messagesize.y) + 20.f) * index, notification.pos.y, Client::deltaTime);
            ImVec4 rect = ImVec4(notification.pos.x - (10.f + notification.addwidth), notification.pos.y - (titlesize.y + 5.f), notification.pos.x + 200.f, notification.pos.y + (messagesize.y + 5.f));

            Utils::ImGuiRender::setSize(1.8f);
            ImVec2 ipos = ImVec2(rect.x + 25.f, rect.y + (((rect.w - rect.y) / 2) - (Utils::ImGuiRender::getTextSize(_("")).y / 2)));

            Utils::ImGuiRender::fillRectangle(rect);

            Utils::ImGuiRender::setBlurStreangth(5.f);
            Utils::ImGuiRender::fillBlurRectangle(rect);

            Utils::ImGuiRender::setThickness(50.f);
            Utils::ImGuiRender::setSize(100.f);
            Utils::ImGuiRender::fillShadowRectangle(rect);

            Utils::ImGuiRender::setSize(1.8f);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * notification.animation));
            Utils::ImGuiRender::drawText(_("i"), ipos);
            ImVec2 ipos2 = ImVec2(ipos.x + (Utils::ImGuiRender::getTextSize(_("i")).x / 2), ipos.y + Utils::ImGuiRender::getTextSize(_("")).y / 2);
            Utils::ImGuiRender::setSegments(24);
            Utils::ImGuiRender::setSize(20.f);
            Utils::ImGuiRender::drawCircle(ipos2);

            Utils::ImGuiRender::setSize(1.3f);
            ImVec2 titlepos = ImVec2(ipos.x + (12.f + 10.f) + 5.f, rect.y + 5.f);
            Utils::ImGuiRender::drawText(notification.title, titlepos);

            Utils::ImGuiRender::setColor(ImColor(0.75f, 0.75f, 0.75f, notification.animation));
            Utils::ImGuiRender::setSize(1.2f);
            ImVec2 messagepos = ImVec2(titlepos.x, titlepos.y + Utils::ImGuiRender::getTextSize("").y);
            Utils::ImGuiRender::drawText(notification.message, messagepos);



            if (!return_)
                index++;
        }

        Client::notifications.erase(
            std::remove_if(Client::notifications.begin(), Client::notifications.end(),
                [](const Client::Notification& notification) {
                    return notification.animation <= 0.01f;
                }), Client::notifications.end());
    }

    // Config Manager
    if (false)
    {
        auto interfaceMod = Client::findMod<Interface>(_("Interface"));
        auto clickguiMod = Client::findMod<ClickGui>(_("Click Gui"));

        if (clickguiMod->enabled)
            Client::openConfigmanager = false;

        if (Client::screenName != _("hud_screen"))
            Client::openConfigmanager = false;

        static float animation = 0.f;
        animation = Utils::Math::animate(Client::openConfigmanager ? 1.f : 0.f, animation, Client::deltaTime * 5.f);

        ImVec4 rect = ImVec4(
            Client::windowsize.x / 2 - 400.f * animation,
            Client::windowsize.y / 2 - 250.f * animation,
            Client::windowsize.x / 2 + 400.f * animation,
            Client::windowsize.y / 2 + 250.f * animation
        );

        Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());

        Utils::ImGuiRender::setColor(ImColor(0.1f, 0.1f, 0.1f, animation));
        Utils::ImGuiRender::setRound(30.f);
        Utils::ImGuiRender::fillRectangle(rect);

        Utils::ImGuiRender::setSize(50.f);
        Utils::ImGuiRender::setThickness(100.f);
        Utils::ImGuiRender::fillShadowRectangle(rect);


        ImVec2 pos = ImVec2(rect.x + 20.f, rect.y + 20.f);
        Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);
        Utils::ImGuiRender::setSize(1.8f * animation);

        Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
        Utils::ImGuiRender::drawText(_("CONFIGS"), pos);

        Utils::ImGuiRender::setSize(1.2f * animation);
        {

            ImVec2 newconfigsize = Utils::ImGuiRender::getTextSize(_("New Config"));
            ImVec2 newconfigpos = ImVec2(
                pos.x + 5.f,
                pos.y + 50.f
            );

            ImVec4 newconfigrect = ImVec4(
                newconfigpos.x - 5.f,
                newconfigpos.y - 5.f,
                newconfigpos.x + 5.f + newconfigsize.x,
                newconfigpos.y + 5.f + newconfigsize.y
            );

            Utils::ImGuiRender::setRound(10.f);
            Utils::ImGuiRender::setColor(ImColor(0.2f, 0.2f, 0.2f, animation));
            Utils::ImGuiRender::fillRectangle(newconfigrect);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
            Utils::ImGuiRender::drawText(_("New Config"), newconfigpos);
        }
    }

    auto clickguiMod = Client::findMod<ClickGui>(Datas::Language::get().module.render.clickgui.name.c_str());

    // Controls
    {
        static bool openCredits = false;
        {
            static float animation = 0.f;
            animation = Utils::Math::animate(((Client::screenName == _("start_screen") || Client::screenName == _("pause_screen") || (clickguiMod && clickguiMod->enabled)) && !openCredits) ? 1.f : 0.f, animation, Client::deltaTime * 10.f);

            Utils::ImGuiRender::setDrawList(ImGui::GetForegroundDrawList());
            Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);
            Utils::ImGuiRender::setSize(1.5f);
            ImVec2 size1 = Utils::ImGuiRender::getTextSize(_("Credits"));
            ImVec2 size2 = Utils::ImGuiRender::getTextSize(_("Soon"));

            ImVec2 pos1 = ImVec2(Client::syncwindowsize.x / 2 - ((size1.x + size2.x) / 2), (Client::syncwindowsize.y + 100) - (150 * animation));
            ImVec2 pos2 = ImVec2(Client::syncwindowsize.x / 2 + ((size1.x + size2.x) / 2), (Client::syncwindowsize.y + 100) - (150 * animation));

            {
                ImVec4 rect = ImVec4(pos1.x - 15.f, pos1.y - 7.5f, pos1.x + size1.x + 15.f, pos1.y + size1.y + 7.5f);
                Utils::ImGuiRender::setColor(ImColor(0.1f, 0.1f, 0.1f, animation));
                Utils::ImGuiRender::setRound(10.f);
                Utils::ImGuiRender::fillRectangle(rect);

                Utils::ImGuiRender::setSize(10.f);
                Utils::ImGuiRender::setThickness(20.f);
                Utils::ImGuiRender::fillShadowRectangle(rect);

                Utils::ImGuiRender::setSize(1.5f);
                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::drawText(_("Credits"), pos1);
                if (Utils::ImGuiRender::isHoveringRect(rect) && ImGui::IsMouseDown(0)) {
                    openCredits = true;
                }
            }
            {
                ImVec4 rect = ImVec4(pos2.x - 15.f, pos2.y - 7.5f, pos2.x + size2.x + 15.f, pos2.y + size2.y + 7.5f);
                Utils::ImGuiRender::setColor(ImColor(0.1f, 0.1f, 0.1f, animation));
                Utils::ImGuiRender::setRound(10.f);
                Utils::ImGuiRender::fillRectangle(rect);

                Utils::ImGuiRender::setSize(10.f);
                Utils::ImGuiRender::setThickness(20.f);
                Utils::ImGuiRender::fillShadowRectangle(rect);

                Utils::ImGuiRender::setSize(1.5f);
                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::drawText(_("Soon"), pos2);
            }
        }

        {
            static bool back = false;
            if (openCredits) {
                Client::forceCancelinputs = true;
                back = true;
                if (clickguiMod)
                    clickguiMod->unvisible = true;
                if (Client::clientinstance)
                    Client::clientinstance->releaseMouse();
                if (Client::keymaps[VK_ESCAPE]) {
                    openCredits = false;
                }
            }
            else {
                if (back) {
                    Client::forceCancelinputs = false;
                    if (clickguiMod)
                        clickguiMod->unvisible = false;
                    if (Client::clientinstance && Client::screenName == _("hud_screen"))
                        Client::clientinstance->grabMouse();

                    back = false;
                }
            }

            static float animation = 0.f;
            animation = Utils::Math::animate(openCredits ? 1.f : 0.f, animation, Client::deltaTime * 5.f);

            Utils::ImGuiRender::setDrawList(ImGui::GetForegroundDrawList());
            Utils::ImGuiRender::setBlurStreangth(10.f * animation);
            Utils::ImGuiRender::fillBlurRectangle(ImVec4(0, 0, Client::syncwindowsize.x, Client::syncwindowsize.y));
            Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);
            Utils::ImGuiRender::setSize(2.f * animation);
            ImVec2 size = Utils::ImGuiRender::getTextSize(_("Credits"));
            ImVec2 pos = ImVec2(Client::syncwindowsize.x / 2 - size.x / 2, Client::syncwindowsize.y / 2.5f);
            ImVec4 rect = ImVec4(pos.x - (200.f * animation), pos.y - (100.f * animation), pos.x + size.x + (200.f * animation), pos.y + (400.f * animation));
            Utils::ImGuiRender::setColor(ImColor(0.1f, 0.1f, 0.1f, animation));
            Utils::ImGuiRender::setRound(20.f);
            Utils::ImGuiRender::fillRectangle(rect);

            Utils::ImGuiRender::setSize(10.f);
            Utils::ImGuiRender::setThickness(20.f);
            Utils::ImGuiRender::fillShadowRectangle(rect);

            Utils::ImGuiRender::setSize(2.4f * animation);
            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
            Utils::ImGuiRender::drawText(_("Credits"), pos);

            {
                Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);
                Utils::ImGuiRender::setSize(1.6f * animation);
                ImVec2 size_ = Utils::ImGuiRender::getTextSize(_("Development"));
                ImVec2 pos_ = ImVec2(Client::syncwindowsize.x / 2 - size_.x / 2, (Client::syncwindowsize.y / 2.5f) + size.y + 40.f);

                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::drawText(_("Development"), pos_);


                Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * interfaceMod->font)]);
                Utils::ImGuiRender::setSize(1.2f * animation);
                ImVec2 size__ = Utils::ImGuiRender::getTextSize(_("Hiroki, Zv9u"));
                ImVec2 pos__ = ImVec2(Client::syncwindowsize.x / 2 - size__.x / 2, (Client::syncwindowsize.y / 2.5f) + size.y + size_.y + 40.f);

                Utils::ImGuiRender::setColor(ImColor(0.8f, 0.8f, 0.8f, animation));
                Utils::ImGuiRender::drawText(_("Hiroki, Zv9u"), pos__);




                Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);
                Utils::ImGuiRender::setSize(1.6f * animation);
                ImVec2 size___ = Utils::ImGuiRender::getTextSize(_("Special Thanks"));
                ImVec2 pos___ = ImVec2(Client::syncwindowsize.x / 2 - size___.x / 2, (Client::syncwindowsize.y / 2.5f) + size.y + size_.y + size__.y + 40.f + 10.f);

                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::drawText(_("Special Thanks"), pos___);


                Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * interfaceMod->font)]);
                Utils::ImGuiRender::setSize(1.2f * animation);
                ImVec2 size____ = Utils::ImGuiRender::getTextSize(_("Beta Testers: PT Hacker, OwO, Full Disabler, Surukotonai"));
                ImVec2 pos____ = ImVec2(Client::syncwindowsize.x / 2 - size____.x / 2, (Client::syncwindowsize.y / 2.5f) + size.y + size_.y + size__.y + size___.y + 40.f + 10.f);

                Utils::ImGuiRender::setColor(ImColor(0.8f, 0.8f, 0.8f, animation));
                Utils::ImGuiRender::drawText(_("Beta Testers: PT Hacker, OwO, Hiyoki, Surukotonai"), pos____);












                Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[2 + (4 * interfaceMod->font)]);
                Utils::ImGuiRender::setSize(1.1f * animation);
                ImVec2 size_____ = Utils::ImGuiRender::getTextSize(_("Valkyrie Client (C) 2025 Hiroki. All rights reserved"));
                ImVec2 pos_____ = ImVec2(Client::syncwindowsize.x / 2 - size_____.x / 2, (Client::syncwindowsize.y / 2.5f) + (350.f * animation));

                Utils::ImGuiRender::setColor(ImColor(0.8f, 0.8f, 0.8f, animation));
                Utils::ImGuiRender::drawText(_("Valkyrie Client (C) 2025 Hiroki. All rights reserved"), pos_____);
            }
        }
    }

    {
        if (Client::screenName == _("hud_screen")) {
            Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
            Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * interfaceMod->font)]);
            Utils::ImGuiRender::setSize(1.2f);
            ImVec2 size = Utils::ImGuiRender::getTextSize(_("www.valkyrieclient.xyz"));
            ImVec2 pos = ImVec2(Client::windowsize.x - (size.x + 5.f), Client::windowsize.y - (size.y + 5.f));
            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f));
            Utils::ImGuiRender::drawText(_("www.valkyrieclient.xyz"), pos);
        }
    }

    {
        static float animation = 0.f;
        animation = Utils::Math::animate(Client::screenName == _("chat_screen") ? 1.f : 0.f, animation, Client::deltaTime * 5.f);

        static bool isdragging1 = false;
        static bool isdragging2 = false;
        static bool isdragging3 = false;
        static bool isdragging4 = false;
        static bool isdragging5 = false;
        static bool isdragging6 = false;

        auto sessionInfoMod = Client::findMod<SessionInfo>(_("Session Info"));
        if (clickguiMod && !clickguiMod->enabled && sessionInfoMod->enabled) {
            float width = 0.f;
            int style = sessionInfoMod->style;
            if (style == 0)
                width = 140.f;
            else if (style == 1)
                width = 120.f;

            ImVec4 rect = ImVec4(
                sessionInfoMod->pos.x - (120.f + 1.f),
                sessionInfoMod->pos.y - 51.f,
                sessionInfoMod->pos.x + (width + 1.f),
                sessionInfoMod->pos.y + 51.f
            );
            
            Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
            Utils::ImGuiRender::setThickness(2.5f);
            Utils::ImGuiRender::setRound(20.f);
            Utils::ImGuiRender::drawRectangle(rect);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f * animation));
            Utils::ImGuiRender::fillRectangle(rect);

            if (ImGui::IsMouseDown(0)) {
                if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect)) {
                    isdragging1 = true;
                }
            }
            else {
                isdragging1 = false;
            }

            if (isdragging1) {
                if (!isdragging2 && !isdragging3 && !isdragging4 && !isdragging5 && !isdragging6)
                    sessionInfoMod->pos = ImVec2(Client::mousex, Client::mousey);
            }
        }

        auto keystrokesMod = Client::findMod<Keystrokes>(_("Keystrokes"));
        if (clickguiMod && !clickguiMod->enabled && keystrokesMod->enabled) {
            ImVec4 rect = ImVec4(
                keystrokesMod->pos.x - 85.f,
                keystrokesMod->pos.y - 85.f,
                keystrokesMod->pos.x + 85.f,
                keystrokesMod->pos.y + 65.f
            );
            
            Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
            Utils::ImGuiRender::setThickness(2.5f);
            Utils::ImGuiRender::setRound(20.f);
            Utils::ImGuiRender::drawRectangle(rect);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f * animation));
            Utils::ImGuiRender::fillRectangle(rect);

            if (ImGui::IsMouseDown(0)) {
                if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect)) {
                    isdragging2 = true;
                }
            }
            else {
                isdragging2 = false;
            }

            if (isdragging2) {
                if (!isdragging1 && !isdragging3 && !isdragging4 && !isdragging5 && !isdragging6)
                    keystrokesMod->pos = ImVec2(Client::mousex, Client::mousey);
            }
        }

        auto targetinfoMod = Client::findMod<TargetInfo>(_("Target Info"));
        if (clickguiMod && !clickguiMod->enabled && targetinfoMod->enabled) {
            Utils::ImGuiRender::setSize(1.4f);
            ImVec4 rect;
            if (targetinfoMod->style == 0) {
                rect = ImVec4(
                    targetinfoMod->pos.x - (((Utils::ImGuiRender::getTextSize(_("Name: ") + targetinfoMod->lastplayer.name).x) / 2) + 50.f),
                    targetinfoMod->pos.y - 40.f,
                    targetinfoMod->pos.x + (((Utils::ImGuiRender::getTextSize(_("Name: ") + targetinfoMod->lastplayer.name).x) / 2) + 50.f),
                    targetinfoMod->pos.y + 40.f
                );
            }
            else if (targetinfoMod->style == 1) {
                rect = ImVec4(
                    targetinfoMod->pos.x - (((Utils::ImGuiRender::getTextSize(targetinfoMod->lastplayer.name).x) / 2) + 50.f),
                    targetinfoMod->pos.y - 40.f,
                    targetinfoMod->pos.x + (((Utils::ImGuiRender::getTextSize(targetinfoMod->lastplayer.name).x) / 2) + 50.f),
                    targetinfoMod->pos.y + 40.f
                );
            }
            else if (targetinfoMod->style == 2) {
                rect = ImVec4(
                    targetinfoMod->pos.x - (((Utils::ImGuiRender::getTextSize(targetinfoMod->lastplayer.name).x) / 2) + 50.f),
                    targetinfoMod->pos.y - 40.f,
                    targetinfoMod->pos.x + (((Utils::ImGuiRender::getTextSize(targetinfoMod->lastplayer.name).x) / 2) + 50.f),
                    targetinfoMod->pos.y + 40.f
                );
            }

            Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
            Utils::ImGuiRender::setThickness(2.5f);
            Utils::ImGuiRender::setRound(20.f);
            Utils::ImGuiRender::drawRectangle(rect);

            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f * animation));
            Utils::ImGuiRender::fillRectangle(rect);

            if (ImGui::IsMouseDown(0)) {
                if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect)) {
                    isdragging3 = true;
                }
            }
            else {
                isdragging3 = false;
            }

            if (isdragging3) {
                if (!isdragging1 && !isdragging2 && !isdragging4 && !isdragging5 && !isdragging6)
                    targetinfoMod->pos = ImVec2(Client::mousex, Client::mousey);
            }
        }


        auto clientinstance = Client::clientinstance;
        if (!clientinstance) return;

        auto localplayer = clientinstance->getLocalPlayer();
        if (!localplayer) return;

        auto minecraft = clientinstance->getMinecraft();
        if (!minecraft) return;

        auto timer = minecraft->getTimer();
        if (!timer) return;

        Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);

        Utils::ImGuiRender::setSize(1.5f);

        std::stringstream ssfps, sscps, ssbps;

        ssfps.precision(0);
        ssfps << std::fixed << Client::framerate;

        sscps.precision(0);
        sscps << std::fixed << static_cast<int>(interfaceMod->clicks.size());

        ssbps.precision(1);
        ssbps << std::fixed << Utils::Move::getSpeed(localplayer) * timer->mTicksPerSecond;

        std::string fpsstr = ssfps.str();
        std::string cpsstr = sscps.str();
        std::string bpsstr = ssbps.str();


        auto interfaceMod = Client::findMod<Interface>(_("Interface"));
        if (clickguiMod && !clickguiMod->enabled && interfaceMod->enabled && interfaceMod->info == 0) {
            Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[1 + (4 * interfaceMod->font)]);

            Utils::ImGuiRender::setSize(1.5f);

            if (interfaceMod->fps) {
                ImVec4 rect = ImVec4(
                    interfaceMod->fpspos.x - (10.f + 1.f),
                    interfaceMod->fpspos.y - (25.f + 1.f),
                    interfaceMod->fpspos.x + (10.f + Utils::ImGuiRender::getTextSize(_("FPS: ") + fpsstr).x),
                    interfaceMod->fpspos.y + (25.f + 1.f)
                );

                Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::setThickness(2.5f);
                Utils::ImGuiRender::setRound(10.f);
                Utils::ImGuiRender::drawRectangle(rect);

                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f * animation));
                Utils::ImGuiRender::fillRectangle(rect);

                if (ImGui::IsMouseDown(0)) {
                    if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect)) {
                        isdragging4 = true;
                    }
                }
                else {
                    isdragging4 = false;
                }

                if (isdragging4) {
                    if (!isdragging1 && !isdragging2 && !isdragging3 && !isdragging5 && !isdragging6)
                        interfaceMod->fpspos = ImVec2(Client::mousex, Client::mousey);
                }
            }
            if (interfaceMod->cps) {
                ImVec4 rect = ImVec4(
                    interfaceMod->cpspos.x - (10.f + 1.f),
                    interfaceMod->cpspos.y - (25.f + 1.f),
                    interfaceMod->cpspos.x + (10.f + Utils::ImGuiRender::getTextSize(_("CPS: ") + cpsstr).x),
                    interfaceMod->cpspos.y + (25.f + 1.f)
                );

                Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::setThickness(2.5f);
                Utils::ImGuiRender::setRound(10.f);
                Utils::ImGuiRender::drawRectangle(rect);

                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f * animation));
                Utils::ImGuiRender::fillRectangle(rect);

                if (ImGui::IsMouseDown(0)) {
                    if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect)) {
                        isdragging5 = true;
                    }
                }
                else {
                    isdragging5 = false;
                }

                if (isdragging5) {
                    if (!isdragging1 && !isdragging2 && !isdragging3 && !isdragging4 && !isdragging6)
                        interfaceMod->cpspos = ImVec2(Client::mousex, Client::mousey);
                }
            }
            if (interfaceMod->bps) {
                ImVec4 rect = ImVec4(
                    interfaceMod->bpspos.x - (10.f + 1.f),
                    interfaceMod->bpspos.y - (25.f + 1.f),
                    interfaceMod->bpspos.x + (10.f + Utils::ImGuiRender::getTextSize(_("BPS: ") + bpsstr).x),
                    interfaceMod->bpspos.y + (25.f + 1.f)
                );

                Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
                Utils::ImGuiRender::setThickness(2.5f);
                Utils::ImGuiRender::setRound(10.f);
                Utils::ImGuiRender::drawRectangle(rect);

                Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 0.2f * animation));
                Utils::ImGuiRender::fillRectangle(rect);

                if (ImGui::IsMouseDown(0)) {
                    if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect)) {
                        isdragging6 = true;
                    }
                }
                else {
                    isdragging6 = false;
                }

                if (isdragging6) {
                    if (!isdragging1 && !isdragging2 && !isdragging3 && !isdragging4 && !isdragging5)
                        interfaceMod->bpspos = ImVec2(Client::mousex, Client::mousey);
                }
            }
        }

        {
            Utils::ImGuiRender::setSize(1.4f);
            Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0]);
            ImVec2 size = Utils::ImGuiRender::getTextSize(_("Reset Position"));
            ImVec2 pos = ImVec2(Client::windowsize.x / 2.f - (size.x / 2), -(size.y + 100.f) + ((size.y + 110.f) * animation));
            ImVec4 rect = ImVec4(pos.x - 5.f, pos.y - 5.f, pos.x + size.x + 5.f, pos.y + size.y + 5.f);
            Utils::ImGuiRender::setColor(ImColor(0.1f, 0.1f, 0.1f, animation));
            Utils::ImGuiRender::setSize(10.f);
            Utils::ImGuiRender::setThickness(200.f);
            Utils::ImGuiRender::setRound(10.f);
            Utils::ImGuiRender::fillShadowRectangle(rect);
            Utils::ImGuiRender::fillRectangle(rect);

            Utils::ImGuiRender::setThickness(2.5f);
            Utils::ImGuiRender::setColor(ImColor(0.2f, 0.2f, 0.2f, animation));
            Utils::ImGuiRender::drawRectangle(rect);
            
            Utils::ImGuiRender::setSize(1.4f);
            Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, animation));
            Utils::ImGuiRender::drawText(_("Reset Position"), pos);

            if (Client::screenName == _("chat_screen") && Utils::ImGuiRender::isHoveringRect(rect) && ImGui::IsMouseDown(0)) {
                sessionInfoMod->pos = ImVec2(130.f, Client::windowsize.y / 4);
                keystrokesMod->pos = ImVec2(90.f, Client::windowsize.y / 2.5f);
                targetinfoMod->pos = ImVec2(Client::windowsize.x / 2 + 300.f, Client::windowsize.y / 2 + 100.f);
                interfaceMod->fpspos = ImVec2(30.f, Client::windowsize.y - (Utils::ImGuiRender::getTextSize("").y + 10.f));
                interfaceMod->cpspos = ImVec2((30.f + (15.f + Utils::ImGuiRender::getTextSize(_("FPS: ") + fpsstr).x)) + 60.f, Client::windowsize.y - (Utils::ImGuiRender::getTextSize("").y + 10.f));
                interfaceMod->bpspos = ImVec2((30.f + (10.f + Utils::ImGuiRender::getTextSize(_("FPS: ") + fpsstr).x + Utils::ImGuiRender::getTextSize(_("CPS: ") + cpsstr).x)) + (60.f * 2), Client::windowsize.y - (Utils::ImGuiRender::getTextSize("").y + 10.f));
            }
        }
    }
}

auto Hooks::Swapchain::calcFps() -> void {
    static float calcfps = 0.f;
    calcfps++;
    static long long start = Utils::Time::getMs();
    long long now = Utils::Time::getMs();
    if (now - start >= 1000.f) {
        Client::framerate = calcfps;
        calcfps = 0.f;
        start = now;
    }
}

void Hooks::Swapchain::commandlist_callback(ID3D12CommandQueue* queue, void* arg_2, void* arg_3) {
    if (!d3d12CommandQueue)
        d3d12CommandQueue = queue;
    
    commandlist(queue, arg_2, arg_3);
}

long Hooks::Swapchain::present_callback(IDXGISwapChain3* swapchain, void* arg_2, void* arg_3) {
    static HWND window = FindWindowA(0, _("Minecraft"));
    static bool inited = false;

    /*
    RECT rect;
    GetClientRect(window, &rect);
    Client::windowsize = ImVec2(rect.right - rect.left, rect.bottom - rect.top);
    */

    {
        if (Client::dropfps) {
            long long now = Utils::Time::getMs();
            static long long start = now;
            if (now - start >= 400.f) {
                start = now;
            }
            else {
                return false;
            }
        }
    }

    if (SUCCEEDED(swapchain->GetDevice(IID_PPV_ARGS(&device_11)))) {
        ID3D11DeviceContext* context;
        ID3D11Texture2D* backbuffer;
        IDXGISurface* dxgibuffer;
        ID3D11RenderTargetView* rendertargetview;

        device_11->GetImmediateContext(&context);

        {
            swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backbuffer);
            swapchain->GetBuffer(0, __uuidof(IDXGISurface), (LPVOID*)&dxgibuffer);
        }

        device_11->CreateRenderTargetView(backbuffer, 0, &rendertargetview);

        backbuffer->Release();

        {
            if (!inited) {
                ImGui::CreateContext();
                initFonts();

                ImGui_ImplWin32_Init(window);
                ImGui_ImplDX11_Init(device_11, context);

                inited = true;
            }
        }

        ImGui_ImplDX11_NewFrame();
        ImGui_ImplWin32_NewFrame();

        ImBlur::NewFrame(device_11, dxgibuffer, GetDpiForWindow(window));
        ImGui::NewFrame();

        handleMods();
        handleRenderings();
        calcFps();

        ImGui::EndFrame();
        ImBlur::EndFrame();
        ImGui::Render();

        context->OMSetRenderTargets(1, &rendertargetview, 0);
        ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

        rendertargetview->Release();
        device_11->Release();
    }
    else if (SUCCEEDED(swapchain->GetDevice(__uuidof(ID3D12Device), reinterpret_cast<void**>(&device_12)))) {
        //swapchain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
        reinterpret_cast<ID3D12Device5*>(device_12)->RemoveDevice();

        /* // i never use dx12 100% shit gay
        DXGI_SWAP_CHAIN_DESC sdesc;
        swapchain->GetDesc(&sdesc);
        sdesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
        sdesc.OutputWindow = window;
        sdesc.Windowed = ((GetWindowLongPtr(window, GWL_STYLE) & WS_POPUP) != 0) ? false : true;

        buffersCounts = sdesc.BufferCount;
        frameContext = new FrameContext[buffersCounts];

        D3D12_DESCRIPTOR_HEAP_DESC descriptorImGuiRender = {};
        descriptorImGuiRender.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
        descriptorImGuiRender.NumDescriptors = buffersCounts;
        descriptorImGuiRender.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;

        if (!d3d12DescriptorHeapImGuiRender)
            if (FAILED(device_12->CreateDescriptorHeap(&descriptorImGuiRender, IID_PPV_ARGS(&d3d12DescriptorHeapImGuiRender))))
                return present(swapchain, arg_2, arg_3);

        if (device_12->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)) != S_OK)
            return false;

        for (size_t i = 0; i < buffersCounts; i++) {
            frameContext[i].commandAllocator = allocator;
        };

        if (device_12->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, allocator, NULL, IID_PPV_ARGS(&d3d12CommandList)) != S_OK ||
            d3d12CommandList->Close() != S_OK)
            return false;

        D3D12_DESCRIPTOR_HEAP_DESC descriptorBackBuffers;
        descriptorBackBuffers.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
        descriptorBackBuffers.NumDescriptors = buffersCounts;
        descriptorBackBuffers.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        descriptorBackBuffers.NodeMask = 1;

        if (device_12->CreateDescriptorHeap(&descriptorBackBuffers, IID_PPV_ARGS(&d3d12DescriptorHeapBackBuffers)) != S_OK)
            return false;

        const auto rtvDescriptorSize = device_12->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
        D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = d3d12DescriptorHeapBackBuffers->GetCPUDescriptorHandleForHeapStart();

        for (size_t i = 0; i < buffersCounts; i++) {
            ID3D12Resource* backbuffer = nullptr;
            IDXGISurface* dxgibackbuffer = nullptr;
            frameContext[i].main_render_target_descriptor = rtvHandle;

            swapchain->GetBuffer((UINT)i, __uuidof(ID3D12Resource), (LPVOID*)&backbuffer);
            swapchain->GetBuffer((UINT)i, __uuidof(IDXGISurface), (LPVOID*)&dxgibackbuffer);

            device_12->CreateRenderTargetView(backbuffer, nullptr, rtvHandle);
            frameContext[i].main_render_target_resource = backbuffer;
            rtvHandle.ptr += rtvDescriptorSize;

            backbuffer->Release();
        };

        if (!inited) {
            ImGui::CreateContext();

            initFonts();

            ImGui_ImplWin32_Init(window);
            ImGui_ImplDX12_Init(device_12, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM, d3d12DescriptorHeapImGuiRender, d3d12DescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(), d3d12DescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart());
            inited = true;
        };

        if (!d3d12CommandQueue)
            return present(swapchain, arg_2, arg_3);

        ImGui_ImplDX12_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();

        handleMods();
        handleRenderings();
        calcFps();

        FrameContext& currentFrameContext = frameContext[swapchain->GetCurrentBackBufferIndex()];
        currentFrameContext.commandAllocator->Reset();

        D3D12_RESOURCE_BARRIER barrier = {};
        barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
        barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
        barrier.Transition.pResource = currentFrameContext.main_render_target_resource;
        barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
        barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
        barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;

        d3d12CommandList->Reset(currentFrameContext.commandAllocator, nullptr);
        d3d12CommandList->ResourceBarrier(1, &barrier);
        d3d12CommandList->OMSetRenderTargets(1, &currentFrameContext.main_render_target_descriptor, FALSE, nullptr);
        d3d12CommandList->SetDescriptorHeaps(1, &d3d12DescriptorHeapImGuiRender);

        ImGui::EndFrame();
        ImGui::Render();

        ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), d3d12CommandList);

        barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
        barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;

        d3d12CommandList->ResourceBarrier(1, &barrier);
        d3d12CommandList->Close();
        d3d12CommandQueue->ExecuteCommandLists(1, reinterpret_cast<ID3D12CommandList* const*>(&d3d12CommandList));

        if (d3d12DescriptorHeapBackBuffers) {
            d3d12DescriptorHeapBackBuffers->Release();
        }

        d3d12CommandList->Release();
        allocator->Release();
        currentFrameContext.main_render_target_resource->Release();
        device_12->Release();

        delete frameContext;*/
    }
    else {
        MessageBoxA(0, _("The program was terminated due to an error.\nError code: 1-2-1"), _("Valkyrie"), MB_ICONERROR);
        Client::running = false;
    }

    /*
    POINT pt;
    GetCursorPos(&pt);
    HMONITOR hMonitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
    UINT dpix, dpiy;
    GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
    ImGui::GetIO().MousePos = ImVec2(pt.x, MulDiv(pt.y, 90, dpiy));
    */



    return present(swapchain, arg_2, arg_3);
}

long Hooks::Swapchain::resize_callback(IDXGISwapChain* swapchain, int buffercount, int width, int height, DXGI_FORMAT newFormat, int flags) {
    ImBlur::Cleanup();

    return resize(swapchain, buffercount, width, height, newFormat, flags);
}

long Hooks::Swapchain::corewindow_callback(IDXGIFactory2* factory, IUnknown* device, IUnknown* window, DXGI_SWAP_CHAIN_DESC1* desc, IDXGIOutput* output, IDXGISwapChain1* swapchain) {
    desc->Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;

    return corewindow(factory, device, window, desc, output, swapchain);
}
