#!/bin/sh

get_cards() {
	pacmd list-cards | awk -F '[\t ]+' '
	function printcard() {
		print cardindex " " cardname " " carddesc
	}
	
	$2 ~ "index:" {
		if(incard) {
			printcard()
		}
		incard=1
		cardindex=$3
	}
	incard && $2 ~ "name:" {
		cardname=substr($3, 2, length($3) - 2)
	}
	incard && $2 ~ "device.description" {
		carddesc=substr($0, index($0, "= ") + 2)
	}
	END {
		printcard()
	}
	'
}

# First line will always be the active profile
get_selected_card_profiles() {
	pacmd list-cards | awk -F '[\t ]+' \
		-v selected_card_index="$selected_card_index" '
	BEGIN {
		profile_count=0
	}
	function print_card() {
		if(do_print) {
			print profile_names[i] " " profile_descs[i]
		}
	}
		
	$2 ~ "index:" && $3 == selected_card_index {
		incard=1
	}
	incard && $2 ~ "profiles:" {
		inprofiles=1
		next
	}
	inprofiles && $2 ~ "active" {
		for(i = 0; i < profile_count; i++) {
			if(profile_names[i] == substr($4, 2, length($4) - 2)) {
				current_card_index=i
				do_print=1
			}
			print_card()
		}
		for(i = 0; i < current_card_index; i++) {
			print_card()
		}
		exit
	}
	inprofiles {
		profile_names[profile_count] = substr($2, 0, length($2) - 1)
		profile_descs[profile_count] = substr($0, index($0, ": ") + 2)
		profile_count++
	}
	'
}

select_default_sink_card() {
	selected_card=$(pacmd list-sinks | awk -F '[\t ]+' '
	$2 == "*" && $3 ~ "index:" {
		incard=1
	}
	incard && $2 == "card:" {
		print $3 " " substr($4, 2, length($4) - 2)
		exit
	}
	')
}

select_card_manually() {
	card_options=$(get_cards)
	selected_option_index=$(printf %s\\n "$card_options" | rofi -dmenu -format 'i')
	selected_option_index=$((selected_option_index+1))
	selected_card=$(printf %s\\n "$card_options" | sed -n "${selected_option_index}p")
}

print_usage() {
	printf '
Usage: le-audio [OPTIONS]
Manage audio profiles

Options
    -a        Auto   - Auto-select the card for the default sink
    -f        Filter - Filter out "off" profiles
    -c        Cycle  - Auto-select the next audio profile after the current one
    
Utility written by Dakedres (dakedres.sys42.net)
'
}

while getopts 'afc' args; do
	case "$args" in
		a)
			arg_auto_select_card=true
			;;

		f)
			arg_filter_off_profile=true
			;;

		c)
			arg_select_next_profile=true
			;;

		?)
			print_usage
			exit
			;;

		*)
			>&2 echo "Invalid option '${args}'"
	esac
done

if [ "$arg_auto_select_card" = true ]; then
	select_default_sink_card
else
	select_card_manually
fi

selected_card_index=$(printf %s\\n "$selected_card" | awk '{ print $1 }')
echo "$selected_card"

if [ "$arg_filter_off_profile" = true ]; then
   selected_card_profiles=$(get_selected_card_profiles | grep -v '^off')
else
   selected_card_profiles=$(get_selected_card_profiles)
fi

if [ "$arg_select_next_profile" = true ]; then
	selected_profile_index=1
else
	selected_profile_index=$(printf %s\\n "$selected_card_profiles" | rofi -dmenu -format "i")
fi

if [ -z "$selected_profile_index" ]; then
	>&2 echo "No profile selected"
	exit 1
fi

printf %s\\n "$selected_card_profiles" | awk \
	-v selected_profile_index="$selected_profile_index" \
	-v selected_card="$selected_card" \
	-v qt="'" '
NR-1 == selected_profile_index {
	split(selected_card, split_card, " ")
	printf "pactl set-card-profile" " " split_card[1] " " $1
	$1=""
	print " && notify-send " qt "Set audio profile to" $0 qt
}
' | sh
