#include <iostream>
#include <windows.h>
#include <iomanip>
#include <vector>
#include <string>
#include <cwchar>
#include <sstream>
#include <locale>
#include <chrono>
#include <thread>
#include <cmath>
#include <stdexcept>
#include <cstdio>
#include <memory>
#include <array>

using namespace std;

float dpi = -1;

//坐标结构体
struct Coord {
    int x;
    int y;
};

//获取DPI缩放比例
float GetDPIScale() {
    // 方法1：使用GetDpiForWindow（Windows 10 1607+）
    static float cachedScale = 0.0f;
    
    if (cachedScale == 0.0f) {
        HMODULE hUser32 = LoadLibraryW(L"user32.dll");
        if (hUser32) {
            typedef UINT(WINAPI* GetDpiForWindowFunc)(HWND);
            GetDpiForWindowFunc pGetDpiForWindow = 
                (GetDpiForWindowFunc)GetProcAddress(hUser32, "GetDpiForWindow");
            
            if (pGetDpiForWindow) {
                // 获取主窗口的DPI
                UINT dpi = pGetDpiForWindow(GetDesktopWindow());
                if (dpi > 0) {
                    cachedScale = static_cast<float>(dpi) / 96.0f;
                    FreeLibrary(hUser32);
                    return cachedScale;
                }
            }
            FreeLibrary(hUser32);
        }
        
        // 方法2：使用SystemParametersInfo
        HDC hdc = GetDC(NULL);
        if (hdc) {
            // 获取真实的DPI
            int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
            ReleaseDC(NULL, hdc);
            
            // 系统可能返回96（虚拟化DPI），所以需要进一步验证
            if (dpiX > 96) {
                cachedScale = static_cast<float>(dpiX) / 96.0f;
                return cachedScale;
            }
        }
        
        // 方法3：检查注册表（作为后备）
        HKEY hKey;
        if (RegOpenKeyExW(HKEY_CURRENT_USER, 
                        L"Control Panel\\Desktop\\WindowMetrics", 
                        0, KEY_READ, &hKey) == ERROR_SUCCESS) {
            DWORD value;
            DWORD size = sizeof(DWORD);
            
            // 检查AppliedDPI设置
            if (RegQueryValueExW(hKey, L"AppliedDPI", NULL, NULL, 
                               (LPBYTE)&value, &size) == ERROR_SUCCESS) {
                cachedScale = static_cast<float>(value) / 96.0f;
            } else {
                // 默认回退值
                cachedScale = 1.0f;
            }
            RegCloseKey(hKey);
        } else {
            cachedScale = 1.0f;
        }
    }
    
    return cachedScale;
}

//根据DPI将逻辑坐标转为绝对坐标
int dx(int x){
    return x*dpi;
}
int dy(int y){
    return y*dpi;
}

//根据DPI将绝对坐标转为逻辑坐标
int lx(int x){
    return x/dpi;
}
int ly(int y){
    return y/dpi;
}

//移动鼠标到指定位置
void MoveMouseTo(int x, int y) {
    SetCursorPos(lx(x), ly(y));
    cout<<"[INFO]模拟鼠标移动成功\n\n";
}

//模拟鼠标左键点击
void SimulateMouseClick() {
    INPUT inputs[2] = {};
    inputs[0].type = INPUT_MOUSE;
    inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    inputs[1].type = INPUT_MOUSE;
    inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(2, inputs, sizeof(INPUT));
    cout<<"[INFO]模拟点击成功\n\n";
}

//模拟鼠标左键按下
void MouseLeftDown() {
    INPUT input = {};
    input.type = INPUT_MOUSE;
    input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    SendInput(1, &input, sizeof(INPUT));
    cout<<"[INFO]模拟鼠标按下成功\n\n";
}

//模拟鼠标左键抬起
void MouseLeftUp() {
    INPUT input = {};
    input.type = INPUT_MOUSE;
    input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(1, &input, sizeof(INPUT));
    cout<<"[INFO]模拟鼠标抬起成功\n\n";
}

