#Requires AutoHotkey v2.0
#SingleInstance Force
CoordMode "Mouse", "Screen"

MsgBox "神陆逊试用版本！感谢测试用户反馈"

global GAME_TITLE := "王于兴师"
global CONFIG_FILE := A_ScriptDir "\positions.ini"
global ENABLED := true

; 窗口句柄 -> 槽位
global WINDOW_BINDINGS := Map()

; 3个槽位，每个槽位一套配置
global SLOT_DATA := []
Loop 3 {
    SLOT_DATA.Push({
        teams: [0, 0, 0, 0, 0], ; 1~5队相对客户区坐标
        exists: [false, false, false, false, false], ; 仅供参考显示
        dx: 0,
        dy: 0
    })
}

LoadProfiles()

; =========================
; 基础函数
; =========================

IsGameWindow(hwnd := 0) {
    global GAME_TITLE

    if !hwnd {
        hwnd := WinActive("A")
    }

    if !hwnd {
        return false
    }

    title := WinGetTitle("ahk_id " hwnd)
    return InStr(title, GAME_TITLE) > 0
}

GetGameHwnd() {
    hwnd := WinActive("A")
    if !IsGameWindow(hwnd) {
        return 0
    }
    return hwnd
}

GetClient(hwnd) {
    WinGetClientPos &x, &y, &w, &h, "ahk_id " hwnd
    return {x: x, y: y, w: w, h: h}
}

GetSlot() {
    global WINDOW_BINDINGS

    hwnd := GetGameHwnd()
    if !hwnd {
        return 0
    }

    if WINDOW_BINDINGS.Has(hwnd) {
        return WINDOW_BINDINGS[hwnd]
    }

    return 0
}

; =========================
; 窗口绑定
; =========================

BindWindow(slot) {
    global WINDOW_BINDINGS

    hwnd := GetGameHwnd()
    if !hwnd {
        MsgBox "请先点击《王于兴师》窗口，再按 F" slot
        return
    }

    WINDOW_BINDINGS[hwnd] := slot
    MsgBox "当前窗口已绑定到槽位 " slot
}

; =========================
; 标定队伍
; =========================

SetTeam(teamIndex) {
    global SLOT_DATA

    hwnd := GetGameHwnd()
    if !hwnd {
        MsgBox "请先激活《王于兴师》窗口"
        return
    }

    slot := GetSlot()
    if !slot {
        MsgBox "请先按 F1 / F2 / F3 绑定窗口"
        return
    }

    origin := GetClient(hwnd)
    MouseGetPos &mx, &my

    rel := {
        x: mx - origin.x,
        y: my - origin.y
    }

    SLOT_DATA[slot].teams[teamIndex] := rel

    if (teamIndex = 2) {
        if IsObject(SLOT_DATA[slot].teams[1]) {
            GenerateTeams(slot)
            SaveSlot(slot)
            MsgBox "已记录 2队，并自动生成 3/4/5 队"
        } else {
            SaveSlot(slot)
            MsgBox "已记录 2队"
        }
    } else {
        SaveSlot(slot)
        MsgBox "已记录 1队"
    }
}

GenerateTeams(slot) {
    global SLOT_DATA

    s := SLOT_DATA[slot]

    if !IsObject(s.teams[1]) {
        return
    }

    if !IsObject(s.teams[2]) {
        return
    }

    t1 := s.teams[1]
    t2 := s.teams[2]

    s.dx := t2.x - t1.x
    s.dy := t2.y - t1.y

    Loop 5 {
        i := A_Index
        if (i <= 2) {
            continue
        }

        s.teams[i] := {
            x: t1.x + s.dx * (i - 1),
            y: t1.y + s.dy * (i - 1)
        }
    }
}

; =========================
; 局部存在检测（仅供参考）
; 不再阻止拖拽
; =========================

ExistsAt(x, y) {
    colors := Map()
    bright := 0
    sampleCount := 0

    offsets := [-18, -9, 0, 9, 18]

    for ox in offsets {
        for oy in offsets {
            try {
                c := PixelGetColor(x + ox, y + oy, "RGB")
            } catch {
                continue
            }

            sampleCount += 1
            colors[c] := 1

            r := (c >> 16) & 255
            g := (c >> 8) & 255
            b := c & 255
            brightness := (r + g + b) / 3

            if (brightness > 22) {
                bright += 1
            }
        }
    }

    return (sampleCount >= 9 && colors.Count >= 3 && bright >= 3)
}

RefreshCurrentTeams() {
    global SLOT_DATA

    hwnd := GetGameHwnd()
    if !hwnd {
        MsgBox "请先激活《王于兴师》窗口"
        return
    }

    slot := GetSlot()
    if !slot {
        MsgBox "当前窗口未绑定槽位"
        return
    }

    origin := GetClient(hwnd)
    s := SLOT_DATA[slot]

    ; 1队、2队是手动标的，默认存在
    if IsObject(s.teams[1]) {
        s.exists[1] := true
    } else {
        s.exists[1] := false
    }

    if IsObject(s.teams[2]) {
        s.exists[2] := true
    } else {
        s.exists[2] := false
    }

    count := 0
    if s.exists[1] {
        count := 1
    }
    if s.exists[2] {
        count := 2
    }

    ; 顺序检测 3/4/5，仅做参考
    Loop 3 {
        i := A_Index + 2 ; 3,4,5

        if !IsObject(s.teams[i]) {
            s.exists[i] := false
            continue
        }

        if !s.exists[i - 1] {
            s.exists[i] := false
            continue
        }

        ax := origin.x + s.teams[i].x
        ay := origin.y + s.teams[i].y

        found := false

        testOffsets := [
            {x: 0, y: 0},
            {x: -12, y: 0},
            {x: 12, y: 0},
            {x: 0, y: -12},
            {x: 0, y: 12},
            {x: -8, y: -8},
            {x: 8, y: 8}
        ]

        for p in testOffsets {
            if ExistsAt(ax + p.x, ay + p.y) {
                found := true
                break
            }
        }

        s.exists[i] := found

        if found {
            count := i
        } else {
            Loop (5 - i) {
                s.exists[i + A_Index] := false
            }
            break
        }
    }

    MsgBox "检测完成：当前 " count " 队（仅供参考）"
}

