#include "pch.h"
#include "imguiC.h"
#include "DNFTOOL.h"

#ifdef _WIN64
#define SELF_PTR LONG_PTR
#define WNDPROC_INDEX GWLP_WNDPROC
#else
#define SELF_PTR DWORD
#define WNDPROC_INDEX GWL_WNDPROC

#endif
typedef HRESULT(WINAPI* Reset_t)(LPDIRECT3DDEVICE9, D3DPRESENT_PARAMETERS*); // 16
typedef long(__stdcall* EndScene_t)(LPDIRECT3DDEVICE9);                      // 42
typedef LRESULT(__stdcall* WndProc_t)(const HWND, UINT, WPARAM, LPARAM);

D3DPRESENT_PARAMETERS   g_present;
IDirect3D9* g_Direct3D9 = NULL;
IDirect3DDevice9* g_pd3dDevice = NULL;
HWND g_hWnd = NULL;

Reset_t     oReset;
EndScene_t  oBeginScene;
EndScene_t  oEndScene;
WndProc_t   oWndProc;

DWORD* dDeviceVT = NULL;


extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

static bool IMGUISW = false;

LRESULT __stdcall hkWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true;
    switch (msg) {
    case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:    case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
    case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:    case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
        if (checkBoxFalgs_1) return true;
    }


    return CallWindowProc(oWndProc, hWnd, msg, wParam, lParam);
}

void MineImGuiInit(IDirect3DDevice9* pd3dDevice)
{
    // 检查IMGUI 版本
    IMGUI_CHECKVERSION();

    // 创建IMGUI上下文
    ImGui::CreateContext();

    ImGuiIO& io = ImGui::GetIO();
    // 关闭imgui  配置文件的显示
    io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
    io.WantSaveIniSettings = false;
    io.IniFilename = NULL;

    //ImGuiStyle& style = ImGui::GetStyle();
    ImGui::StyleColorsDark();
    //ImGui::StyleColorsClassic();
    //ImGui::StyleColorsLight();
    //LoadMyStype();

    //SetLayeredWindowAttributes();
    // 设置字体---为了显示中文
    ImFontConfig f_cfg;
    f_cfg.FontDataOwnedByAtlas = false;
    //const ImFont* font = io.Fonts->AddFontFromMemoryTTF((void*)baidu_font_data, baidu_font_size, 17.0f, &f_cfg, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
    const ImFont* font = io.Fonts->AddFontFromFileTTF("Fonts/simsun.ttc", 11.5f, &f_cfg, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
    
    ImGui_ImplWin32_Init(g_hWnd);
    ImGui_ImplDX9_Init(pd3dDevice);

}


LPDIRECT3DTEXTURE9 g_texture;
void imguiC::LoadImg()
{

    //unsigned char* buffer = GetNPK();



    /*
    for (int y = 0; y < 118; y++)
        memcpy((unsigned char*)lock_rect.pBits + lock_rect.Pitch * y, buffer + (203 * 4) * y, (203 * 4));
        */



}


namespace Gdiplus
{
    using std::min;
    using std::max;
};
#include <atlimage.h>

bool TmainBeginSate = TRUE;
void DrawCustom(IDirect3DDevice9* pd3dDevice)
{
    // 界面开始绘制
    ImGui_ImplDX9_NewFrame();
    ImGui_ImplWin32_NewFrame();

    ImGui::NewFrame();

    // 窗口大小
    ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver);
    ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
    //ImGui::SetNextWindowBgAlpha(0);

    ImGui::Begin(u8"imgui_Test", &TmainBeginSate, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);


    ImDrawList* draw_list = ImGui::GetForegroundDrawList();


    

    CImage Img;
    DWORD adwBitmasks[3] = { 0x0000000f, 0x000000f0, 0x00000f00 };
    Img.CreateEx(100, 100, 16, BI_BITFIELDS, adwBitmasks, 0);
    Img.Save(L"Test.png");

    ImGui::Image(Img, ImVec2(400, 400));
    draw_list->AddText(ImVec2(400, 400), 0xfaff0000,u8"倾泪寒");
    /*
    pd3dDevice->CreateTexture(203, 118, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &g_texture, NULL);


    D3DLOCKED_RECT lock_rect;
    g_texture->LockRect(0, &lock_rect, NULL, 0);

    char* nPbit = (char*)lock_rect.pBits;
    int nPitch = lock_rect.Pitch;
    int stride = nPitch / (4 * 3);//划分为3等份，stride为步长

    DWORD* pwd = (DWORD*)nPbit;
    for (UINT row = 0; row < 240; row++)
    {
        for (int col = 0; col < stride; col++)
        {
            pwd[row * nPitch / 4 + col] = 0xFFFF0000;
            pwd[row * nPitch / 4 + col + stride] = 0xFF00FF00;
            pwd[row * nPitch / 4 + col + 2 * stride] = 0xFF0000FF;
        }
    }
    g_texture->UnlockRect(0);

    ImGui::Image(g_texture, ImGui::GetContentRegionAvail());
 */

    //ImGui::Checkbox(u8"禁用鼠标     ", &checkBoxFalgs_1); ImGui::SameLine();
    ////CString tmpste = (checkBoxFalgs_1) ? "ON" : "OFF";
    ////ImGui::Text(u8"[ %S ]", tmpste); 

    //if (ImGui::BeginTabBar("tab1", tab_bar_flags))
    //{
    //    loadTab1();
    //    loadTab2();
    //    loadTab3();
    //    loadTab4();
    //}

    //BYTE* PNGB = GetNPK();
    //ImGui::RenderText(ImVec2(203, 118), (char*)PNGB);
    /*
    std::vector<unsigned char> encoded;
    unsigned error_enc = lodepng::encode(encoded, PNGB, 203, 118, LodePNGColorType::LCT_RGBA, unsigned(8));

    static ImTextureID bg_tex_id = 0;
    if (!bg_tex_id)
    {
        //这里使用opencv加载图片当然你也可以使用其他方式加载图片
        //loadTexture是一个自定义的函数用于图片字符加载为纹理，不知道怎么加载纹理的可以自行百度
        

        bg_tex_id = &encoded;
    }

    ImGui::Image(bg_tex_id, ImGui::GetContentRegionAvail());
    */
    

    ImGui::EndTabBar();
    ImGui::End();
    ImGui::EndFrame();
    ImGui::Render();
    ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());

}