//获取鼠标当前坐标
Coord GetCurrentMouseCoord() {
    POINT pt;
    GetCursorPos(&pt);
    Coord result;
    result.x = dx(pt.x);
    result.y = dy(pt.y);
    return result;
}

//模拟单个按键
void SimulateKeyPress(WORD vkCode, bool extended = false) {
    INPUT inputs[2] = {};
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = vkCode;
    inputs[0].ki.dwFlags = (extended ? KEYEVENTF_EXTENDEDKEY : 0);
    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.wVk = vkCode;
    inputs[1].ki.dwFlags = KEYEVENTF_KEYUP | (extended ? KEYEVENTF_EXTENDEDKEY : 0);
    SendInput(2, inputs, sizeof(INPUT));
}

//模拟组合键
void SimulateHotkey(WORD vk1, WORD vk2) {
    INPUT inputs[4] = {};
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = vk1;
    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.wVk = vk2;
    inputs[2].type = INPUT_KEYBOARD;
    inputs[2].ki.wVk = vk2;
    inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
    inputs[3].type = INPUT_KEYBOARD;
    inputs[3].ki.wVk = vk1;
    inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(4, inputs, sizeof(INPUT));
}

//模拟输入字符串
void TypeString(const string& text) {
    for (size_t i = 0; i < text.length(); i++) {
        INPUT inputs[2] = {};
        BYTE ch = text[i];  // 使用 BYTE 而不是 WORD
        
        inputs[0].type = INPUT_KEYBOARD;
        inputs[0].ki.wVk = 0;  // 虚拟键码设为 0
        inputs[0].ki.dwFlags = KEYEVENTF_UNICODE;
        inputs[0].ki.wScan = ch;  // 使用 ASCII 码
        
        inputs[1].type = INPUT_KEYBOARD;
        inputs[1].ki.wVk = 0;
        inputs[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
        inputs[1].ki.wScan = ch;
        
        SendInput(2, inputs, sizeof(INPUT));
        Sleep(20);
    }
}

//计算偏移坐标
Coord calculateOffsetCoord(int x, int y, int angle, double distance) {
    double radians = angle * 3.14159265358979323846 / 180.0;
    double dx = distance * sin(radians);
    double dy = distance * cos(radians);
    Coord result;
    result.x = static_cast<int>(round(x + dx));
    result.y = static_cast<int>(round(y - dy));
    return result;
}

//执行命令并读取命令输出
bool readCommandOutput(const string& command) {
    string message;
    int code;
    FILE* pipe = _popen((command + " 2>&1").c_str(), "r");
    if (!pipe) {
        message="错误：无法执行命令";
    }
    array<char, 128> buffer;
    string result;
    while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
        message=buffer.data();
    }
    code = _pclose(pipe);
    cout<<"[INFO]控制台响应信息："<<message <<"\n"<<"[INFO]控制台响应代码："<<code<<"\n\n";
    if(code!=0){
        cout<<"[ERROR]控制台响应代码错误\n\n";
        return false;
    }
    return true;
}

//提取字符之间内容
string extractBetweenChars(const string& str, char startChar, char endChar) {
    size_t startPos = str.find(startChar);
    if (startPos == string::npos) {
        return "";
    }
    
    size_t endPos;
    if (startChar == endChar) {
        endPos = str.find(endChar, startPos + 1);
    } else {
        endPos = str.find(endChar, startPos + 1);
    }
    
    if (endPos == string::npos) {
        return "";
    }
    
    return str.substr(startPos + 1, endPos - startPos - 1);
}