; =========================
; 拖拽
; 只认坐标，不再被 exists 卡住
; =========================

DragTeam(teamIndex) {
    global ENABLED, SLOT_DATA

    if !ENABLED {
        return
    }

    hwnd := GetGameHwnd()
    if !hwnd {
        return
    }

    slot := GetSlot()
    if !slot {
        TrayTip "提示", "当前窗口未绑定槽位", 1000
        return
    }

    s := SLOT_DATA[slot]

    if !IsObject(s.teams[1]) || !IsObject(s.teams[2]) {
        TrayTip "提示", "请先用 Ctrl+1 和 Ctrl+2 标定", 1000
        return
    }

    if !IsObject(s.teams[teamIndex]) {
        TrayTip "提示", "第" teamIndex "队坐标不存在", 1000
        return
    }

    origin := GetClient(hwnd)
    pos := s.teams[teamIndex]

    sx := origin.x + pos.x
    sy := origin.y + pos.y

    MouseGetPos &tx, &ty

    MouseMove sx, sy, 5
    Sleep 80
    Send "{LButton down}"
    Sleep 80
    MouseMove tx, ty, 15
    Sleep 80
    Send "{LButton up}"
}

; =========================
; 保存 / 读取
; =========================

SaveSlot(slot) {
    global SLOT_DATA, CONFIG_FILE

    s := SLOT_DATA[slot]

    if IsObject(s.teams[1]) {
        IniWrite s.teams[1].x, CONFIG_FILE, "Slot" slot, "x1"
        IniWrite s.teams[1].y, CONFIG_FILE, "Slot" slot, "y1"
    } else {
        IniWrite 0, CONFIG_FILE, "Slot" slot, "x1"
        IniWrite 0, CONFIG_FILE, "Slot" slot, "y1"
    }

    if IsObject(s.teams[2]) {
        IniWrite s.teams[2].x, CONFIG_FILE, "Slot" slot, "x2"
        IniWrite s.teams[2].y, CONFIG_FILE, "Slot" slot, "y2"
    } else {
        IniWrite 0, CONFIG_FILE, "Slot" slot, "x2"
        IniWrite 0, CONFIG_FILE, "Slot" slot, "y2"
    }
}

LoadProfiles() {
    global SLOT_DATA, CONFIG_FILE

    Loop 3 {
        slot := A_Index

        x1 := Integer(IniRead(CONFIG_FILE, "Slot" slot, "x1", "0"))
        y1 := Integer(IniRead(CONFIG_FILE, "Slot" slot, "y1", "0"))
        x2 := Integer(IniRead(CONFIG_FILE, "Slot" slot, "x2", "0"))
        y2 := Integer(IniRead(CONFIG_FILE, "Slot" slot, "y2", "0"))

        if (x1 != 0 || y1 != 0) {
            SLOT_DATA[slot].teams[1] := {x: x1, y: y1}
        }

        if (x2 != 0 || y2 != 0) {
            SLOT_DATA[slot].teams[2] := {x: x2, y: y2}
        }

        if IsObject(SLOT_DATA[slot].teams[1]) && IsObject(SLOT_DATA[slot].teams[2]) {
            GenerateTeams(slot)
        }
    }
}

; =========================
; 调试 / 工具
; =========================

ShowStatus() {
    global SLOT_DATA

    slot := GetSlot()
    if !slot {
        MsgBox "当前窗口未绑定槽位"
        return
    }

    s := SLOT_DATA[slot]
    txt := "当前槽位：" slot "`n`n"

    Loop 5 {
        i := A_Index
        if IsObject(s.teams[i]) {
            txt .= i "队 坐标=(" s.teams[i].x ", " s.teams[i].y ")  存在=" (s.exists[i] ? "是" : "否") "`n"
        } else {
            txt .= i "队 未设置`n"
        }
    }

    MsgBox txt
}

ClearCurrentSlot() {
    global SLOT_DATA, CONFIG_FILE

    slot := GetSlot()
    if !slot {
        MsgBox "当前窗口未绑定槽位"
        return
    }

    SLOT_DATA[slot] := {
        teams: [0, 0, 0, 0, 0],
        exists: [false, false, false, false, false],
        dx: 0,
        dy: 0
    }

    IniWrite 0, CONFIG_FILE, "Slot" slot, "x1"
    IniWrite 0, CONFIG_FILE, "Slot" slot, "y1"
    IniWrite 0, CONFIG_FILE, "Slot" slot, "x2"
    IniWrite 0, CONFIG_FILE, "Slot" slot, "y2"

    MsgBox "当前槽位已清空"
}

; =========================
; 快捷键
; =========================

F1::BindWindow(1)
F2::BindWindow(2)
F3::BindWindow(3)

^1::SetTeam(1)
^2::SetTeam(2)

9::RefreshCurrentTeams()

1::DragTeam(1)
2::DragTeam(2)
3::DragTeam(3)
4::DragTeam(4)
5::DragTeam(5)

^9::ShowStatus()
^0::ClearCurrentSlot()

F5::{
    global ENABLED
    ENABLED := !ENABLED
    TrayTip "状态", ENABLED ? "开启" : "关闭", 1000
}

F8::{
    MsgBox "脚本正在运行"
}