-- Set programs that you use
-- Generated by hyprlang2lua. Review TODOs before reloading Hyprland.

local terminal = "FONTCONFIG_FILE=/home/sudacode/.config/ghostty/ghostty-fonts.conf uwsm app -sa -- ghostty"
local fileManager = "uwsm app -sa -- thunar"
-- $menu = rofi -show drun
-- https://github.com/Vladimir-csp/uwsm#2-service-startup-notification-and-vars-set-by-compositor
-- $menu = rofi -show drun -run-command "uwsm app -- {cmd}"
local menu = "~/.config/rofi/launchers/type-6/launcher.sh 1"
-- See https://wiki.hyprland.org/Configuring/Keywords/
local mainMod = "ALT" -- Sets "Windows" key as main modifier

-- Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
hl.bind("SUPER + SUPER_L", hl.dsp.exec_cmd("~/.config/rofi/launchers/type-2/launcher.sh 10"))
hl.bind(mainMod .. " + RETURN", hl.dsp.exec_cmd(terminal))
hl.bind(mainMod .. " + Q", hl.dsp.window.close())
hl.bind(mainMod .. " + SHIFT + M", hl.dsp.exec_cmd("uwsm stop"))
hl.bind(mainMod .. " + E", hl.dsp.exec_cmd(fileManager))
hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }))
hl.bind(mainMod .. " + d", hl.dsp.exec_cmd(menu))
-- bind = $mainMod, P, pseudo, # dwindle
hl.bind(mainMod .. " + SHIFT + p", hl.dsp.exec_cmd("~/.local/bin/hyprland-pin.sh"))
-- bind = $mainMod, t, togglesplit, # dwindle
hl.bind(mainMod .. " + f", hl.dsp.window.fullscreen(""))
hl.bind(mainMod .. " + i", hl.dsp.window.cycle_next(""))

-- Move focus with mainMod + arrow keys
hl.bind(mainMod .. " + h", hl.dsp.focus({ direction = "left" }))
hl.bind(mainMod .. " + l", hl.dsp.focus({ direction = "right" }))
hl.bind(mainMod .. " + k", hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + j", hl.dsp.focus({ direction = "down" }))

hl.bind(mainMod .. " + SHIFT + j", hl.dsp.window.move({ direction = "d" }))
hl.bind(mainMod .. " + SHIFT + k", hl.dsp.window.move({ direction = "u" }))
hl.bind(mainMod .. " + SHIFT + h", hl.dsp.window.move({ direction = "l" }))
hl.bind(mainMod .. " + SHIFT + l", hl.dsp.window.move({ direction = "r" }))
hl.bind(mainMod .. " + SHIFT + c", hl.dsp.window.center())

-- Move focus to next monitor
hl.bind("CTRL+ALT + j", hl.dsp.focus({ monitor = "r" }))
hl.bind("CTRL+ALT + k", hl.dsp.focus({ monitor = "l" }))

-- Switch workspaces with mainMod + [0-9]
for i = 1, 10 do
	local key = i % 10
	hl.bind(
		mainMod .. " + " .. key,
		hl.dsp.focus({
			workspace = i,
			silent = true,
		})
	)
end
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
for i = 1, 10 do
	local key = i % 10 -- workspace 10 maps to key 0
	hl.bind(
		mainMod .. " + SHIFT + " .. key,
		hl.dsp.window.move({
			workspace = i,
			follow = false,
			silent = true,
		})
	)
end

-- Example special workspace (scratchpad)
-- hl.bind("SUPER + S", hl.dsp.workspace.toggle_special("magic"))
-- hl.bind("CTRL + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" }))

-- Scroll through existing workspaces with mainMod + scroll
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))

-- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })

-- Laptop multimedia keys for volume and LCD brightness
hl.bind(
	"XF86AudioRaiseVolume",
	hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"),
	{ locked = true, repeating = true }
)
hl.bind(
	"XF86AudioLowerVolume",
	hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"),
	{ locked = true, repeating = true }
)
hl.bind(
	"XF86AudioMute",
	hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"),
	{ locked = true, repeating = true }
)
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), { locked = true, repeating = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { locked = true, repeating = true })
hl.bind("F12", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true })
hl.bind("F11", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true })
hl.bind("F10", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true })

