import ctypes
import ctypes.wintypes
from PIL import Image

user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32

# Find window of PID 43084
target_pid = 43084
found_hwnd = None

WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.wintypes.BOOL, ctypes.wintypes.HWND, ctypes.wintypes.LPARAM)

def enum_windows_callback(hwnd, lparam):
    global found_hwnd
    if user32.IsWindowVisible(hwnd):
        pid = ctypes.wintypes.DWORD()
        user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
        if pid.value == target_pid:
            length = user32.GetWindowTextLengthW(hwnd)
            buff = ctypes.create_unicode_buffer(length + 1)
            user32.GetWindowTextW(hwnd, buff, length + 1)
            if "Path of Exile" in buff.value:
                found_hwnd = hwnd
                return False
    return True

user32.EnumWindows(WNDENUMPROC(enum_windows_callback), 0)
print(f"Target HWND: {hex(found_hwnd) if found_hwnd else 'None'}")

if found_hwnd:
    # Bring to foreground to ensure rendered
    user32.ShowWindow(found_hwnd, 9) # SW_RESTORE
    user32.SetForegroundWindow(found_hwnd)
    
    rect = ctypes.wintypes.RECT()
    user32.GetWindowRect(found_hwnd, ctypes.byref(rect))
    w = rect.right - rect.left
    h = rect.bottom - rect.top
    print(f"Window Rect: ({rect.left}, {rect.top}, {rect.right}, {rect.bottom}) - Size: {w}x{h}")
    
    desk_dc = user32.GetDC(0)
    mem_dc = gdi32.CreateCompatibleDC(desk_dc)
    bmp = gdi32.CreateCompatibleBitmap(desk_dc, w, h)
    gdi32.SelectObject(mem_dc, bmp)
    
    SRCCOPY = 0x00CC0020
    gdi32.BitBlt(mem_dc, 0, 0, w, h, desk_dc, rect.left, rect.top, SRCCOPY)
    
    class BITMAPINFOHEADER(ctypes.Structure):
        _fields_ = [
            ('biSize', ctypes.wintypes.DWORD),
            ('biWidth', ctypes.wintypes.LONG),
            ('biHeight', ctypes.wintypes.LONG),
            ('biPlanes', ctypes.wintypes.WORD),
            ('biBitCount', ctypes.wintypes.WORD),
            ('biCompression', ctypes.wintypes.DWORD),
            ('biSizeImage', ctypes.wintypes.DWORD),
            ('biXPelsPerMeter', ctypes.wintypes.LONG),
            ('biYPelsPerMeter', ctypes.wintypes.LONG),
            ('biClrUsed', ctypes.wintypes.DWORD),
            ('biClrImportant', ctypes.wintypes.DWORD),
        ]
    bmi = BITMAPINFOHEADER()
    bmi.biSize = ctypes.sizeof(BITMAPINFOHEADER)
    bmi.biWidth = w
    bmi.biHeight = -h
    bmi.biPlanes = 1
    bmi.biBitCount = 32
    bmi.biCompression = 0
    buf = ctypes.create_string_buffer(w * h * 4)
    lines = gdi32.GetDIBits(mem_dc, bmp, 0, h, buf, ctypes.byref(bmi), 0)
    
    if lines > 0:
        img = Image.frombuffer("RGBA", (w, h), buf, "raw", "BGRA", 0, 1)
        img.save("captures/poe2_live_screen.png")
        print("Successfully captured captures/poe2_live_screen.png!")
        
        # Crop skillbar region (bottom right)
        # Usually skillbar is in the bottom right corner (from x = w - 600, y = h - 250)
        crop_box = (max(0, w - 650), max(0, h - 250), w, h)
        skillbar_img = img.crop(crop_box)
        skillbar_img.save("captures/poe2_skillbar_crop.png")
        print("Saved captures/poe2_skillbar_crop.png!")
        
        # Crop buffs region (top left or above skillbar)
        buff_box = (0, 0, min(w, 800), 200)
        buff_img = img.crop(buff_box)
        buff_img.save("captures/poe2_buffs_crop.png")
        print("Saved captures/poe2_buffs_crop.png!")
