#!/bin/bash

# INIT
echo "$$" > "$HOME/.cache/pidofbar"

# MODULES
update_crypto() {
    crypto="$(crypto)"
}

update_cpu() {
    cpu=" $(grep -o "^[^ ]*" /proc/loadavg)"
}

update_memory() {
    memory=" $(free -h | sed -n '2s/\([^ ]* *\)\{2\}\([^ ]*\).*/\2/p')"
}

update_bat() {
    local dir; dir="$(echo /sys/class/power_supply/BAT*/ | sort -n | tail -n1)"

    bat="$(grep -q Charging "$dir/status" && printf '' || printf '')"
    bat="$bat $(cat "$dir/capacity")%"
}

update_vol() {
    local v; v="$(wpctl get-volume '@DEFAULT_AUDIO_SINK@')"

    if grep -q 'MUTED' <<< "$v"; then
        vol='🔇'
    else
        vol=" $((10#$(tr -dc '0-9' <<< "$v")))"
    fi
}

update_wlp() {
    local sig; sig="$(grep wlp /proc/net/wireless | awk '{print $3 * 100}')"
    local ssid; ssid="$(nmcli -t -f name,device connection show --active | grep wlp | cut -d: -f1)"

    [ -z "$ssid" ] && wlp='⚠' && return
    [ -z "$sig"  ] && sig=0

    # https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/main/src/libnmc-base/nm-client-utils.c#L628
    { [ "$sig" -gt 5600 ] && wlp="▂▄▆█ $ssid"; } ||
    { [ "$sig" -gt 3850 ] && wlp="▂▄▆_ $ssid"; } ||
    { [ "$sig" -gt 1650 ] && wlp="▂▄__ $ssid"; } ||
    { [ "$sig" -gt  275 ] && wlp="▂___ $ssid"; } ||
    {                        wlp="____ $ssid"; }
}

update_time() {
    time="$(date "+%a %m/%d %R")"
}

# For calcurse users, refer https://github.com/pystardust/automeet
#update_event () {
#   event="$(calcurse -n | sed 1d | \
#       sed -E "s_^ *\[(.*):(.*)\] ([^\t]*)\t?.*_[\1h \2m->\3]_")"
#   [ "[]" = "$event" ] && event=""
#}

# modules that don't update on their own need to be run at the start for getting their initial value
while [ -z "$(wpctl get-volume '@DEFAULT_AUDIO_SINK@' 2> /dev/null)" ]; do
    sleep 1
done
update_vol

reload_bar() {
    sec=0
}

display() {
    xsetroot -name "$crypto | $cpu | $memory | $vol | $wlp | $bat | $time"
}

# SIGNALING
# trap  '<function>;display'       'RTMIN+n'
trap    'reload_bar;display'       'RTMIN'
trap    'update_vol;display'       'RTMIN+1'
trap    'update_crypto;display'    'RTMIN+2'
# to update it from external commands
## kill -m "$(cat ~/.cache/pidofbar)"
# where m = 34 + n

sec=0
while true; do
    [ "$((sec % 3600))" = 0 ] && update_crypto
    [ "$((sec % 5   ))" = 0 ] && {
        update_time
        update_cpu
        update_memory
        update_bat
        update_wlp
        display
    }

    sleep 1 & wait
    sec="$((sec + 1))"
done