HRESULT __stdcall hkEndScene(IDirect3DDevice9* pd3dDevice)
{
    /*
    static int num = 0;
    std::cout << "D3d:" << num << std::endl;
    ++num;
    */
    g_pd3dDevice = pd3dDevice;
    Helpers::UnHookFunction((PVOID*)(&oEndScene), hkEndScene);

    // IMGUI初始化
    static bool firstCall = TRUE;
    if (firstCall)
    {
        firstCall = !firstCall;
        MineImGuiInit(pd3dDevice);
        oWndProc = (WNDPROC)SetWindowLongPtr(g_hWnd, WNDPROC_INDEX, (LONG_PTR)hkWndProc);
    }

    if (IMGUISW == true)
    {
        //DrawCustom(pd3dDevice);
        IMGUISW = false;
    }
    //DrawCustom();

    HRESULT result = pd3dDevice->EndScene();
    Helpers::HookFunction((PVOID*)(&oEndScene), hkEndScene);
    return result;
}

HRESULT __stdcall hkReset(IDirect3DDevice9* pd3dDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
    std::cout << "Im Going" << std::endl;
    Helpers::UnHookFunction((PVOID*)(&oReset), &hkReset);
    ImGui_ImplDX9_InvalidateDeviceObjects();
    HRESULT tmpReset = pd3dDevice->Reset(pPresentationParameters);
    ImGui_ImplDX9_CreateDeviceObjects();
    Helpers::HookFunction((PVOID*)(&oReset), hkReset);
    return tmpReset;
}






IDirect3DDevice9* imguiC::GetD3dDev9()
{
    return g_pd3dDevice;
}






















