#include "imgui.h"
#include "sysdeps.h"
#include "options.h"
#include "inputdevice.h"
#include "amiberry_input.h"
#include "imgui_panels.h"
#include <vector>
#include <string>
#include <unordered_map>

#include "gui/gui_handling.h"

// Local constants matching inputdevice.h if needed
#ifndef TABLET_OFF
#define TABLET_OFF 0
#define TABLET_MOUSEHACK 1
#define TABLET_REAL 2
#endif
#ifndef MOUSEUNTRAP_MIDDLEBUTTON
#define MOUSEUNTRAP_MIDDLEBUTTON 1
#endif
#ifndef MOUSEUNTRAP_MAGIC
#define MOUSEUNTRAP_MAGIC 2
#endif

static std::vector<std::string> input_device_names;
static std::vector<const char *> input_device_items;
static std::vector<int> input_device_ids;

static void poll_input_devices() {
    input_device_names.clear();
    input_device_items.clear();
    input_device_ids.clear();

    // Static Items
    auto add = [](const char *name, int id) {
        input_device_names.emplace_back(name);
        input_device_ids.push_back(id);
    };

    add("<none>", JPORT_NONE);
    add("Keyboard Layout A (Numpad, 0/5=Fire, Decimal/DEL=2nd Fire)", JSEM_KBDLAYOUT);
    add("Keyboard Layout B (Cursor, RCtrl/RAlt=Fire, RShift=2nd Fire)", JSEM_KBDLAYOUT + 1);
    add("Keyboard Layout C (WSAD, LAlt=Fire, LShift=2nd Fire)", JSEM_KBDLAYOUT + 2);
    add("Keyrah Layout (Cursor, Space/RAlt=Fire, RShift=2nd Fire)", JSEM_KBDLAYOUT + 3);

    for (int j = 0; j < 4; j++) {
        char buf[64];
        snprintf(buf, sizeof(buf), "Retroarch KBD as Joystick Player%d", j + 1);
        add(buf, JSEM_KBDLAYOUT + j + 4);
    }

    // Joysticks — add type prefix so users can identify device types
    int num_joys = inputdevice_get_device_total(IDTYPE_JOYSTICK);
    for (int j = 0; j < num_joys; j++) {
        const char* name = inputdevice_get_device_name(IDTYPE_JOYSTICK, j);
        std::string label;
        if (j < MAX_INPUT_DEVICES && di_joystick[j].is_controller)
            label = std::string("[Gamepad] ") + (name ? name : "?");
        else
            label = std::string("[Joystick] ") + (name ? name : "?");
        input_device_names.push_back(label);
        input_device_ids.push_back(JSEM_JOYS + j);
    }

    // Mice — always prefixed with [Mouse] for parity with [Joystick] /
    // [Gamepad] entries. In single-mouse mode there is exactly one entry
    // ("[Mouse] System mouse"); in multi-mouse mode one entry per physical
    // device.
    int num_mice = inputdevice_get_device_total(IDTYPE_MOUSE);
    for (int j = 0; j < num_mice; j++) {
        const char* name = inputdevice_get_device_name(IDTYPE_MOUSE, j);
        std::string label = std::string("[Mouse] ") + (name && name[0] ? name : "?");
        input_device_names.push_back(label);
        input_device_ids.push_back(JSEM_MICE + j);
    }

    // Disambiguate duplicate device names by appending instance numbers
    std::unordered_map<std::string, int> name_counts;
    for (const auto &name : input_device_names) {
        name_counts[name]++;
    }
    std::unordered_map<std::string, int> name_seen;
    for (auto &name : input_device_names) {
        if (name_counts[name] > 1) {
            int instance = ++name_seen[name];
            name = name + " (" + std::to_string(instance) + ")";
        }
    }

    for (const auto &name: input_device_names) input_device_items.push_back(name.c_str());
}

static int get_device_index(int id) {
    for (size_t i = 0; i < input_device_ids.size(); ++i) {
        if (input_device_ids[i] == id) return (int) i;
    }
    return 0; // Default to <none>
}

