-- MAME Controls Menu Plugin with F9 hotkey, Start+RB gamepad support, Precaching and Persistent Config
local exports = {}
exports.name = "controls"
exports.version = "0.7"
exports.description = "MAME Controls Display with Precaching, Persistent Config, and Lightning Mode"
exports.license = "MIT"
exports.author = { name = "Custom" }

--[[ 
CONTROLLER BUTTON MAPPING REFERENCE:

Xbox Controller / XINPUT Mapping:
  XINPUT_1_A            - A Button
  XINPUT_1_B            - B Button
  XINPUT_1_X            - X Button
  XINPUT_1_Y            - Y Button
  XINPUT_1_SHOULDER_L   - Left Bumper (LB)
  XINPUT_1_SHOULDER_R   - Right Bumper (RB)
  XINPUT_1_TRIGGER_L    - Left Trigger (LT)
  XINPUT_1_TRIGGER_R    - Right Trigger (RT)
  XINPUT_1_THUMB_L      - Left Stick Button (Press L3)
  XINPUT_1_THUMB_R      - Right Stick Button (Press R3)
  XINPUT_1_START        - Start Button
  XINPUT_1_SELECT       - Back/Select Button
  XINPUT_1_DPAD_UP      - D-Pad Up
  XINPUT_1_DPAD_DOWN    - D-Pad Down
  XINPUT_1_DPAD_LEFT    - D-Pad Left
  XINPUT_1_DPAD_RIGHT   - D-Pad Right

Generic Joystick / JOYCODE Mapping:
  JOYCODE_1_BUTTON1     - Usually A Button
  JOYCODE_1_BUTTON2     - Usually B Button
  JOYCODE_1_BUTTON3     - Usually X Button
  JOYCODE_1_BUTTON4     - Usually Y Button
  JOYCODE_1_BUTTON5     - Usually Left Bumper (LB)
  JOYCODE_1_BUTTON6     - Usually Right Bumper (RB)
  JOYCODE_1_BUTTON7     - Usually Left Trigger (LT)
  JOYCODE_1_BUTTON8     - Usually Right Trigger (RT)
  JOYCODE_1_BUTTON9     - Usually Left Stick Button (L3)
  JOYCODE_1_BUTTON10    - Usually Right Stick Button (R3)
  JOYCODE_1_BUTTON11    - Often Back/Select
  JOYCODE_1_BUTTON12    - Often Start
  JOYCODE_1_HATUP       - D-Pad Up
  JOYCODE_1_HATDOWN     - D-Pad Down
  JOYCODE_1_HATLEFT     - D-Pad Left
  JOYCODE_1_HATRIGHT    - D-Pad Right
  
For a different player's controller, change the number after JOYCODE or XINPUT.
Example: XINPUT_2_A or JOYCODE_2_BUTTON1 for player 2's controller.
]]