typedef struct tagWNDINFO
{
    DWORD dwProcessId;
    HWND hWnd;
} WNDINFO, * LPWNDINFO;
//枚举窗口过程
static BOOL CALLBACK EnumProc(HWND hWnd, LPARAM lParam)
{
    DWORD dwProcessId;
    GetWindowThreadProcessId(hWnd, &dwProcessId);
    LPWNDINFO pInfo = (LPWNDINFO)lParam;

    if (dwProcessId == pInfo->dwProcessId)
    {
        pInfo->hWnd = hWnd;
        return FALSE;
    }
    return TRUE;
}
//获取主窗口句柄
static HWND GetProcessMainWnd()
{
    DWORD dwProcessId = ::GetCurrentProcessId();
    WNDINFO wi;
    wi.dwProcessId = dwProcessId;
    wi.hWnd = NULL;
    EnumWindows(EnumProc, (LPARAM)&wi);
    return wi.hWnd;
}












void imguiC::Init()
{
    IMGUISW = true;
    /*
    static bool Sw = false;
    if (!Sw)
    {
        // 检查IMGUI 版本
        IMGUI_CHECKVERSION();
        ImGui::CreateContext();
        ImGuiIO& io = ImGui::GetIO(); (void)io;
        io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
        io.WantSaveIniSettings = false;
        io.IniFilename = NULL;

        ImGui::StyleColorsDark();

        ImFontConfig f_cfg;
        f_cfg.FontDataOwnedByAtlas = false;
        const ImFont* font = io.Fonts->AddFontFromMemoryTTF((void*)baidu_font_data, baidu_font_size, 17.0f, &f_cfg, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());

        ImGui_ImplWin32_Init(g_hWnd);
        ImGui_ImplDX9_Init(g_pd3dDevice);
        Sw = true;
    }


    //g_pd3dDevice->BeginScene();

    // 界面开始绘制
    ImGui_ImplDX9_NewFrame();
    ImGui_ImplWin32_NewFrame();

    ImGui::NewFrame();

    // 窗口大小
    ImGui::SetNextWindowPos(ImVec2(50, 50), ImGuiCond_FirstUseEver);
    ImGui::SetNextWindowSize(ImVec2(350, 450), ImGuiCond_FirstUseEver);

    ImGui::Begin(u8"Imgui_Test", &TmainBeginSate);

    ImGui::EndTabBar();
    ImGui::End();
    ImGui::EndFrame();
    ImGui::Render();
    ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());

    //g_pd3dDevice->EndScene();
    */
}




void imguiC::Run()
{
    //while (true)
    //{
    //    if (DNFTOOL::GetHook(0x1A5FB4C, "0x14+0x28+") == 6)
    //    {
    //        std::cout << "开始注入" << std::endl;
    //        break;
    //    }
    //}

    // 获取目标游戏窗口句柄
    //g_hWnd = FindWindowA("DNF Taiwan", "DNF Taiwan");
    g_hWnd = GetProcessMainWnd();
    //std::cout << g_hWnd << std::endl;
    // 创建D39设备对象
    g_Direct3D9 = Direct3DCreate9(D3D_SDK_VERSION);

    // 初始化参数结构体
    memset(&g_present, 0, sizeof(g_present));
    g_present.Windowed = TRUE;
    g_present.SwapEffect = D3DSWAPEFFECT_DISCARD;
    g_present.BackBufferFormat = D3DFMT_UNKNOWN;
    g_present.EnableAutoDepthStencil = TRUE;
    g_present.AutoDepthStencilFormat = D3DFMT_D16;


    // 创建d3d9设备标识
    HRESULT result = g_Direct3D9->CreateDevice(
        D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
        g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &g_present, &g_pd3dDevice
    );

    //// 开始hook对应的D3D9函数
    dDeviceVT = (DWORD*)*(DWORD*)g_pd3dDevice;
    oReset = (Reset_t)dDeviceVT[16];
    oBeginScene = (EndScene_t)dDeviceVT[41];
    oEndScene = (EndScene_t)dDeviceVT[42];

    Helpers::HookFunction((PVOID*)(&oReset), hkReset);
    //Helpers::HookFunction((PVOID*)(&oBeginScene), hkBeginScene);
    Helpers::HookFunction((PVOID*)(&oEndScene), hkEndScene);




}
