local ____lualib = require("lualib_bundle")
local __TS__New = ____lualib.__TS__New
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
local __TS__ArraySome = ____lualib.__TS__ArraySome
local ____exports = {}
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local ButtonAction = ____isaac_2Dtypescript_2Ddefinitions.ButtonAction
local Controller = ____isaac_2Dtypescript_2Ddefinitions.Controller
local ControllerIndex = ____isaac_2Dtypescript_2Ddefinitions.ControllerIndex
local Keyboard = ____isaac_2Dtypescript_2Ddefinitions.Keyboard
local ____cachedEnumValues = require("cachedEnumValues")
local CONTROLLER_INDEX_VALUES = ____cachedEnumValues.CONTROLLER_INDEX_VALUES
local ____keyboardToStringMap = require("maps.keyboardToStringMap")
local KEYBOARD_TO_STRING_MAP = ____keyboardToStringMap.KEYBOARD_TO_STRING_MAP
local ____ReadonlySet = require("types.ReadonlySet")
local ReadonlySet = ____ReadonlySet.ReadonlySet
local ____string = require("functions.string")
local trimPrefix = ____string.trimPrefix
____exports.MODIFIER_KEYS = {
    Keyboard.LEFT_SHIFT,
    Keyboard.LEFT_CONTROL,
    Keyboard.LEFT_ALT,
    Keyboard.LEFT_SUPER,
    Keyboard.RIGHT_SHIFT,
    Keyboard.RIGHT_CONTROL,
    Keyboard.RIGHT_ALT,
    Keyboard.RIGHT_SUPER
}
____exports.MOVEMENT_BUTTON_ACTIONS = {ButtonAction.LEFT, ButtonAction.RIGHT, ButtonAction.UP, ButtonAction.DOWN}
____exports.MOVEMENT_BUTTON_ACTIONS_SET = __TS__New(ReadonlySet, ____exports.MOVEMENT_BUTTON_ACTIONS)
____exports.SHOOTING_BUTTON_ACTIONS = {ButtonAction.SHOOT_LEFT, ButtonAction.SHOOT_RIGHT, ButtonAction.SHOOT_UP, ButtonAction.SHOOT_DOWN}
____exports.SHOOTING_BUTTON_ACTIONS_SET = __TS__New(ReadonlySet, ____exports.SHOOTING_BUTTON_ACTIONS)
--- Helper function to get the enum name for the specified `Controller` value. Note that this will
-- trim off the "BUTTON_" prefix.
-- 
-- Returns undefined if the submitted controller value was not valid.
function ____exports.controllerToString(self, controller)
    local key = Controller[controller]
    if key == nil then
        return nil
    end
    return trimPrefix(nil, key, "BUTTON_")
end
--- Helper function to get the movement actions that the specified `ControllerIndex` is currently
-- pressing down. This returns an array because a player can be holding down more than one movement
-- key at a time.
function ____exports.getMoveButtonActions(self, controllerIndex)
    return __TS__ArrayFilter(
        ____exports.MOVEMENT_BUTTON_ACTIONS,
        function(____, buttonAction) return Input.IsActionPressed(buttonAction, controllerIndex) end
    )
end
--- Helper function to get the shooting actions that the specified `ControllerIndex` is currently
-- pressing down. This returns an array because a player can be holding down more than one shooting
-- key at a time.
function ____exports.getShootButtonActions(self, controllerIndex)
    return __TS__ArrayFilter(
        ____exports.SHOOTING_BUTTON_ACTIONS,
        function(____, buttonAction) return Input.IsActionPressed(buttonAction, controllerIndex) end
    )
end
--- Helper function to check if a player is pressing a specific button (i.e. holding it down).
-- 
-- This is a variadic version of `Input.IsActionPressed`, meaning that you can pass as many buttons
-- as you want to check for. This function will return true if any of the buttons are pressed.
function ____exports.isActionPressed(self, controllerIndex, ...)
    local buttonActions = {...}
    return __TS__ArraySome(
        buttonActions,
        function(____, buttonAction) return Input.IsActionPressed(buttonAction, controllerIndex) end
    )
end
--- Helper function to iterate over all inputs to determine if a specific button is pressed (i.e.
-- being held down).
-- 
-- This function is variadic, meaning you can pass as many buttons as you want to check for. This
-- function will return true if any of the buttons are pressed.
function ____exports.isActionPressedOnAnyInput(self, ...)
    local buttonActions = {...}
    return __TS__ArraySome(
        CONTROLLER_INDEX_VALUES,
        function(____, controllerIndex) return ____exports.isActionPressed(
            nil,
            controllerIndex,
            table.unpack(buttonActions)
        ) end
    )