void render_panel_input() {
    std::string mapping;
    if (ControllerMap_ConsumeResult(mapping)) {
        SDL_AddGamepadMapping(mapping.c_str());
        save_mapping_to_file(mapping);
    }

	if (input_device_names.empty() || joystick_refresh_needed) {
		joystick_refresh_needed = false;
		poll_input_devices();
	}

    ImGui::Indent(4.0f);

    // ---------------------------------------------------------
    // Mouse and Joystick settings
    // ---------------------------------------------------------
    BeginGroupBox("Mouse and Joystick settings");

    if (ImGui::BeginTable("PortsTable", 2, ImGuiTableFlags_None)) {
        ImGui::TableSetupColumn("label", ImGuiTableColumnFlags_WidthFixed, BUTTON_WIDTH);
        ImGui::TableSetupColumn("controls", ImGuiTableColumnFlags_WidthStretch);

        auto render_port = [&](int port_idx, const char *label) {
            ImGui::TableNextRow();
            ImGui::TableNextColumn();
            ImGui::AlignTextToFramePadding();
            ImGui::Text("%s", label);
            ImGui::TableNextColumn();

            int dev_idx = get_device_index(changed_prefs.jports[port_idx].id);
            ImGui::SetNextItemWidth(-ImGui::GetStyle().ItemSpacing.x * 2);
            if (ImGui::BeginCombo(std::string("##Dev").append(std::to_string(port_idx)).c_str(),
                                  input_device_items[dev_idx])) {
                for (int n = 0; n < static_cast<int>(input_device_items.size()); n++) {
                    const bool is_selected = (dev_idx == n);
                    if (is_selected)
                        ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                    ImGui::PushID(n);
                    if (ImGui::Selectable(input_device_items[n], is_selected)) {
                        dev_idx = n;
                        changed_prefs.jports[port_idx].id = input_device_ids[dev_idx];
                        inputdevice_validate_jports(&changed_prefs, port_idx, nullptr); // Validate change
                    }
                    ImGui::PopID();
                    if (is_selected) {
                        ImGui::PopStyleColor();
                        ImGui::SetItemDefaultFocus();
                    }
                }
                ImGui::EndCombo();
            }
            AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
            ShowHelpMarker("Select the input device to use for this Amiga port. Port 0 is typically for mouse, Port 1 for joystick");

            float avail_w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x * 2;
            float item_w = (avail_w - BUTTON_WIDTH * 1.5f) / 2;
            ImGui::SetNextItemWidth(item_w);

            const char *autofire_names[] = {
                "No autofire (normal)", "Autofire", "Autofire (toggle)", "Autofire (always)", "No autofire (toggle)"
            };
            if (ImGui::BeginCombo(std::string("##Autofire").append(std::to_string(port_idx)).c_str(),
                                  autofire_names[changed_prefs.jports[port_idx].autofire])) {
                for (int n = 0; n < IM_ARRAYSIZE(autofire_names); n++) {
                    const bool is_selected = (changed_prefs.jports[port_idx].autofire == n);
                    if (is_selected)
                        ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                    if (ImGui::Selectable(autofire_names[n], is_selected)) {
                        changed_prefs.jports[port_idx].autofire = n;
                    }
                    if (is_selected) {
                        ImGui::PopStyleColor();
                        ImGui::SetItemDefaultFocus();
                    }
                }
                ImGui::EndCombo();
            }
            AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
            ShowHelpMarker("Automatically repeat fire button presses. Toggle mode allows switching on/off with a button");

            ImGui::SameLine();
            ImGui::SetNextItemWidth(item_w);

            const char *mode_names[] = {
                "Default", "Wheel Mouse", "Mouse", "Joystick", "Gamepad", "Analog Joystick", "CDTV remote mouse",
                "CD32 pad"
            };
            if (ImGui::BeginCombo(std::string("##Mode").append(std::to_string(port_idx)).c_str(),
                                  mode_names[changed_prefs.jports[port_idx].mode])) {
                for (int n = 0; n < IM_ARRAYSIZE(mode_names); n++) {
                    const bool is_selected = (changed_prefs.jports[port_idx].mode == n);
                    if (is_selected)
                        ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                    if (ImGui::Selectable(mode_names[n], is_selected)) {
                        changed_prefs.jports[port_idx].mode = n;
                    }
                    if (is_selected) {
                        ImGui::PopStyleColor();
                        ImGui::SetItemDefaultFocus();
                    }
                }
                ImGui::EndCombo();
            }
            AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
            ShowHelpMarker("Select the emulation mode for this device (default, mouse, joystick, gamepad, CD32 pad, etc.)");

            ImGui::SameLine();
            const bool remap_enabled = changed_prefs.jports[port_idx].id >= JSEM_JOYS
                                       && changed_prefs.jports[port_idx].id < JSEM_MICE - 1;
            ImGui::BeginDisabled(!remap_enabled);
            if (AmigaButton(std::string("Remap / Test##").append(std::to_string(port_idx)).c_str())) {
                const auto host_joy_id = changed_prefs.jports[port_idx].id - JSEM_JOYS;
                ControllerMap_Open(host_joy_id, false);
            }
            ImGui::EndDisabled();

            // Row 3: Mouse Map
            ImGui::AlignTextToFramePadding();
            ImGui::Text("Mouse map:");
            ImGui::SameLine();
            ImGui::SetNextItemWidth(item_w);

            ImGui::BeginDisabled(changed_prefs.jports[port_idx].mode == 0);
            const char *mouse_map_names[] = {"None", "LStick"};
            if (ImGui::BeginCombo(std::string("##MouseMap").append(std::to_string(port_idx)).c_str(),
                                  mouse_map_names[changed_prefs.jports[port_idx].mousemap])) {
                for (int n = 0; n < IM_ARRAYSIZE(mouse_map_names); n++) {
                    const bool is_selected = (changed_prefs.jports[port_idx].mousemap == n);
                    if (is_selected)
                        ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                    if (ImGui::Selectable(mouse_map_names[n], is_selected)) {
                        changed_prefs.jports[port_idx].mousemap = n;
                    }
                    if (is_selected) {
                        ImGui::PopStyleColor();
                        ImGui::SetItemDefaultFocus();
                    }
                }
                ImGui::EndCombo();
            }
            AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
            ShowHelpMarker("Map mouse movement to analog stick (LStick). Only available when mode is not default");
            ImGui::EndDisabled();
        };

        render_port(0, "Port 1:");
        ImGui::TableNextRow();
        ImGui::TableNextColumn(); // separator row spans both columns
        ImGui::TableNextColumn();
        ImGui::Separator();
        render_port(1, "Port 2:");

        // Swap & Autoswitch in Column 2
        ImGui::TableNextRow();
        ImGui::TableNextColumn(); // Skip Col 1
        ImGui::TableNextColumn();
        ImGui::Dummy(ImVec2(0, 8.0f));
        if (AmigaButton(ICON_FA_SHUFFLE " Swap ports")) {
            inputdevice_swap_compa_ports(&changed_prefs, 0);
        }
        ImGui::SameLine();
        AmigaCheckbox("Mouse/Joystick autoswitching", &changed_prefs.input_autoswitch);
        ShowHelpMarker("Automatically switch Port 0 and Port 1 devices based on input activity");

        // Multi-mouse toggle — live-applies via a targeted mouse re-init that
        // preserves port bindings by index. We deliberately avoid
        // inputdevice_devicechange() here: that routine rebinds by friendly
        // name, and the "System mouse" ↔ SDL-device-name swap during a mode
        // toggle would make the match fail and shuffle the port assignment.
        ImGui::SameLine();
        const bool prev_multi_mouse = changed_prefs.input_multi_mouse;
        AmigaCheckbox("Multi-mouse support", &changed_prefs.input_multi_mouse);
        ShowHelpMarker("Treat each physical mouse as a separate device for 2-player mouse games (e.g., Lemmings). "
                       "Default: off — all mouse input is merged into a single System mouse, which is the most reliable option.");
        if (prev_multi_mouse != changed_prefs.input_multi_mouse) {
            inputdevice_mouse_reinit(&changed_prefs);
            // Repopulate the dropdown labels immediately so this frame
            // reflects the new device list (avoids a one-frame lag where
            // the combo would still show the pre-toggle names).
            poll_input_devices();
            joystick_refresh_needed = false;
        }

        ImGui::TableNextRow();
        ImGui::TableNextColumn(); // Skip Col 1
        ImGui::TableNextColumn();
        AmigaCheckbox("Map left face button (Xbox X / PS Square) as extra Joy Up", &changed_prefs.input_joystick_up_button);
        ShowHelpMarker("Binds the left face button (Xbox X / PlayStation Square) as a duplicate of "
                       "Joystick Up on Joystick and Default port modes, giving a free dedicated jump "
                       "button on modern gamepads. In Default mode this overrides the rarely-used "
                       "3rd fire button. Does not apply to CD32 or Gamepad modes.");

        ImGui::EndTable();
    }
    ImGui::Spacing();
    EndGroupBox("Mouse and Joystick settings");

    // ---------------------------------------------------------
    // Emulated Parallel Port
    // ---------------------------------------------------------
    if (BeginGroupBox("Emulated parallel port joystick adapter", true)) {

    if (ImGui::BeginTable("ParTable", 2, ImGuiTableFlags_None)) {
        ImGui::TableSetupColumn("label", ImGuiTableColumnFlags_WidthFixed, BUTTON_WIDTH);
        ImGui::TableSetupColumn("controls", ImGuiTableColumnFlags_WidthStretch);

        auto render_par_port = [&](int port_idx, const char *label) {
            ImGui::TableNextRow();
            ImGui::TableNextColumn();
            ImGui::AlignTextToFramePadding();
            ImGui::Text("%s", label);
            ImGui::TableNextColumn();

            int dev_idx = get_device_index(changed_prefs.jports[port_idx].id);
            ImGui::SetNextItemWidth(-ImGui::GetStyle().ItemSpacing.x * 2);
            if (ImGui::BeginCombo(std::string("##ParDev").append(std::to_string(port_idx)).c_str(),
                                  input_device_items[dev_idx])) {
                for (int n = 0; n < static_cast<int>(input_device_items.size()); n++) {
                    const bool is_selected = (dev_idx == n);
                    if (is_selected)
                        ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                    ImGui::PushID(n);
                    if (ImGui::Selectable(input_device_items[n], is_selected)) {
                        dev_idx = n;
                        changed_prefs.jports[port_idx].id = input_device_ids[dev_idx];
                    }
                    ImGui::PopID();
                    if (is_selected) {
                        ImGui::PopStyleColor();
                        ImGui::SetItemDefaultFocus();
                    }
                }
                ImGui::EndCombo();
            }
            AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());

            // Row 2: Autofire | Remap
            float avail_w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x * 2;
            float item_w = (avail_w - BUTTON_WIDTH * 1.5f) / 2;

            ImGui::SetNextItemWidth(item_w);
            const char *autofire_names[] = {
                "No autofire (normal)", "Autofire", "Autofire (toggle)", "Autofire (always)", "No autofire (toggle)"
            };
            if (ImGui::BeginCombo(std::string("##ParAutofire").append(std::to_string(port_idx)).c_str(),
                                  autofire_names[changed_prefs.jports[port_idx].autofire])) {
                for (int n = 0; n < IM_ARRAYSIZE(autofire_names); n++) {
                    const bool is_selected = (changed_prefs.jports[port_idx].autofire == n);
                    if (is_selected)
                        ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                    if (ImGui::Selectable(autofire_names[n], is_selected)) {
                        changed_prefs.jports[port_idx].autofire = n;
                    }
                    if (is_selected) {
                        ImGui::PopStyleColor();
                        ImGui::SetItemDefaultFocus();
                    }
                }
                ImGui::EndCombo();
            }
            AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
            ShowHelpMarker("Automatically repeat fire button presses on this parallel port device");

            ImGui::SameLine();
            const bool remap_enabled = changed_prefs.jports[port_idx].id >= JSEM_JOYS
                                       && changed_prefs.jports[port_idx].id < JSEM_MICE - 1;
            ImGui::BeginDisabled(!remap_enabled);
            if (AmigaButton(std::string("Remap / Test##Par").append(std::to_string(port_idx)).c_str())) {
                const auto host_joy_id = changed_prefs.jports[port_idx].id - JSEM_JOYS;
                ControllerMap_Open(host_joy_id, false);
            }
            ImGui::EndDisabled();
        };

        render_par_port(2, "Port 3:");
        ImGui::TableNextRow();
        ImGui::TableNextColumn();
        ImGui::TableNextColumn();
        render_par_port(3, "Port 4:");

        ImGui::EndTable();
    }
    ImGui::Spacing();
    }
    EndGroupBox("Emulated parallel port joystick adapter");

    static const int digital_joymousespeed_values[] = {2, 5, 10, 15, 20};
    static const int analog_joymousespeed_values[] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 75, 100, 125, 150};

    if (BeginGroupBox("Game Controller Settings", true)) {
    // Joystick Dead Zone
    ImGui::AlignTextToFramePadding();
    ImGui::Text("Joystick dead zone:");
    ImGui::SameLine();
    ImGui::SetNextItemWidth(BUTTON_WIDTH);
    ImGui::SliderInt("##DeadZone", &changed_prefs.input_joystick_deadzone, 0, 100, "%d%%");
    AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), false);
    ShowHelpMarker("Analog stick dead zone - area of no response around center position (0-100%)");

    // Autofire Rate
    ImGui::SameLine();
    ImGui::AlignTextToFramePadding();
    ImGui::Text("Autofire Rate:");
    ImGui::SameLine();
    int af_rate_idx = 0;
    if (changed_prefs.input_autofire_linecnt == 0) af_rate_idx = 0;
    else if (changed_prefs.input_autofire_linecnt > 10 * 312) af_rate_idx = 1;
    else if (changed_prefs.input_autofire_linecnt > 6 * 312) af_rate_idx = 2;
    else af_rate_idx = 3;

    ImGui::SetNextItemWidth(BUTTON_WIDTH);
    const char *af_rate_names[] = {"Off", "Slow", "Medium", "Fast"};
    if (ImGui::BeginCombo("##AutofireRate", af_rate_names[af_rate_idx])) {
        for (int n = 0; n < IM_ARRAYSIZE(af_rate_names); n++) {
            const bool is_selected = (af_rate_idx == n);
            if (is_selected)
                ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
            if (ImGui::Selectable(af_rate_names[n], is_selected)) {
                af_rate_idx = n;
                if (af_rate_idx == 0) changed_prefs.input_autofire_linecnt = 0;
                else if (af_rate_idx == 1) changed_prefs.input_autofire_linecnt = 12 * 312;
                else if (af_rate_idx == 2) changed_prefs.input_autofire_linecnt = 8 * 312;
                else changed_prefs.input_autofire_linecnt = 4 * 312;
            }
            if (is_selected) {
                ImGui::PopStyleColor();
                ImGui::SetItemDefaultFocus();
            }
        }
        ImGui::EndCombo();
    }
    AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), false);
    ShowHelpMarker("How fast autofire repeats (lower values = faster repeat rate)");

    // Digital Joy-Mouse Speed
    ImGui::AlignTextToFramePadding();
    ImGui::Text("Digital joy-mouse speed:");
    ImGui::SameLine();
    int dig_speed_idx = 2; // Default 10
    for (int i = 0; i < IM_ARRAYSIZE(digital_joymousespeed_values); ++i) {
        if (changed_prefs.input_joymouse_speed == digital_joymousespeed_values[i]) {
            dig_speed_idx = i;
            break;
        }
    }
    ImGui::SetNextItemWidth(BUTTON_WIDTH);
    if (ImGui::SliderInt("##DigSpeed", &dig_speed_idx, 0, IM_ARRAYSIZE(digital_joymousespeed_values) - 1, "")) {
        changed_prefs.input_joymouse_speed = digital_joymousespeed_values[dig_speed_idx];
    }
    AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), false);
    ShowHelpMarker("Mouse cursor speed when controlled by digital joystick directions");
    ImGui::SameLine();
    ImGui::AlignTextToFramePadding();
    ImGui::Text("%d", changed_prefs.input_joymouse_speed);

    // Analog Joy-Mouse Speed
    ImGui::AlignTextToFramePadding();
    ImGui::Text("Analog joy-mouse speed:");
    ImGui::SameLine();
    int ana_speed_idx = 1; // Default 10
    for (int i = 0; i < IM_ARRAYSIZE(analog_joymousespeed_values); ++i) {
        if (changed_prefs.input_joymouse_multiplier == analog_joymousespeed_values[i]) {
            ana_speed_idx = i;
            break;
        }
    }
    ImGui::SetNextItemWidth(BUTTON_WIDTH);
    if (ImGui::SliderInt("##AnaSpeed", &ana_speed_idx, 0, IM_ARRAYSIZE(analog_joymousespeed_values) - 1, "")) {
        changed_prefs.input_joymouse_multiplier = analog_joymousespeed_values[ana_speed_idx];
    }
    AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), false);
    ShowHelpMarker("Sensitivity multiplier for mouse cursor controlled by analog joystick");
    ImGui::SameLine();
    ImGui::AlignTextToFramePadding();
    ImGui::Text("%d", changed_prefs.input_joymouse_multiplier);
    ImGui::Spacing();
    }
    EndGroupBox("Game Controller Settings");

    if (BeginGroupBox("Mouse extra settings", true)) {

    if (ImGui::BeginTable("MouseExtrasTable", 2, ImGuiTableFlags_None)) {
        // Row 1
        ImGui::TableNextRow();

        // Left: Mouse Speed
        ImGui::TableNextColumn();
        ImGui::AlignTextToFramePadding();
        ImGui::Text("Mouse speed:");
        ImGui::SameLine();
        ImGui::SetNextItemWidth(BUTTON_WIDTH);
        ImGui::InputInt("##MouseSpd", &changed_prefs.input_mouse_speed, 1, 10);
        AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), true);
        ShowHelpMarker("Mouse sensitivity multiplier (100 = normal speed, higher = faster)");

        // Right: Mouse Untrap (Inline Label)
        ImGui::TableNextColumn();
        ImGui::AlignTextToFramePadding();
        ImGui::Text("Mouse untrap:");
        ImGui::SameLine();

        const char *untrap_items[] = {"None", "Middle button", "Magic mouse", "Both"};
        int untrap_val = changed_prefs.input_mouse_untrap;
        int untrap_idx = 0;
        if ((untrap_val & MOUSEUNTRAP_MIDDLEBUTTON) && (untrap_val & MOUSEUNTRAP_MAGIC)) untrap_idx = 3;
        else if (untrap_val & MOUSEUNTRAP_MAGIC) untrap_idx = 2;
        else if (untrap_val & MOUSEUNTRAP_MIDDLEBUTTON) untrap_idx = 1;

        ImGui::SetNextItemWidth(-ImGui::GetStyle().ItemSpacing.x * 2);
        if (ImGui::BeginCombo("##UntrapMode", untrap_items[untrap_idx])) {
            for (int n = 0; n < IM_ARRAYSIZE(untrap_items); n++) {
                const bool is_selected = (untrap_idx == n);
                if (is_selected)
                    ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                if (ImGui::Selectable(untrap_items[n], is_selected)) {
                    untrap_idx = n;
                    int new_val = 0;
                    if (untrap_idx == 1) new_val = MOUSEUNTRAP_MIDDLEBUTTON;
                    else if (untrap_idx == 2) new_val = MOUSEUNTRAP_MAGIC;
                    else if (untrap_idx == 3) new_val = MOUSEUNTRAP_MIDDLEBUTTON | MOUSEUNTRAP_MAGIC;
                    changed_prefs.input_mouse_untrap = new_val;
                }
                if (is_selected) {
                    ImGui::PopStyleColor();
                    ImGui::SetItemDefaultFocus();
                }
            }
            ImGui::EndCombo();
        }
        AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
        ShowHelpMarker("How to release the mouse from the emulator window (middle button, magic mouse, or both)");

        // Row 2
        ImGui::TableNextRow();

        // Left: Virtual Mouse
        ImGui::TableNextColumn();
		bool virt_mouse = changed_prefs.input_tablet > 0;
		if (AmigaCheckbox("Install virtual mouse driver", &virt_mouse)) {
			if (virt_mouse) {
				if (changed_prefs.input_tablet == TABLET_OFF)
					changed_prefs.input_tablet = TABLET_MOUSEHACK;
			} else {
				changed_prefs.input_tablet = TABLET_OFF;
			}
		}
        ShowHelpMarker("Install a virtual mouse driver for tablet/touchscreen absolute positioning");

        // Right: Cursor Mode
        ImGui::TableNextColumn();
        ImGui::AlignTextToFramePadding();
        ImGui::Text("Magic Mouse cursor:");
        ImGui::SameLine();
        const char *magic_items[] = {"Both", "Native only", "Host only"};
        ImGui::SetNextItemWidth(-ImGui::GetStyle().ItemSpacing.x * 2);

        ImGui::BeginDisabled(changed_prefs.input_tablet == 0);
        if (ImGui::BeginCombo("##MagicMouse", magic_items[changed_prefs.input_magic_mouse_cursor])) {
            for (int n = 0; n < IM_ARRAYSIZE(magic_items); n++) {
                const bool is_selected = (changed_prefs.input_magic_mouse_cursor == n);
                if (is_selected)
                    ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]);
                if (ImGui::Selectable(magic_items[n], is_selected)) {
                    changed_prefs.input_magic_mouse_cursor = n;
                }
                if (is_selected) {
                    ImGui::PopStyleColor();
                    ImGui::SetItemDefaultFocus();
                }
            }
            ImGui::EndCombo();
        }
        AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
        ShowHelpMarker("Display Amiga cursor, host cursor, or both when using magic mouse mode");
        ImGui::EndDisabled();

        // Row 3
        ImGui::TableNextRow();

        ImGui::TableNextColumn();
        bool tablet_active = changed_prefs.input_tablet > 0;
        ImGui::BeginDisabled(!tablet_active);
        AmigaCheckbox("Tablet.library emulation", &changed_prefs.tablet_library);
        ShowHelpMarker("Emulate Amiga tablet.library for graphics tablet support");
        ImGui::EndDisabled();

        ImGui::TableNextColumn();
        ImGui::AlignTextToFramePadding();
        ImGui::Text("Tablet mode:");
        ImGui::SameLine();

		ImGui::BeginDisabled(!tablet_active);
		int tablet_mode = 0;
		if (changed_prefs.input_tablet == TABLET_MOUSEHACK)
			tablet_mode = 1;
		else if (changed_prefs.input_tablet == TABLET_REAL)
			tablet_mode = 2;
		ImGui::SetNextItemWidth(-ImGui::GetStyle().ItemSpacing.x * 2);
		if (ImGui::Combo("##TabletMode", &tablet_mode, "Disabled\0MouseHack\0Real Tablet\0")) {
			if (tablet_mode == 2)
				changed_prefs.input_tablet = TABLET_REAL;
			else if (tablet_mode == 1)
				changed_prefs.input_tablet = TABLET_MOUSEHACK;
			else
				changed_prefs.input_tablet = TABLET_OFF;
		}
		AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), ImGui::IsItemActivated());
		ShowHelpMarker("Tablet mode: MouseHack for mouse absolute positioning, Real Tablet for pressure-sensitive pen/tablet input via SDL3");
        ImGui::EndDisabled();

        ImGui::EndTable();
    }
    ImGui::Spacing();
    }
    EndGroupBox("Mouse extra settings");
}