function exports.startplugin()
    -- Variables to track key state
    local single_key_pressed = false
    local hotkey1_pressed = false
    local hotkey2_pressed = false
    
    -- Cooldown variables to prevent immediate re-triggering
    local last_show_time = 0
    local cooldown_period = 1.0  -- 1 second cooldown
    local showing_controls = false
    
    -- Get the plugin directory for config file
    local function get_config_path()
        -- Try to get the plugin directory
        local plugin_path = "plugins/controls/"  -- Default fallback
        
        -- Alternative paths to try
        local possible_paths = {
            "plugins/controls/controls_config.cfg",
            "preview/controls_config.cfg",
            "controls_config.cfg"
        }
        
        -- Return the first path that works for writing
        for _, path in ipairs(possible_paths) do
            local test_file = io.open(path, "a")
            if test_file then
                test_file:close()
                return path
            end
        end
        
        -- Fallback to current directory
        return "controls_config.cfg"
    end
    
    local config_file_path = get_config_path()
    
    -- Default configuration - only assign what user explicitly sets
    local default_config = {
        single_assign = nil,     -- Single key/button assignment
        hotkey1 = nil,          -- Hotkey 1 assignment  
        hotkey2 = nil,          -- Hotkey 2 assignment
        show_on_pause = false,  -- Show controls when pausing MAME
        lightning_mode = false  -- NEW: Lightning Mode (faster image-only display) - defaults to Normal Mode
    }
    
    -- Configuration variables (will be loaded from file)
    local config = {}
    
    -- Function to save configuration to file
    local function save_config()
        local file = io.open(config_file_path, "w")
        if file then
            file:write("-- MAME Controls Plugin Configuration\n")
            file:write("-- This file is automatically generated\n")
            file:write("-- Set to 'nil' or remove line to disable that assignment\n")
            file:write("\n")
            file:write("single_assign=" .. (config.single_assign or "nil") .. "\n")
            file:write("hotkey1=" .. (config.hotkey1 or "nil") .. "\n")
            file:write("hotkey2=" .. (config.hotkey2 or "nil") .. "\n")
            file:write("show_on_pause=" .. tostring(config.show_on_pause or false) .. "\n")
            file:write("lightning_mode=" .. tostring(config.lightning_mode or false) .. "\n")
            file:close()
            print("Configuration saved to: " .. config_file_path)
            return true
        else
            print("Error: Could not save configuration to: " .. config_file_path)
            return false
        end
    end
    
    -- Function to load configuration from file
    local function load_config()
        -- Start with default configuration
        for key, value in pairs(default_config) do
            config[key] = value
        end
        
        local file = io.open(config_file_path, "r")
        if file then
            print("Loading configuration from: " .. config_file_path)
            for line in file:lines() do
                -- Skip comments and empty lines
                if not line:match("^%s*%-%-") and not line:match("^%s*$") then
                    local key, value = line:match("^([^=]+)=(.+)$")
                    if key and value then
                        key = key:gsub("%s+", "")  -- Remove whitespace
                        value = value:gsub("%s+", "")  -- Remove whitespace
                        
                        -- Don't set if value is "nil"
                        if value ~= "nil" then
                            if key == "show_on_pause" or key == "lightning_mode" then
                                config[key] = (value:lower() == "true")
                            else
                                config[key] = value
                            end
                            print("Loaded config: " .. key .. " = " .. tostring(config[key]))
                        end
                    end
                end
            end
            file:close()
        else
            print("No configuration file found, using defaults")
            print("Config file will be created at: " .. config_file_path)
            -- Save default configuration
            save_config()
        end
    end
    
    -- Load configuration on startup
    load_config()
    
    -- Menu state
    local menu_state = "main" -- "main", "config", "select_single", "select_hotkey1", "select_hotkey2"
    local selection_index = 1
    
    -- Precaching variables (from working older version)
    local user_paused = false
    local current_rom = nil
    local rom_precached = false
    local has_timer = (emu.timer ~= nil)
    
    -- Print plugin initialization info
    print("Controls plugin initializing...")
    print("Timer functionality available: " .. tostring(has_timer))
    print("Single Assignment: " .. (config.single_assign or "None"))
    print("Hotkey 1: " .. (config.hotkey1 or "None"))
    print("Hotkey 2: " .. (config.hotkey2 or "None"))
    print("Show on Pause: " .. tostring(config.show_on_pause))
    print("Lightning Mode: " .. tostring(config.lightning_mode))
    
    -- Precaching function (adapted from working older version)
    local function precache_controls(game_name)
        if not game_name or game_name == "" or game_name == "___empty" then
            print("No valid ROM name available, skipping precache")
            return 
        end
        
        -- Skip if already precached
        if current_rom == game_name and rom_precached then 
            print("ROM already precached: " .. game_name)
            return 
        end
        
        -- Log to file for debugging
        os.execute("echo Game detected: " .. game_name .. " > C:\\mame_plugin_log.txt")
        
        -- Use the precache option to load data in background (updated path and executable)
        local command = string.format('"preview\\mame controls.exe" --precache --game %s', game_name)
        print("Pre-caching controls for: " .. game_name)
        
        -- Try to run the precache command
        local result = os.execute(command)
        if result then
            -- Mark as precached
            current_rom = game_name
            rom_precached = true
            print("Precaching complete for: " .. game_name)
        else
            print("Precaching failed for: " .. game_name)
        end
    end

    -- Function to show controls (with cooldown protection and Lightning Mode support)
    local function show_controls()
        -- Get current time (approximate)
        local current_time = os.clock()
        
        -- Check cooldown period
        if current_time - last_show_time < cooldown_period then
            print("Controls cooldown active, ignoring request")
            return
        end
        
        -- Check if already showing controls
        if showing_controls then
            print("Controls already showing, ignoring request")
            return
        end
        
        -- Get the ROM name
        local game_name = emu.romname()

        -- Only proceed if we have a valid game name
        if game_name and game_name ~= "" and game_name ~= "___empty" then
            print("Showing controls for: " .. game_name .. " (Lightning Mode: " .. tostring(config.lightning_mode) .. ")")
            showing_controls = true
            last_show_time = current_time
            
            -- Pause MAME if the function exists
            if emu.pause then
                emu.pause()
            end
            
            -- Choose command based on Lightning Mode setting
            local command
            if config.lightning_mode then
                -- Lightning Mode: Fast image-only display
                command = string.format('"preview\\mame controls.exe" --image-only --game %s', game_name)
                -- command = string.format('python "preview\\mame_controls_main.py" --image-only --game %s', game_name)
                print("Using Lightning Mode (fast image-only)")
            else
                -- Normal Mode: Full preview with screen selection
                command = string.format('"preview\\mame controls.exe" --preview-only --game %s --clean-preview --screen 1', game_name)
                -- command = string.format('python "preview\\mame_controls_main.py" --preview-only --game %s --clean-preview --screen 1', game_name)
                print("Using Normal Mode (full preview)")
            end
            
            print("Running: " .. command)
            os.execute(command)
            
            -- Reset showing flag after command completes
            showing_controls = false
            
            -- Unpause MAME if it was paused by the user
            if user_paused and emu.unpause then
                print("Unpausing MAME after controls")
                emu.unpause()
                user_paused = false
            elseif emu.unpause then
                emu.unpause()
            end
        else
            print("No valid ROM name available, cannot show controls")
        end
    end

    -- Function to format key display name
    local function format_key_name(key)
        if not key then return "None" end
        local name = key:gsub("KEYCODE_", ""):gsub("JOYCODE_1_", "")
        return name
    end

    -- Menu system with scrollable key selection
    local function menu_populate()
        local menu = {}
        local game_name = emu.romname()
        
        if menu_state == "main" then
            if game_name and game_name ~= "" and game_name ~= "___empty" then
                menu[1] = {"Show Controls for " .. game_name, "", 0}
                menu[2] = {"Configure Settings", "", 0}
                menu[3] = {"", "", "off"}  -- Separator
                menu[4] = {"Current Settings:", "", "off"}
                menu[5] = {"  Single Assign: " .. format_key_name(config.single_assign), "", "off"}
                menu[6] = {"  Hotkey 1: " .. format_key_name(config.hotkey1), "", "off"}
                menu[7] = {"  Hotkey 2: " .. format_key_name(config.hotkey2), "", "off"}
                menu[8] = {"  Show on Pause: " .. (config.show_on_pause and "Enabled" or "Disabled"), "", "off"}
                menu[9] = {"  Lightning Mode: " .. (config.lightning_mode and "Enabled" or "Disabled"), "", "off"}
                menu[10] = {"", "", "off"}  -- Separator
                menu[11] = {"Lightning Mode: Fast image-only display", "", "off"}
                menu[12] = {"Normal Mode: Full preview with options", "", "off"}
                menu[13] = {"", "", "off"}  -- Separator
                menu[14] = {"Exit Controls: Any Keyboard or XINPUT Key", "", "off"}
            else
                menu[1] = {"Show Controls (No ROM loaded)", "", 0}
                menu[2] = {"Configure Settings", "", 0}
                menu[3] = {"", "", "off"}  -- Separator
                menu[4] = {"Current Settings:", "", "off"}
                menu[5] = {"  Single Assign: " .. format_key_name(config.single_assign), "", "off"}
                menu[6] = {"  Hotkey 1: " .. format_key_name(config.hotkey1), "", "off"}
                menu[7] = {"  Hotkey 2: " .. format_key_name(config.hotkey2), "", "off"}
                menu[8] = {"  Show on Pause: " .. (config.show_on_pause and "Enabled" or "Disabled"), "", "off"}
                menu[9] = {"  Lightning Mode: " .. (config.lightning_mode and "Enabled" or "Disabled"), "", "off"}
                menu[10] = {"", "", "off"}  -- Separator
                menu[11] = {"Lightning Mode: Fast image-only display", "", "off"}
                menu[12] = {"Normal Mode: Full preview with options", "", "off"}
                menu[13] = {"", "", "off"}  -- Separator
                menu[14] = {"Exit Controls: Any Keyboard or XINPUT Key", "", "off"}
            end
        elseif menu_state == "config" then
            menu[1] = {"← Back to Main Menu", "", 0}
            menu[2] = {"", "", "off"}  -- Separator
            menu[3] = {"Current Settings:", "", "off"}
            menu[4] = {"  Single Assign: " .. format_key_name(config.single_assign), "", "off"}
            menu[5] = {"  Hotkey 1: " .. format_key_name(config.hotkey1), "", "off"}
            menu[6] = {"  Hotkey 2: " .. format_key_name(config.hotkey2), "", "off"}
            menu[7] = {"  Show on Pause: " .. (config.show_on_pause and "Enabled" or "Disabled"), "", "off"}
            menu[8] = {"  Lightning Mode: " .. (config.lightning_mode and "Enabled" or "Disabled"), "", "off"}
            menu[9] = {"", "", "off"}  -- Separator
            menu[10] = {"Change Single Assign", "", 0}
            menu[11] = {"Change Hotkey 1", "", 0}
            menu[12] = {"Change Hotkey 2", "", 0}
            menu[13] = {"Toggle Show on Pause", "", 0}
            menu[14] = {"Toggle Lightning Mode", "", 0}
            menu[15] = {"", "", "off"}  -- Separator
            menu[16] = {"Clear Single Assign", "", 0}
            menu[17] = {"Clear Hotkey 1", "", 0}
            menu[18] = {"Clear Hotkey 2", "", 0}
            menu[19] = {"Clear All Assignments", "", 0}
        elseif menu_state == "select_single" or menu_state == "select_hotkey1" or menu_state == "select_hotkey2" then
            menu[1] = {"← Back", "", 0}
            menu[2] = {"", "", "off"}
            menu[3] = {"Select Key or Button (Scrollable):", "", "off"}
            
            -- Comprehensive list of gamepad buttons first, then keyboard keys
            local all_options = {
                -- GAMEPAD BUTTONS FIRST (using correct MAME naming)
                {"Button 1 (A)", "JOYCODE_1_BUTTON1"}, 
                {"Button 2 (B)", "JOYCODE_1_BUTTON2"},
                {"Button 3 (X)", "JOYCODE_1_BUTTON3"}, 
                {"Button 4 (Y)", "JOYCODE_1_BUTTON4"},
                {"Button 5 (LB)", "JOYCODE_1_BUTTON5"}, 
                {"Button 6 (RB)", "JOYCODE_1_BUTTON6"},
                {"Button 7 (LT)", "JOYCODE_1_BUTTON7"}, 
                {"Button 8 (RT)", "JOYCODE_1_BUTTON8"},
                {"Button 9 (L3)", "JOYCODE_1_BUTTON9"}, 
                {"Button 10 (R3)", "JOYCODE_1_BUTTON10"},
                {"Button 11", "JOYCODE_1_BUTTON11"}, 
                {"Button 12", "JOYCODE_1_BUTTON12"},
                
                -- Modern MAME button names (correct naming)
                {"Select Button", "JOYCODE_1_SELECT"}, 
                {"Start Button", "JOYCODE_1_START"},
                
                -- D-Pad (both modern and legacy naming)
                {"D-Pad Up (HAT1)", "JOYCODE_1_HAT1UP"}, 
                {"D-Pad Down (HAT1)", "JOYCODE_1_HAT1DOWN"},
                {"D-Pad Left (HAT1)", "JOYCODE_1_HAT1LEFT"}, 
                {"D-Pad Right (HAT1)", "JOYCODE_1_HAT1RIGHT"},
                {"D-Pad Up (Legacy)", "JOYCODE_1_HATUP"}, 
                {"D-Pad Down (Legacy)", "JOYCODE_1_HATDOWN"},
                {"D-Pad Left (Legacy)", "JOYCODE_1_HATLEFT"}, 
                {"D-Pad Right (Legacy)", "JOYCODE_1_HATRIGHT"},
                
                -- Sliders/Triggers (modern naming)
                {"Slider 1 (LT)", "JOYCODE_1_SLIDER1"}, 
                {"Slider 2 (RT)", "JOYCODE_1_SLIDER2"},
                {"Slider 1 Neg", "JOYCODE_1_SLIDER1_NEG_SWITCH"}, 
                {"Slider 2 Neg", "JOYCODE_1_SLIDER2_NEG_SWITCH"},
                {"Slider 2 Pos", "JOYCODE_1_SLIDER2_POS_SWITCH"},
                
                -- Analog stick axes
                {"Y-Axis Up", "JOYCODE_1_YAXIS_UP_SWITCH"}, 
                {"Y-Axis Down", "JOYCODE_1_YAXIS_DOWN_SWITCH"},
                {"RX-Axis Left", "JOYCODE_1_RXAXIS_NEG_SWITCH"}, 
                {"RX-Axis Right", "JOYCODE_1_RXAXIS_POS_SWITCH"},
                {"RY-Axis Up", "JOYCODE_1_RYAXIS_NEG_SWITCH"}, 
                {"RY-Axis Down", "JOYCODE_1_RYAXIS_POS_SWITCH"},
                
                -- KEYBOARD KEYS SECOND
                {"F1", "KEYCODE_F1"}, {"F2", "KEYCODE_F2"}, {"F3", "KEYCODE_F3"}, {"F4", "KEYCODE_F4"},
                {"F5", "KEYCODE_F5"}, {"F6", "KEYCODE_F6"}, {"F7", "KEYCODE_F7"}, {"F8", "KEYCODE_F8"},
                {"F9", "KEYCODE_F9"}, {"F10", "KEYCODE_F10"}, {"F11", "KEYCODE_F11"}, {"F12", "KEYCODE_F12"},
                {"Space", "KEYCODE_SPACE"}, {"Enter", "KEYCODE_ENTER"}, {"Tab", "KEYCODE_TAB"},
                {"Escape", "KEYCODE_ESC"}, {"Backspace", "KEYCODE_BACKSPACE"},
                {"A", "KEYCODE_A"}, {"B", "KEYCODE_B"}, {"C", "KEYCODE_C"}, {"D", "KEYCODE_D"},
                {"E", "KEYCODE_E"}, {"F", "KEYCODE_F"}, {"G", "KEYCODE_G"}, {"H", "KEYCODE_H"},
                {"I", "KEYCODE_I"}, {"J", "KEYCODE_J"}, {"K", "KEYCODE_K"}, {"L", "KEYCODE_L"},
                {"M", "KEYCODE_M"}, {"N", "KEYCODE_N"}, {"O", "KEYCODE_O"}, {"P", "KEYCODE_P"},
                {"Q", "KEYCODE_Q"}, {"R", "KEYCODE_R"}, {"S", "KEYCODE_S"}, {"T", "KEYCODE_T"},
                {"U", "KEYCODE_U"}, {"V", "KEYCODE_V"}, {"W", "KEYCODE_W"}, {"X", "KEYCODE_X"},
                {"Y", "KEYCODE_Y"}, {"Z", "KEYCODE_Z"},
                {"0", "KEYCODE_0"}, {"1", "KEYCODE_1"}, {"2", "KEYCODE_2"}, {"3", "KEYCODE_3"},
                {"4", "KEYCODE_4"}, {"5", "KEYCODE_5"}, {"6", "KEYCODE_6"}, {"7", "KEYCODE_7"},
                {"8", "KEYCODE_8"}, {"9", "KEYCODE_9"},
                {"Left Shift", "KEYCODE_LSHIFT"}, {"Right Shift", "KEYCODE_RSHIFT"},
                {"Left Ctrl", "KEYCODE_LCONTROL"}, {"Right Ctrl", "KEYCODE_RCONTROL"},
                {"Left Alt", "KEYCODE_LALT"}, {"Right Alt", "KEYCODE_RALT"},
                {"Insert", "KEYCODE_INSERT"}, {"Delete", "KEYCODE_DEL"},
                {"Home", "KEYCODE_HOME"}, {"End", "KEYCODE_END"},
                {"Page Up", "KEYCODE_PGUP"}, {"Page Down", "KEYCODE_PGDN"},
                {"Arrow Up", "KEYCODE_UP"}, {"Arrow Down", "KEYCODE_DOWN"},
                {"Arrow Left", "KEYCODE_LEFT"}, {"Arrow Right", "KEYCODE_RIGHT"},
                {"Comma", "KEYCODE_COMMA"}, {"Period", "KEYCODE_STOP"},
                {"Semicolon", "KEYCODE_COLON"}, {"Quote", "KEYCODE_QUOTE"},
                {"Left Bracket", "KEYCODE_OPENBRACE"}, {"Right Bracket", "KEYCODE_CLOSEBRACE"},
                {"Backslash", "KEYCODE_BACKSLASH"}, {"Slash", "KEYCODE_SLASH"},
                {"Minus", "KEYCODE_MINUS"}, {"Equals", "KEYCODE_EQUALS"},
                {"Tilde", "KEYCODE_TILDE"}
            }
            
            for i, option in ipairs(all_options) do
                menu[i + 3] = {option[1], option[2], 0}
            end
        end
        
        return menu
    end

    -- Menu callback
    local function menu_callback(index, event)
        if event == "select" then
            if menu_state == "main" then
                if index == 1 then
                    -- Show controls
                    local game_name = emu.romname()
                    if game_name and game_name ~= "" and game_name ~= "___empty" then
                        show_controls()
                        return true
                    else
                        print("No ROM is currently loaded, cannot show controls")
                        return false
                    end
                elseif index == 2 then
                    -- Configure Settings
                    menu_state = "config"
                    return true
                end
            elseif menu_state == "config" then
                if index == 1 then
                    -- Back to main menu
                    menu_state = "main"
                    return true
                elseif index == 10 then
                    -- Change Single Assign
                    menu_state = "select_single"
                    return true
                elseif index == 11 then
                    -- Change Hotkey 1
                    menu_state = "select_hotkey1"
                    return true
                elseif index == 12 then
                    -- Change Hotkey 2
                    menu_state = "select_hotkey2"
                    return true
                elseif index == 13 then
                    -- Toggle Show on Pause
                    config.show_on_pause = not config.show_on_pause
                    print("Show on Pause: " .. (config.show_on_pause and "Enabled" or "Disabled"))
                    save_config()
                    return true
                elseif index == 14 then
                    -- Toggle Lightning Mode
                    config.lightning_mode = not config.lightning_mode
                    print("Lightning Mode: " .. (config.lightning_mode and "Enabled" or "Disabled"))
                    if config.lightning_mode then
                        print("  → Using fast image-only display")
                    else
                        print("  → Using full preview with options")
                    end
                    save_config()
                    return true
                elseif index == 16 then
                    -- Clear Single Assign
                    config.single_assign = nil
                    print("Single assignment cleared")
                    save_config()
                    return true
                elseif index == 17 then
                    -- Clear Hotkey 1
                    config.hotkey1 = nil
                    print("Hotkey 1 cleared")
                    save_config()
                    return true
                elseif index == 18 then
                    -- Clear Hotkey 2
                    config.hotkey2 = nil
                    print("Hotkey 2 cleared")
                    save_config()
                    return true
                elseif index == 19 then
                    -- Clear All Assignments
                    config.single_assign = nil
                    config.hotkey1 = nil
                    config.hotkey2 = nil
                    print("All assignments cleared")
                    save_config()
                    return true
                end
            elseif menu_state == "select_single" or menu_state == "select_hotkey1" or menu_state == "select_hotkey2" then
                if index == 1 then
                    -- Back to config menu
                    menu_state = "config"
                    return true
                elseif index > 3 then
                    -- Get the menu item and extract the keycode from it
                    local menu = menu_populate()
                    local selected_item = menu[index]
                    if selected_item and selected_item[2] then
                        if menu_state == "select_single" then
                            config.single_assign = selected_item[2]
                            print("Single assignment set to: " .. config.single_assign)
                        elseif menu_state == "select_hotkey1" then
                            config.hotkey1 = selected_item[2]
                            print("Hotkey 1 set to: " .. config.hotkey1)
                        elseif menu_state == "select_hotkey2" then
                            config.hotkey2 = selected_item[2]
                            print("Hotkey 2 set to: " .. config.hotkey2)
                        end
                        save_config()
                        menu_state = "config"
                        return true
                    end
                end
            end
        end
        return false
    end

    -- Add frame done callback to check for key combinations
    emu.register_frame_done(function()
        -- Only check if we have necessary components
        if not manager or not manager.machine then
            return false
        end
        
        local machine = manager.machine
        if not machine.input then
            return false
        end
        
        -- Get the input manager
        local input = machine.input
        
        -- Check Single Assignment (if configured)
        if config.single_assign and input.seq_pressed then
            local single_key_state = false
            local seq = input:seq_from_tokens(config.single_assign)
            if seq then
                single_key_state = input:seq_pressed(seq)
            end
            
            -- Trigger on key press (not hold)
            if single_key_state and not single_key_pressed then
                print("Single assignment activated: " .. config.single_assign)
                show_controls()
            end
            single_key_pressed = single_key_state
        end
        
        -- Check Hotkey Combination (if both configured)
        if config.hotkey1 and config.hotkey2 and input.seq_pressed then
            local hotkey1_state = false
            local hotkey2_state = false
            
            -- Check Hotkey 1 with fallback mappings
            local seq1 = input:seq_from_tokens(config.hotkey1)
            if seq1 then hotkey1_state = input:seq_pressed(seq1) end
            
            -- Add fallback mappings for common Start button variations
            if not hotkey1_state and (config.hotkey1 == "JOYCODE_1_START" or config.hotkey1 == "JOYCODE_1_BUTTON12") then
                local fallbacks = {"JOYCODE_1_START", "JOYCODE_1_BUTTON12", "JOYCODE_1_BUTTON10"}
                for _, fallback in ipairs(fallbacks) do
                    if fallback ~= config.hotkey1 then
                        local seq_fallback = input:seq_from_tokens(fallback)
                        if seq_fallback then 
                            hotkey1_state = hotkey1_state or input:seq_pressed(seq_fallback)
                            if hotkey1_state then break end
                        end
                    end
                end
            end
            
            -- Check Hotkey 2 with fallback mappings
            local seq2 = input:seq_from_tokens(config.hotkey2)
            if seq2 then hotkey2_state = input:seq_pressed(seq2) end
            
            -- Add fallback mappings for common RB button variations
            if not hotkey2_state and (config.hotkey2 == "JOYCODE_1_BUTTON6" or config.hotkey2 == "JOYCODE_1_BUTTON5") then
                local fallbacks = {"JOYCODE_1_BUTTON6", "JOYCODE_1_BUTTON5"}
                for _, fallback in ipairs(fallbacks) do
                    if fallback ~= config.hotkey2 then
                        local seq_fallback = input:seq_from_tokens(fallback)
                        if seq_fallback then 
                            hotkey2_state = hotkey2_state or input:seq_pressed(seq_fallback)
                            if hotkey2_state then break end
                        end
                    end
                end
            end
            
            -- Trigger when both are pressed AND at least one wasn't pressed before
            if hotkey1_state and hotkey2_state and (not hotkey1_pressed or not hotkey2_pressed) then
                print("Hotkey combo activated: " .. config.hotkey1 .. " + " .. config.hotkey2)
                show_controls()
            end
            
            hotkey1_pressed = hotkey1_state
            hotkey2_pressed = hotkey2_state
        end
        
        return false  -- Keep the callback active
    end)

    -- Register menu using the LEGACY API (from working older version)
    emu.register_menu(menu_callback, menu_populate, "Controls")
    
    -- Register pause handler using LEGACY API (from working older version)
    if emu.register_pause then
        print("Registering pause handler")
        emu.register_pause(function()
            -- Check if a ROM is running before trying to show controls
            local game_name = emu.romname()
            if not game_name or game_name == "" or game_name == "___empty" then
                print("No ROM is loaded, skipping pause handler")
                return
            end
            
            -- When the user pauses, check if we should show controls
            if not user_paused then
                user_paused = true
                print("User paused MAME")
                
                -- Only show controls if the option is enabled
                if config.show_on_pause then
                    print("Show on pause enabled - displaying controls")
                    show_controls()
                else
                    print("Show on pause disabled - not displaying controls")
                end
            else
                -- Reset our flag when MAME is unpaused
                user_paused = false
                print("MAME unpaused")
            end
        end)
    else
        print("emu.register_pause not available in this MAME version")
    end
    
    -- Register start handler using LEGACY API (from working older version)
    if emu.register_start then
        print("Registering start handler")
        emu.register_start(function()
            -- Reset precache status for new ROM
            rom_precached = false
            
            -- Directly check ROM name if timer is not available
            if not has_timer then
                local game_name = emu.romname()
                if game_name and game_name ~= "" and game_name ~= "___empty" then
                    print("ROM detected via start handler (without timer): " .. game_name)
                    precache_controls(game_name)
                else
                    print("No valid ROM name available in start handler")
                end
                return
            end
            
            -- Use a small delay to ensure MAME has fully loaded the ROM (if timer is available)
            emu.timer.pulse(1.0, function()
                local game_name = emu.romname()
                if game_name and game_name ~= "" and game_name ~= "___empty" then
                    print("ROM detected via start handler: " .. game_name)
                    precache_controls(game_name)
                else
                    print("No valid ROM name available in start handler")
                end
                return false  -- Don't repeat this timer
            end)
        end)
    end
    
    -- Reset when game stops using LEGACY API (from working older version)
    emu.register_stop(function()
        user_paused = false
        rom_precached = false
        current_rom = nil
        showing_controls = false
        last_show_time = 0
        print("Controls plugin reset for next game")
    end)
    
    -- Periodic timer as a final fallback using LEGACY API (from working older version)
    if has_timer then
        local periodic_timer = emu.timer.periodic(5.0, function()
            local game_name = emu.romname()
            if game_name and game_name ~= "" and game_name ~= "___empty" and game_name ~= current_rom then
                print("ROM change detected via periodic timer: " .. game_name)
                precache_controls(game_name)
            end
            return true  -- Keep timer running
        end)
        print("Periodic timer registered")
    else
        print("Timer functionality not available, skipping periodic checks")
    end
    
    print("Controls plugin loaded with precaching, hotkey support, persistent configuration, and Lightning Mode (legacy API)")
end

return exports