function InputManager() constructor {
    
    var _get_keyboard_key = function(_type, _id) {
        switch _type {
            case "status": return keyboard_check(_id);
            case "pressed": return keyboard_check_pressed(_id);
            case "released": return keyboard_check_released(_id);
        }
    }
    
    var _get_gamepad_button = function(_pad, _type, _id) {
        switch _type {
            case "status": return gamepad_button_check(_pad, _id);
            case "pressed": return gamepad_button_check_pressed(_pad, _id);
            case "released": return gamepad_button_check_released(_pad, _id);
        }
    }
    
    var _get_gamepad_axis = function(_pad, _type, _axis, _direction, _threshold) {
        switch _type {
            case "value": return gamepad_axis_value(_pad, _axis);
            case "status":
                return max(_get_gamepad_axis(_pad, "value", _axis) * _direction, 0) > _threshold;
            case "pressed":
                var _prev; try { _prev = _prev_axis[$ _pad][$ _axis][$ _direction]; } catch(e) { _prev = 0; };
                return !_prev && _get_gamepad_axis(_pad, "status", _axis, _direction, _threshold);
            case "released":
                var _prev; try { _prev = _prev_axis[$ _pad][$ _axis][$ _direction]; } catch(e) { _prev = 0; };
                return _prev && !_get_gamepad_axis(_pad, "status", _axis, _direction, _threshold);
        }
    }
    self._get_gamepad_axis = _get_gamepad_axis
    
    self._prev_axis = {};
    var end_step_update = function() {
        // Clear and recreate Prev
        _prev_axis = {};
        if (variable_global_exists("gamepads_list")) {
            var pads = global.gamepads_list;
            var pad_count = array_length(pads);
            for (var i = 0; i < pad_count; i++) {
                var _pad = pads[i];
                if (_prev_axis[$ _pad] == undefined) {
                    _prev_axis[$ _pad] = {};
                }
                
                var axes = [gp_axislh, gp_axislv, gp_axisrh, gp_axisrv];
                var axis_count = array_length(axes);
                for (var j = 0; j < axis_count; j++) {
                    var _axis = axes[j];
                    if (_prev_axis[$ _pad][$ _axis] == undefined) {
                        _prev_axis[$ _pad][$ _axis] = {};
                    }
                    
                    var dirs = [1, -1];
                    var dir_count = array_length(dirs);
                    for (var k = 0; k < dir_count; k++) {
                        var _direction = dirs[k];
                        _prev_axis[$ _pad][$ _axis][$ _direction] = _get_gamepad_axis(_pad, "status", _axis, _direction, 0.4);
                    }
                }
            }
        }
    };
    self.end_step_update = end_step_update;
}