#!/bin/bash

# This script contains utility functions related to X monitors.

_monitors=() # Cache for the xrandr output

# Get the list of connected and disconnected monitors.
# Usage: _get_monitors
_get_monitors() {
    set -euo pipefail
    local monitors enabled_regex="[[:digit:]]+x[[:digit:]]+\+[[:digit:]]+\+[[:digit:]]+" # Regex for enabled monitors

    if [ ${#_monitors[@]} -eq 0 ]; then
        monitors=$(xrandr | grep -Eo "^.* ((dis|)connected)( primary|) ($enabled_regex|)" | sed 's/ /,/g' | sed 's/,$//g')
        for monitor in $monitors; do
            if [[ "$monitor" =~ $enabled_regex ]]; then
                monitor="$monitor,enabled"
            else
                monitor="$monitor,disabled"
            fi
            _monitors+=("$monitor")
        done
    fi

    for monitor in "${_monitors[@]}"; do
        echo "$monitor"
    done
}

# Function to get all monitors with optional filters.
# Usage: get_monitors [filter1] [filter2] ...
get_monitors() {
    set -euo pipefail
    local monitors
    monitors=$(_get_monitors)

    if [ "$#" -eq 0 ]; then
        echo "$monitors"
        return 0
    fi

    for monitor in $monitors; do
        for filter in "$@"; do
            for part in ${monitor//,/ }; do
                if [ "$part" = "$filter" ]; then
                    echo "$monitor"
                    continue 3 # Continue to the next monitor
                fi
            done
        done
    done
}

# Check if the specified monitor is connected.
# Usage: monitor_exist <monitor_name>
monitor_exist() {
    set -euo pipefail
    local monitor=${1:?Monitor not set}
    local connected_monitors
    connected_monitors=$(get_monitors connected)

    for connected_monitor in $connected_monitors; do
        echo "Processing monitor $connected_monitor" 1>&2
        if [ "$(cut -d',' -f1 <<<"$connected_monitor")" = "$monitor" ]; then
            return 0
        fi
    done

    return 1
}

# Check if specified monitors are connected.
# Usage: monitors_exist <monitor1> [monitor2] ...
monitors_exist() {
    set -euo pipefail
    local monitor matches=0

    for monitor in "$@"; do
        echo "Checking if monitor $monitor exists" 1>&2
        if monitor_exist "$monitor"; then
            echo "$monitor"
            matches=$((matches + 1))
        fi
    done

    if [ "$matches" -ne "$#" ]; then
        echo "Amount of devices does not match the amount of arguments ($#: $*)" 1>&2
        return 1
    fi

    return 0
}

# Disable all monitors that are not connected.
# Usage: disable_disconnected_monitors
disable_disconnected_monitors() {
    set -euo pipefail
    local connected_monitors
    connected_monitors=$(get_monitors disconnected)

    echo "Disabling disconnected monitors"

    for monitor in $connected_monitors; do
        echo "Disabling monitor $(cut -d',' -f1 <<<"$monitor")"
        xrandr --output "$(cut -d',' -f1 <<<"$monitor")" --off
    done
}