int main(){
    system("chcp 65001");   //防止控制台乱码
    cout<<"\n自动画图程序\n小满工作室制作 侵权必究\n© 2026 小满工作室. All rights reserved.\n";
    cout<<"------------------\n\n";
    cout<<"[INFO]正在识别DPI缩放比例...\n\n";
    dpi=GetDPIScale();
    cout<<"您的DPI："<<fixed<<setprecision(2)<<dpi<<"("<<fixed<<setprecision(0)<<dpi*100<<"%)\n\n";

    cout<<"[INFO]尝试打开画图应用...\n若打开了画图应用 请手动关闭以继续运行\n\n";
    bool startP = readCommandOutput("start mspaint");
    if(!startP){
        cout<<"[ERROR]无法打开画图应用\n\n";
        cout<<"[ERROR]程序错误结束 退出码：2 请参阅官方文档\n\n";
        cout<<"------------------\n";
        cout<<"防止窗口直接退出 请按任意键继续\n";
        system("pause");
        return 2;
    }
    cout<<"画图应用可以被正常打开\n\n";

    cout<<"[INFO]正在正式打开画图应用...\n\n";
    system("start /max mspaint");
    cout<<"请待画图应用完全打开后按任意键继续\n";
    system("pause");
    cout<<"\n";
    cout<<"请调整画布大小为全屏 应用最大化 并按任意键继续\n";
    system("pause");
    cout<<"\n";

    cout<<"[INFO]进入主函数\n\n";
    string passphrase;
    cout<<"请输入操作指令：";
    cin>>passphrase;
    //示例：MA-960&540&,D,MR-90*200&,MR-234*200&,MR-18*200&,MR-162*200&,MR-306*200&,U;
    cout<<"\n\n";
    try{
        vector<string> result;
        string current;
        for (char ch : passphrase) {
            if (ch == ',') {
                result.push_back(current);
                current.clear();
            }
            else if (ch == ';') {
                result.push_back(current);
                break;
            }
            else {
                current += ch;
            }
        }

        cout<<"[INFO]5s后开始根据指令执行操作\n";
        for(int i=5;i>=1;i--){
            cout<<"[INFO]倒计时："<<i<<"\n";
            Sleep(1000);
        }
        cout<<"\n";

        cout<<"[INFO]开始根据指令执行操作\n\n";
        for(int i=0;i<result.size();i++){
            cout<<"[INFO]执行操作["<<i+1<<"]："<<result[i]<<"\n\n";
            switch(result[i][0]){
                case 'D':
                    MouseLeftDown();
                    break;
                case 'U':
                    MouseLeftUp();
                    break; 
                case 'M':
                    switch(result[i][1]){
                        case 'A':
                            MoveMouseTo(stoi(extractBetweenChars(result[i],'-','&')),stoi(extractBetweenChars(result[i],'&','&')));
                            break;
                        case 'R':{
                            Coord coordStart = GetCurrentMouseCoord();
                            Coord coordEnd = calculateOffsetCoord(coordStart.x,coordStart.y,stoi(extractBetweenChars(result[i],'-','*')),stoi(extractBetweenChars(result[i],'*','&')));
                            MoveMouseTo(coordEnd.x,coordEnd.y);
                            break;
                        }
                        default:
                            cout<<"[ERROR]输入了未定义的指令\n\n";
                            cout<<"[ERROR]程序错误结束 退出码：3 请参阅官方文档";
                            cout<<"\n\n------------------\n";
                            cout<<"防止窗口直接退出 请按任意键继续\n";
                            system("pause");
                            return 3;
                            break;
                    break;
                    }
                    break;
                default:
                    cout<<"[ERROR]输入了未定义的指令\n\n";
                    cout<<"[ERROR]程序错误结束 退出码：3 请参阅官方文档";
                    cout<<"\n\n------------------\n";
                    cout<<"防止窗口直接退出 请按任意键继续\n";
                    system("pause");
                    return 3;
                    break;
            }
        }
        cout<<"[INFO]操作已全部执行完毕\n\n";
    }
    catch(...){
        cout<<"[ERROR]指令解析或调用函数时出现异常\n\n";
        cout<<"[ERROR]程序错误结束 退出码：1 请参阅官方文档";
        cout<<"\n\n------------------\n";
        cout<<"防止窗口直接退出 请按任意键继续\n";
        system("pause");
        return 1;
    }

    cout<<"------------------\n小满牛逼\n小满牛逼\n小满牛逼";

    cout<<"\n\n防止窗口直接退出 请按任意键继续\n";
    system("pause");   //防止直接退出
    return 0;
}