# This script flashes the current line when the cursor moves or the window is focused,
# to help highlight where the cursor is.
# Heavily inspired by the Beacon.nvim plugin: https://github.com/DanilaMihailov/beacon.nvim

declare-option str beacon_final_bg "5c6a72"
declare-option str beacon_refresh_interval "0.03"
declare-option -hidden str beacon_transition

declare-option -hidden str beacon_keys_normal "<c-f> <c-b> <c-d> <c-u> <pageup> <pagedown> ( ) m M <a-semicolon> n <a-n> N <a-N> u U"
declare-option -hidden str beacon_keys_goto "g k j e ."

lua %opt{beacon_final_bg} %{
    bg = tonumber(arg[1], 16)
    colors = ""

    -- Split the background into individual bytes.
    -- This will help ensure a smooth transition.
    bg_left = bg >> 16
    bg_center = (bg >> 8) & 0xFF
    bg_right = bg & 0xFF

    while true do
        bg_left = bg_left + 0x11
        if bg_left > 0xFF then
            break
        end

        -- Prevent the center bytes and rightmost bytes from "overflowing"
        -- and yielding an overall red color (which would look bad)
        bg_center = bg_center + 0x11
        if bg_center > 0xFF then
            bg_center = 0xFF
        end
        
        bg_right = bg_right + 0x11
        if bg_right > 0xFF then
            bg_right = 0xFF
        end
        
        bg = bg_right + (bg_center << 8) + (bg_left << 16)
        colors = "rgb:" .. string.format("%X", bg) .. " " .. colors
    end

    kak.set_option("global", "beacon_transition", colors)
}

define-command beacon %{
    # Since this requires running kak commands at a set time rather than all at the end,
    # using %sh{} instead of %lua{} is better here.
    nop %sh{
        (
            printf "%s\n" "evaluate-commands -client $kak_client %{ try %{
                               add-highlighter buffer/beacon group
                           }}" | kak -p $kak_session

            for color in $kak_opt_beacon_transition; do
                printf "%s\n" "
                    evaluate-commands -client $kak_client %{
                        evaluate-commands -draft %{
                            execute-keys x
                            declare-option range-specs beacon_range %val{timestamp} \"%val{selection_desc}|default,$color\"
                        }
                    try %{ add-highlighter buffer/beacon/$color ranges beacon_range }
                }" | kak -p $kak_session
                sleep $kak_opt_beacon_refresh_interval
            done

            printf "%s\n" "evaluate-commands -client $kak_client %{
                               try %{ remove-highlighter buffer/beacon }
                           }" | kak -p $kak_session
        ) >/dev/null 2>&1 </dev/null &
    }
} -hidden

hook global FocusIn .* beacon

hook global WinCreate .* %{
    lua %opt{beacon_keys_normal} %opt{beacon_keys_goto} %{
        for key in string.gmatch(arg[1], "[^%s]+") do
            kak.map("window", "normal", key, key .. ":beacon<ret>")
        end
        for key in string.gmatch(arg[2], "[^%s]+") do
            kak.map("window", "goto", key, key .. ":beacon<ret>")
        end
    }
    hook window RawKey '<mouse:press:left:.*>' beacon
}