end
--- Helper function to check if a player is triggering a specific button (i.e. pressing and releasing
-- it).
-- 
-- This is a variadic version of `Input.IsActionTriggered`, meaning that you can pass as many
-- buttons as you want to check for. This function will return true if any of the buttons are
-- triggered.
function ____exports.isActionTriggered(self, controllerIndex, ...)
    local buttonActions = {...}
    return __TS__ArraySome(
        buttonActions,
        function(____, buttonAction) return Input.IsActionTriggered(buttonAction, controllerIndex) end
    )
end
--- Iterates over all inputs to determine if a specific button is triggered (i.e. held down and then
-- released).
-- 
-- This function is variadic, meaning you can pass as many buttons as you want to check for. This
-- function will return true if any of the buttons are pressed.
function ____exports.isActionTriggeredOnAnyInput(self, ...)
    local buttonActions = {...}
    return __TS__ArraySome(
        CONTROLLER_INDEX_VALUES,
        function(____, controllerIndex) return ____exports.isActionTriggered(
            nil,
            controllerIndex,
            table.unpack(buttonActions)
        ) end
    )
end
--- Helper function to see if a specific keyboard key is being held down by the player.
-- 
-- This function is variadic, meaning you can pass as many keyboard values as you want to check for.
-- This function will return true if any of the values are pressed.
function ____exports.isKeyboardPressed(self, ...)
    local keys = {...}
    return __TS__ArraySome(
        keys,
        function(____, key) return Input.IsButtonPressed(key, ControllerIndex.KEYBOARD) end
    )
end
--- Helper function to check if one or more modifier keys are being pressed down on the keyboard.
-- 
-- A modifier key is defined as shift, control, alt, or Windows.
function ____exports.isModifierKeyPressed(self)
    return ____exports.isKeyboardPressed(
        nil,
        table.unpack(____exports.MODIFIER_KEYS)
    )
end
function ____exports.isMoveAction(self, buttonAction)
    return ____exports.MOVEMENT_BUTTON_ACTIONS_SET:has(buttonAction)
end
function ____exports.isMoveActionPressed(self, controllerIndex)
    return ____exports.isActionPressed(
        nil,
        controllerIndex,
        table.unpack(____exports.MOVEMENT_BUTTON_ACTIONS)
    )
end
function ____exports.isMoveActionPressedOnAnyInput(self)
    return __TS__ArraySome(
        ____exports.MOVEMENT_BUTTON_ACTIONS,
        function(____, moveAction) return ____exports.isActionPressedOnAnyInput(nil, moveAction) end
    )
end
function ____exports.isMoveActionTriggered(self, controllerIndex)
    return ____exports.isActionTriggered(
        nil,
        controllerIndex,
        table.unpack(____exports.MOVEMENT_BUTTON_ACTIONS)
    )
end
function ____exports.isMoveActionTriggeredOnAnyInput(self)
    return __TS__ArraySome(
        ____exports.MOVEMENT_BUTTON_ACTIONS,
        function(____, moveAction) return ____exports.isActionTriggeredOnAnyInput(nil, moveAction) end
    )
end
function ____exports.isShootAction(self, buttonAction)
    return ____exports.SHOOTING_BUTTON_ACTIONS_SET:has(buttonAction)
end
function ____exports.isShootActionPressed(self, controllerIndex)
    return ____exports.isActionPressed(
        nil,
        controllerIndex,
        table.unpack(____exports.SHOOTING_BUTTON_ACTIONS)
    )
end
function ____exports.isShootActionPressedOnAnyInput(self)
    return __TS__ArraySome(
        ____exports.SHOOTING_BUTTON_ACTIONS,
        function(____, shootAction) return ____exports.isActionPressedOnAnyInput(nil, shootAction) end
    )
end
function ____exports.isShootActionTriggered(self, controllerIndex)
    return ____exports.isActionTriggered(
        nil,
        controllerIndex,
        table.unpack(____exports.SHOOTING_BUTTON_ACTIONS)
    )
end
function ____exports.isShootActionTriggeredOnAnyInput(self)
    return __TS__ArraySome(
        ____exports.SHOOTING_BUTTON_ACTIONS,
        function(____, shootAction) return ____exports.isActionTriggeredOnAnyInput(nil, shootAction) end
    )
end
--- Helper function to get the string that would be typed if someone pressed the corresponding key.
-- This is useful for creating in-game chat.
-- 
-- Note that this function will only work for the keyboard values that are printable. Thus, it will
-- return undefined for e.g. `Keyboard.LEFT_SHIFT` (340). If all you want is the corresponding name
-- of the key, then simply use the enum reverse mapping (e.g. `Keyboard[keyboard]`).
function ____exports.keyboardToString(self, keyboard, uppercase)
    local tuple = KEYBOARD_TO_STRING_MAP:get(keyboard)
    if tuple == nil then
        return nil
    end
    local lowercaseCharacter, uppercaseCharacter = table.unpack(tuple, 1, 2)
    return uppercase and uppercaseCharacter or lowercaseCharacter
end
return ____exports
