;
; Functions for holding and repeating keys
;

_TurboOn := Map()

Hold(Primary, Secondary:=[],Tertiary:=[]) {
    Send "{Blind}{" Primary " down}"
    SetTimer HoldLoop.Bind(Primary,Secondary,Tertiary), 50
}

HoldLoop(Primary, Secondary, Tertiary) {
    if GetKeyState(Primary,"P") {
        SetTimer , 0
        return
    }
    for index,key in Secondary {
        if GetKeyState(key,"P") {
            Send "{Blind}{" Primary " up}"
            SetTimer , 0
            return
        }
    }
    keyHeld:=0
    for index,key in Tertiary {
        if GetKeyState(key,"P") {
            keyHeld:=1
            break
        }
    }
    if (!keyHeld) {
        Send "{Blind}{" Primary " up}"
        SetTimer , 0
        return
    }
}

Repeat(Primary, Secondary) {
    Send "{Blind}{" Primary " up}"
    Sleep 100
    RepeatVar := 0
    Loop {
        if GetKeyState(Primary,"P") {
            return
        }
        for index,key in Secondary {
            if GetKeyState(key,"P") {
                return
            }
        }
        if (RepeatVar == 1) {
            Send "{Blind}{" Primary " down}"
            RepeatVar := 0
        } else {
            Send "{Blind}{" Primary " down}"
            RepeatVar := 1
        }
        Sleep 100
    }
}

; Sets key to hold if single tap, or repeat if double tap
HoldOrRepeat(Primary, Secondary) {
    Send "{Blind}{" Primary " down}"
    if KeyWait(Primary, "D T0.2") {
        Repeat(Primary,Secondary)
    } else {
        Hold(Primary,Secondary)
    }
}

; Press Target button extremely rapidly while Hold button is held down
Turbo(Target,Hold:=Target) {
    global _TurboOn
    If (_TurboOn.Has(Target "_" Hold) and _TurboOn[Target "_" Hold]) {
        return
    } else {
        _TurboOn[Target "_" Hold]:=1
        While GetKeyState(Hold,"P") {
            Send "{Blind}{" Target " down}"
            Sleep 10
            Send "{Blind}{" Target " up}"
            Sleep 10
        }
        _TurboOn[Target "_" Hold]:=0
    }
}