-- Requires playerctl
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("mpc next"), { locked = true })
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("mpc toggle"), { locked = true })
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("mpc toggle"), { locked = true })
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("mpc prev"), { locked = true })
hl.bind("F9", hl.dsp.exec_cmd("playerctl next"), { locked = true })
hl.bind("F8", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("F7", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
-- bindl = , XF86AudioStop, exec, mpc stop

-- rofi
hl.bind(mainMod .. " + SHIFT + v", hl.dsp.exec_cmd("uwsm app -sb -- rofi-rbw"))
-- bind = $mainMod, w, exec, rofi -show window -theme $HOME/.config/rofi/launchers/type-2/style-2.rasi -dpi 96  -theme-str 'window {width: 35%;}'
hl.bind(mainMod .. " + SHIFT + w", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-wallpaper.sh"))
hl.bind(mainMod .. " + SHIFT + d", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-docs.sh"))
hl.bind("SUPER + SHIFT + j", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-jellyfin-dir.sh"))
hl.bind("SUPER + t", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-launch-texthooker-steam.sh"))
hl.bind(mainMod .. " + SHIFT + t", hl.dsp.exec_cmd("~/projects/scripts/popup-ai-translator.py"))
hl.bind("SUPER + SHIFT + g", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-vn-helper.sh"))
hl.bind(mainMod .. " + SHIFT + i", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-image-browser.sh"))

-- ncmcppp
hl.bind(mainMod .. " + n", hl.dsp.exec_cmd("uwsm app -sb -- ghostty --command=/usr/bin/ncmpcpp"))

-- notifications
hl.bind(mainMod .. " + SHIFT + n", hl.dsp.exec_cmd("swaync-client -t"))

-- mpv add
hl.bind("SUPER + m", hl.dsp.exec_cmd("~/.local/bin/mpv-add.sh"))

-- hl.bind("SUPER + SHIFT + s", hl.dsp.exec_cmd("slurp | grim -g - - | wl-copy"))
hl.bind("SUPER + SHIFT + s", hl.dsp.exec_cmd([[sh -c 'grim -g "$(slurp -d)" - | wl-copy']]))
hl.bind("code:107", hl.dsp.exec_cmd("~/.local/bin/screenshot"))
hl.bind("SHIFT + code:107", hl.dsp.exec_cmd("~/.local/bin/screenshot-active-window.sh"))
hl.bind("SUPER + code:107", hl.dsp.exec_cmd("~/.local/bin/screenshot-active-window.sh -s"))
hl.bind("SUPER + o", hl.dsp.exec_cmd("~/.local/bin/ocr.sh"))
hl.bind(mainMod .. " + o", hl.dsp.exec_cmd("~/.local/bin/rofi-open tab"))
-- bind = $mainMod SHIFT, o, exec, ~/.local/bin/rofi-open window

-- change wallpaper
hl.bind(mainMod .. " + CTRL + n", hl.dsp.exec_cmd("~/.local/bin/change-wallpaper"))

-- toggle focus between current and last focused window
-- hl.bind("ALT + Tab", hl.dsp.focus({ urgent_or_last = true }))
-- hl.bind("ALT + Tab", hl.dsp.window.cycle_next())
hl.bind("ALT + Tab", hl.dsp.focus({ last = true }))

hl.bind("CTRL + F9", hl.dsp.pass({ window = "class:^(com\\.obsproject\\.Studio)$" }))
hl.bind("CTRL + F10", hl.dsp.pass({ window = "class:^(com\\.obsproject\\.Studio)$" }))
-- Discord mute: also re-bound inside the "clean" submap below so it keeps working there
local function bindDiscordMute()
	hl.bind("CTRL + SHIFT + M", hl.dsp.pass({ window = "class:^(discord)$" }))
end
bindDiscordMute()

hl.bind("CTRL + SHIFT + D", hl.dsp.exec_cmd("~/.local/bin/dragon"))
hl.bind("CTRL + ALT + F", hl.dsp.exec_cmd("~/.local/bin/favorite-wallpaper"))

hl.bind(mainMod .. " + z", hl.dsp.exec_cmd("uwsm app -sb -- zen-browser"))

hl.bind(
	mainMod .. " + SHIFT + s",
	hl.dsp.exec_cmd(
		'rofi -show ssh -theme "'
			.. "~/.config/rofi/launchers/type-2/style-2.rasi\" -terminal -theme-str 'window{width: 25%;} listview {columns: 1; lines: 10;}' ghostty -ssh-command \"ghostty --initial-command='TERM=kitty ssh {host}'\""
	)
)

-- reload monitors
-- hl.bind(
-- 	"CTRL" .. mainMod .. " + SHIFT + R",
-- 	hl.dsp.exec_cmd("hyprctl dispatch dpms off && sleep 1 && hyprctl dispatch dpms on")
-- )

-- Disable keybinds with one master keybind
local function disableMouseWindowBinds()
	hl.unbind(mainMod .. " + mouse:272")
	hl.unbind(mainMod .. " + mouse:273")
end

local function restoreMouseWindowBinds()
	hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
	hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
end

hl.bind(mainMod .. " + Page_Down", function()
	disableMouseWindowBinds()
	hl.dispatch(hl.dsp.submap("clean"))
end)
hl.define_submap("clean", function()
	-- Page Up: exit clean submap
	hl.bind(mainMod .. " + Page_Up", function()
		restoreMouseWindowBinds()
		hl.dispatch(hl.dsp.submap("reset"))
	end)
	-- only other keybind allowed in clean
	bindDiscordMute()
end)

hl.bind("SUPER + l", hl.dsp.exec_cmd("hyprlock"))

-- ANKI
hl.bind(mainMod .. " + a", hl.dsp.exec_cmd("~/.config/rofi/scripts/rofi-anki-script.sh"))
-- bind = $mainMod SHIFT, a, exec, ~/projects/scripts/screenshot-anki.sh -cdMinecraft

-- GSM
-- mouse:275 / BTN_SIDE and mouse:276 / BTN_EXTRA pass through as native back/forward.
-- hl.bind("mouse:275", hl.dsp.exec_cmd("xdotool key alt+w"), { locked = true })
-- hl.bind("mouse:276", hl.dsp.exec_cmd("xdotool key alt+grave"), { locked = true })
hl.bind("ALT + g", hl.dsp.exec_cmd("/opt/mpv-yomitan/mpv-yomitan.AppImage --toggle"))

hl.bind("ALT + SHIFT + f", hl.dsp.exec_cmd("uwsm app -sb -- flameshot gui"))

-- F5
-- bind = ,code:71, exec, ~/projects/scripts/whisper_record_transcribe.py --mode toggle --output type
hl.bind(
	"code:71",
	hl.dsp.exec_cmd(
		"uv run --directory ~/projects/scripts/faster-whisper-transcribe faster-whisper-transcribe --backend ctranslate2 --device cpu --mode toggle --output type"
	)
)

-- SubMiner
hl.bind("ALT + SHIFT + O", hl.dsp.pass({ window = "class:^(SubMiner)$" }))
hl.bind("ALT + SHIFT + I", hl.dsp.pass({ window = "class:^(SubMiner)$" }))
hl.bind("ALT + SHIFT + C", hl.dsp.pass({ window = "class:^(SubMiner)$" }))

-- gsm
hl.bind("ALT + w", hl.dsp.pass({ window = "class:gamesentenceminer" }))

-- {{{ scrolling
hl.bind(mainMod .. " + comma", hl.dsp.layout("swapcol l"))
hl.bind(mainMod .. " + period", hl.dsp.layout("fit all"))
hl.bind(mainMod .. " + slash", hl.dsp.layout("fit active"))
-- }}}
