// ─────────────────────────────────────────────────────────────────────────────
// modules/binds.kdl — Keyboard and mouse bindings for niri
//
// PURPOSE: Central definition of every user-triggered action in the niri
//          session.  Bindings are grouped by function so related keys are easy
//          to find and modify.
//
// MODIFIER KEY ("Mod"): Defaults to the Super / Windows key.
//
// Modifier semantics for directional keys:
//   Mod + dir              → focus (move focus to window or column)
//   Mod + Shift + dir      → move selected window or column in that direction
//   Mod + Ctrl + dir       → navigate workspaces (up/down)
//   Mod + Ctrl+Shift + dir → move the focused column to a workspace
//   Mod + Alt + dir        → resize (column width with H/L, window height with J/K)
//
// allow-when-locked=true: the binding fires even when swaylock is active.
//   WHY: media controls and brightness must work on the lock screen.
// ─────────────────────────────────────────────────────────────────────────────

binds {
    // ── Applications ──────────────────────────────────────────────────────────

    // Mod+T: open a standard kitty terminal.
    Mod+T { spawn "kitty"; }

    // Mod+Shift+T: open cool-retro-term with the CRT profile from this repo.
    // WHY: retro CRT aesthetic for a cyberqueer vibe; kept separate from the
    // main terminal so normal workflows aren't forced through the slow CRT font.
    Mod+Shift+T { spawn "bash" "-c" "cool-retro-term -p ~/Dotfiles/desktopenvs/niri/CRT"; }

    // Mod+M: open Neovim inside kitty (quick editor shortcut).
    Mod+M { spawn "bash" "-c" "kitty -e nvim"; }

    // Mod+E: open Thunar file manager (primary GUI file manager).
    Mod+E { spawn "thunar"; }

    // Mod+Alt+E: open PCManFM-Qt as an alternative file manager.
    // WHY alt key: secondary tool; not used daily but useful as a fallback.
    Mod+Alt+E { spawn "pcmanfm-qt"; }

    // Mod+X: open wofi in "run" mode (raw binary launcher, no .desktop files).
    Mod+X { spawn "bash" "-c" "wofi --show=run"; }

    // Mod+N: open Nextcloud desktop client for cloud sync management.
    Mod+N { spawn "nextcloud"; }

    // Mod+I: open iwmenu (Wi-Fi network picker) using the walker launcher UI.
    Mod+I { spawn "bash" "-c" "iwmenu --launcher walker"; }

    // Mod+Alt+I: open bzmenu (Bluetooth device picker) with walker UI.
    Mod+Alt+I { spawn "bash" "-c" "bzmenu --launcher walker"; }

    // Mod+Shift+I: open nm-connection-editor for advanced network configuration.
    Mod+Shift+I { spawn "nm-connection-editor"; }

    // Mod+R / Mod+Return / Ctrl+Shift+R: toggle the vicinae launcher overlay.
    // WHY three bindings: muscle-memory coverage from different contexts
    // (Mod+R mirrors rofi habit; Return is ergonomic; Ctrl+Shift+R works in
    // some terminal apps where Mod is captured).
    Mod+R { spawn "bash" "-c" "vicinae toggle"; }
    Mod+Return { spawn "bash" "-c" "vicinae toggle"; }
    Ctrl+Shift+R { spawn "bash" "-c" "vicinae toggle"; }

    // Mod+Shift+R: open wofi in drun mode (.desktop application launcher).
    Mod+Shift+R { spawn "bash" "-c" "wofi --show drun"; }

    // File search shortcuts
    Mod+F { spawn "bash" "-c" "~/.config/scripts/wofi-file-search.sh"; }       // fuzzy file search
    Mod+Shift+F { spawn "bash" "-c" "~/.config/scripts/foldersearch.sh"; }     // folder search
    Mod+Alt+F { spawn "wofi-calc"; }                                            // calculator in wofi

    // Mod+S: open PulseAudio volume control (pavucontrol) for audio routing.
    Mod+S { spawn "pavucontrol"; }

    // Mod+U: open btop system monitor inside kitty.
    Mod+U { spawn "bash" "-c" "kitty -e btop"; }

    // Mod+W: open the TUI wallpaper picker (swaybg-based, uses kitty icat).
    Mod+W { spawn "bash" "-c" "kitty -e ~/.config/scripts/wallpaper-picker ~/Pictures"; }

    // Mod+Ctrl+R: open the amssh SSH session picker inside kitty.
    Mod+Ctrl+R { spawn "bash" "-c" "kitty -e ~/.config/scripts/amssh"; }

    // Mod+F1: open the help/keybindings cheatsheet in a kitty window.
    Mod+F1 { spawn "bash" "-c" "kitty -e ~/.config/scripts/helpmenu.sh"; }

    // Mod+Ctrl+T: open a countdown/interval timer picker inside kitty.
    Mod+Ctrl+T { spawn "bash" "-c" "kitty -e ~/.config/scripts/timer-pick"; }

    // Mod+Shift+F1: open the niri config file directly in nvim for quick edits.
    Mod+Shift+F1 { spawn "bash" "-c" "kitty -e nvim ~/.config/niri/config.kdl"; }

    // Mod+Ctrl+P: start/stop screen recording (screenrec.sh toggles ffmpeg).
    Mod+Ctrl+P { spawn "bash" "-c" "~/.config/scripts/screenrec.sh"; }

    // App drawer: nwg-drawer (grid of apps + power menu) — two bindings for
    // ergonomic coverage.
    Mod+D { spawn "bash" "-c" "~/.config/scripts/drawer.sh"; }
    Mod+Shift+A { spawn "bash" "-c" "~/.config/scripts/drawer.sh"; }

    // ── Screenshots ───────────────────────────────────────────────────────────

    // Print / Mod+P: interactive region/window screenshot (saved to Pictures/Screenshots).
    Print { screenshot; }
    Mod+P { screenshot; }

    // Mod+Shift+P: full-screen (current output) screenshot without selection UI.
    Mod+Shift+P { screenshot-screen; }

    // ── Window Management ─────────────────────────────────────────────────────

    // Mod+Q / Mod+Shift+Q: close the focused window (sends WM_DELETE_WINDOW).
    // WHY two bindings: Shift variant is a safe fallback if Q is captured by an app.
    Mod+Q { close-window; }
    Mod+Shift+Q { close-window; }

    // Mod+V: toggle the focused window between tiled and floating mode.
    Mod+V { toggle-window-floating; }

    // Mod+Shift+V / Mod+C: centre the focused column on screen.
    // WHY two bindings: muscle memory from different compositors (hyprland uses C).
    Mod+Shift+V { center-column; }
    Mod+C { center-column; }

    // Mod+Ctrl+M: cycle through available layout algorithms (niri currently
    // offers one, but this future-proofs the setup).
    Mod+Ctrl+M { switch-layout "next"; }

    // ── Niri layout actions ───────────────────────────────────────────────────

    // Mod+Backspace: cycle through preset column widths (1/3, 1/2, 2/3, full).
    // Widths defined in layout.kdl → preset-column-widths.
    Mod+Backspace { switch-preset-column-width; }

    // Mod+Shift+Backspace: toggle the focused column between its current width
    // and the full available width (maximise without going fullscreen).
    Mod+Shift+Backspace { maximize-column; }

    // Mod+Ctrl+Backspace: true fullscreen (window covers the whole output,
    // hiding the eww bar).
    Mod+Ctrl+Backspace { fullscreen-window; }

    // Column stacking (niri's "group" equivalent to hyprland's window groups):
    // Mod+A: pull the window to the right of the focused column into it (stack below).
    // Mod+Y: eject the bottom window of a multi-window column to its own column.
    // Mod+Alt+C/V: consume/expel the adjacent window left or right.
    Mod+A { consume-window-into-column; }
    Mod+Y { expel-window-from-column; }
    Mod+Alt+C { consume-or-expel-window-left; }
    Mod+Alt+V { consume-or-expel-window-right; }

    // ── Focus — Vim-style (H/J/K/L) + arrow keys ─────────────────────────────
    // H/L navigate between columns; J/K navigate between stacked windows within
    // a column.  Arrow keys are duplicated for non-vim users.
    Mod+H { focus-column-left; }
    Mod+L { focus-column-right; }
    Mod+J { focus-window-down; }
    Mod+K { focus-window-up; }
    Mod+Left { focus-column-left; }
    Mod+Right { focus-column-right; }
    Mod+Down { focus-window-down; }
    Mod+Up { focus-window-up; }

    // Mod+Tab: focus the next window down, or the first window of the next column.
    // WHY: provides a natural Alt+Tab-like cycling without needing a separate switcher.
    Mod+Tab { focus-window-down-or-column-right; }
    Mod+Shift+Tab { focus-window-up-or-column-left; }

    // Mod+Shift+Return: toggle the workspace overview (bird's-eye view of all
    // workspaces and their windows).
    Mod+Shift+Return { toggle-overview; }

    // ── Move Window — Vim-style + arrow keys ──────────────────────────────────
    // Moves the focused column/window in the specified direction within the layout.
    Mod+Shift+H { move-column-left; }
    Mod+Shift+L { move-column-right; }
    Mod+Shift+J { move-window-down; }
    Mod+Shift+K { move-window-up; }
    Mod+Shift+Left { move-column-left; }
    Mod+Shift+Right { move-column-right; }
    Mod+Shift+Down { move-window-down; }
    Mod+Shift+Up { move-window-up; }

    // Mouse drag and resize:
    //   Button272 = left mouse button; Button273 = right mouse button.
    //   Mod+LMB: drag window to move it (floating or reorder in tiling).
    //   Mod+RMB / Mod+Shift+LMB: drag to resize window.
    Mod+Button272 { move-window-with-pointer; }
    Mod+Button273 { resize-window-with-pointer; }
    Mod+Shift+Button272 { resize-window-with-pointer; }

    // ── Resize — Mod+Alt + Vim-style + arrow keys ─────────────────────────────
    // Adjusts column width (H/L) or window height within a column (J/K).
    // 10% increments are coarse enough to be useful without needing many presses.
    Mod+Alt+L { set-column-width "+10%"; }
    Mod+Alt+H { set-column-width "-10%"; }
    Mod+Alt+K { set-window-height "-10%"; }
    Mod+Alt+J { set-window-height "+10%"; }
    Mod+Alt+Right { set-column-width "+10%"; }
    Mod+Alt+Left { set-column-width "-10%"; }
    Mod+Alt+Up { set-window-height "-10%"; }
    Mod+Alt+Down { set-window-height "+10%"; }

    // ── Workspaces — direct jump (Mod+number) ────────────────────────────────
    // Jumps directly to workspace N (1-indexed; Mod+0 = workspace 10).
    Mod+1 { focus-workspace 1; }
    Mod+2 { focus-workspace 2; }
    Mod+3 { focus-workspace 3; }
    Mod+4 { focus-workspace 4; }
    Mod+5 { focus-workspace 5; }
    Mod+6 { focus-workspace 6; }
    Mod+7 { focus-workspace 7; }
    Mod+8 { focus-workspace 8; }
    Mod+9 { focus-workspace 9; }
    Mod+0 { focus-workspace 10; }

    // Mod+Shift+number: move the focused column to workspace N.
    Mod+Shift+1 { move-column-to-workspace 1; }
    Mod+Shift+2 { move-column-to-workspace 2; }
    Mod+Shift+3 { move-column-to-workspace 3; }
    Mod+Shift+4 { move-column-to-workspace 4; }
    Mod+Shift+5 { move-column-to-workspace 5; }
    Mod+Shift+6 { move-column-to-workspace 6; }
    Mod+Shift+7 { move-column-to-workspace 7; }
    Mod+Shift+8 { move-column-to-workspace 8; }
    Mod+Shift+9 { move-column-to-workspace 9; }
    Mod+Shift+0 { move-column-to-workspace 10; }

    // ── Workspaces — relative navigation (Ctrl + direction) ──────────────────
    // niri workspaces stack vertically, so J/K and Down/Up are the canonical
    // directions.  H/L and Left/Right are aliased for users habituated to
    // horizontal workspace navigation from other compositors.
    Mod+Ctrl+J { focus-workspace-down; }
    Mod+Ctrl+K { focus-workspace-up; }
    Mod+Ctrl+Down { focus-workspace-down; }
    Mod+Ctrl+Up { focus-workspace-up; }
    // H/L and Left/Right mirror the above for horizontal-habit users
    Mod+Ctrl+L { focus-workspace-down; }
    Mod+Ctrl+H { focus-workspace-up; }
    Mod+Ctrl+Right { focus-workspace-down; }
    Mod+Ctrl+Left { focus-workspace-up; }

    // ── Workspaces — move column (Ctrl+Shift + direction) ────────────────────
    // Sends the focused column to the next/previous workspace while staying on
    // the current workspace (the user does not follow the window).
    Mod+Ctrl+Shift+J { move-column-to-workspace-down; }
    Mod+Ctrl+Shift+K { move-column-to-workspace-up; }
    Mod+Ctrl+Shift+Down { move-column-to-workspace-down; }
    Mod+Ctrl+Shift+Up { move-column-to-workspace-up; }
    Mod+Ctrl+Shift+L { move-column-to-workspace-down; }
    Mod+Ctrl+Shift+H { move-column-to-workspace-up; }
    Mod+Ctrl+Shift+Right { move-column-to-workspace-down; }
    Mod+Ctrl+Shift+Left { move-column-to-workspace-up; }

    // Mouse wheel workspace scrolling (with Mod held):
    // cooldown-ms=150: debounce rapid wheel events to avoid skipping workspaces.
    Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
    Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
    // Shift+wheel: moves the column to the target workspace instead of focusing.
    Mod+Shift+WheelScrollDown { move-column-to-workspace-down; }
    Mod+Shift+WheelScrollUp { move-column-to-workspace-up; }

    // Horizontal scroll (trackpad two-finger swipe or horizontal wheel):
    // scrolls the focused column list left/right.
    Mod+WheelScrollRight { focus-column-right; }
    Mod+WheelScrollLeft { focus-column-left; }

    // Volume rocker keys repurposed as workspace nav when held with Mod.
    // WHY: on compact keyboards / tablets without Ctrl, the volume buttons
    // offer an ergonomic one-handed workspace switch.
    Mod+XF86AudioRaiseVolume { focus-workspace-down; }
    Mod+XF86AudioLowerVolume { focus-workspace-up; }
    Mod+Shift+XF86AudioRaiseVolume { move-column-to-workspace-down; }
    Mod+Shift+XF86AudioLowerVolume { move-column-to-workspace-up; }

    // ── Overview / recent-window scratchpad analog ────────────────────────────
    // focus-workspace-with-recent-window: jump to whichever workspace holds the
    // most recently focused window (like a "last workspace" toggle).
    Mod+Space { focus-workspace-with-recent-window; }
    // Mod+Shift+Space: move the current column to that "recent" workspace.
    Mod+Shift+Space { move-column-to-workspace-with-recent-window; }
    // Overview toggle (bird's-eye all-workspaces view):
    Mod+Ctrl+Space { toggle-overview; }
    // Mute button + Mod as an additional overview toggle (useful on tablets).
    Mod+XF86AudioMute { toggle-overview; }
    Mod+Shift+XF86AudioMute { move-column-to-workspace-with-recent-window; }

    // ── Bar / UI ──────────────────────────────────────────────────────────────
    // Mod+Z: toggle (show/hide) the eww status bar on the current output.
    Mod+Z { spawn "bash" "-c" "~/.config/scripts/togglebar.sh"; }
    // Mod+Ctrl+B: force-reload eww (useful after a config change).
    Mod+Ctrl+B { spawn "bash" "-c" "eww reload"; }

    // ── Audio (media keys) ────────────────────────────────────────────────────
    // allow-when-locked=true: these fire even when swaylock is showing.
    // WHY: volume and media control should always be accessible.
    //
    // wpctl: WirePlumber controller (PipeWire's high-level volume API).
    //   -l 1.4 caps volume at 140% to protect speakers; 5% steps are fine-grained.
    //   @DEFAULT_AUDIO_SINK@: targets whatever the current default output is.
    XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.4" "@DEFAULT_AUDIO_SINK@" "5%+"; }
    XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.4" "@DEFAULT_AUDIO_SINK@" "5%-"; }
    XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
    XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
    // playerctl targets Spotify and VLC; other players won't be accidentally paused.
    XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause" "-p" "spotify,vlc"; }

    // ── Brightness ────────────────────────────────────────────────────────────
    // bri: a minimal backlight helper that adjusts the kernel backlight sysfs node.
    // allow-when-locked=true: brightness must work on the lock screen.
    XF86MonBrightnessUp allow-when-locked=true { spawn "bri" "--up"; }
    XF86MonBrightnessDown allow-when-locked=true { spawn "bri" "--down"; }

    // ── Colour temperature presets (gammastep) ────────────────────────────────
    // Each binding kills the running gammastep instance and starts a new one at
    // a different Kelvin value.  WHY killall first: gammastep doesn't support
    // live reconfiguration via IPC, so we replace the process entirely.
    //   6500 K = neutral daylight white (no filter)
    //   5000 K = slight warmth
    //   4000 K = warm white (default startup value)
    //   3000 K = amber
    //   2700 K = candlelight / maximum eye strain reduction
    Mod+Ctrl+X { spawn "bash" "-c" "killall gammastep; gammastep -O 6500"; }
    Mod+Ctrl+W { spawn "bash" "-c" "killall gammastep; gammastep -O 5000"; }
    Mod+Ctrl+A { spawn "bash" "-c" "killall gammastep; gammastep -O 4000"; }
    Mod+Ctrl+Q { spawn "bash" "-c" "killall gammastep; gammastep -O 3000"; }
    Mod+Ctrl+S { spawn "bash" "-c" "killall gammastep; gammastep -O 2700"; }

    // ── Miscellaneous ─────────────────────────────────────────────────────────

    // chamel — a privacy/stealth overlay tool:
    //   toggle        → show/hide the overlay
    //   clear         → remove content but keep overlay active
    //   clear-and-deactivate → remove content and deactivate overlay entirely
    Mod+Ctrl+I { spawn "chamel" "toggle"; }
    Mod+Ctrl+U { spawn "chamel" "clear"; }
    Mod+Ctrl+Z { spawn "chamel" "clear-and-deactivate"; }

    // Mod+Ctrl+C: dismiss all pending dunst notifications.
    Mod+Ctrl+C { spawn "dunstctl" "close-all"; }

    // Mod+Ctrl+G: toggle on-screen keyboard (for touch/tablet use).
    Mod+Ctrl+G { spawn "bash" "-c" "~/.config/scripts/onscreenkb.sh"; }

    // Mod+Shift+C: toggle caffeine (idle inhibitor) — prevents screen lock/sleep.
    Mod+Shift+C { spawn "bash" "-c" "~/.config/scripts/caffeine.sh"; }

    // Mod+Shift+B: open biometrics enrollment wizard in a kitty window.
    Mod+Shift+B { spawn "bash" "-c" "kitty -e ~/.config/scripts/enroll-biometrics.sh"; }

    // Mod+Shift+X: toggle touchpad on/off (useful when an external mouse is connected).
    Mod+Shift+X { spawn "bash" "-c" "~/.config/scripts/niri-toggle-touchpad.sh"; }

    // Screen rotation shortcuts — delegate to unified-rotate.sh:
    //   Mod+Ctrl+E → clockwise (landscape → portrait right)
    //   Mod+Ctrl+D → counter-clockwise (landscape → portrait left)
    Mod+Ctrl+E { spawn "bash" "-c" "~/.config/scripts/screenrotationwcw.sh"; }
    Mod+Ctrl+D { spawn "bash" "-c" "~/.config/scripts/screenrotationacw.sh"; }

    // ── Lock / Session end ────────────────────────────────────────────────────

    // Mod+O: lock the screen immediately with swaylock.
    // -f: fork so niri isn't blocked waiting for the lock process.
    Mod+O { spawn "swaylock" "-f"; }

    // Mod+Shift+O: quit niri (terminates the entire Wayland session).
    Mod+Shift+O { quit; }

    // Mod+Ctrl+O: immediately power off the machine via systemctl.
    Mod+Ctrl+O { spawn "systemctl" "poweroff"; }

    // Mod+Alt+O: open the power/session menu (pwr-dmenu.sh via wofi).
    // WHY separate from Mod+Ctrl+O: provides a confirmation UI before any
    // destructive action.
    Mod+Alt+O { spawn "bash" "-c" "~/.config/scripts/pwr-dmenu.sh"; }

    // Emergency quit: a deliberately awkward 4-modifier chord so it's
    // never triggered accidentally, but always reachable as a last resort.
    Mod+Alt+Ctrl+Shift+End { quit; }
}
