#!/bin/bash
# Fast Site Engine. Copyright © AC (acwed@ya.ru), 2004-2024. All rights reserved. 2-clause BSD license.
declare -A AC;
profile(){
  local P=${1-0} O='' I='' T='' R='^[0-9]+$' U='output:' A='analog-' S='stereo' M='mono' D='surround' H='hdmi-' N='input:'
  for ((I=0; I<4; I++)); do O=${P:0:1}; P=${P:1}
    if [[ $O =~ $R ]]; then T+=$O; else
      if [[ -n $T ]]; then P=$O$P; O=$T; fi; break
    fi
  done
  I=$P
  if [[ $O == '958' ]]; then O=$U'iec958-'$S
  elif [[ $O == '0' || $O = 'o' ]]; then O='off'; I=''
  elif [[ $O =~ $R ]]; then O=$U$A$D'-'$O
  elif [[ $O == 's' ]]; then O=$U$A$S
  elif [[ $O == 'd' ]]; then I=''; P=${P//[^0-9]}; T=${#P}
    if ((T == 3)); then I=${P: -1}; P=${P:0:2}
    elif ((T == 1)); then I=$P; P=''; fi
    if [[ -z $P ]]; then O=$U$H$S
    else O=$U$H$D; [[ $P != '51' ]] && O+=$P; fi
    if [[ -n $I && $I -gt 1 ]]; then ((I--)); O+='-extra'$I ; fi; I=''
  elif [[ $O == 'i' ]]; then O=''
  elif [[ $O == 'p' ]]; then O='pro-audio'; I=''
  elif [[ $O == 'm' ]]; then O=$U$A$M; fi
  if [[ $I == 'm' ]]; then I=$N$A$M;
  elif [[ $I == 's' ]]; then I=$N$A$S; fi
  if [[ -n $I ]]; then [[ -n "$O" ]] && O+='+'$I || O=$I; fi; echo $O
}
setp(){
  local C=${1-} A=${2-} B=${3-}
  pactl set-card-profile "${AC[$C'n']}" "$A"
  if [[ -n $B ]]; then fcards 1; echo -e "z 2=  ${AC[$C'a']} == $A  $C" "$A" "$B"    [[ $A != ${AC[$C'a']} ]] && pactl set-card-profile "${AC[$C'n']}" "$B"; fi
  fcards 1
  setvol 'all' '-1%'
  setvol 'all' '+1%'
}
setprofile(){
  local P=${1-}' ' C=${2-} A='' B='' I=0
  P=(${P// / }); A=$(profile "${P[0]}")
  [[ -n ${P[1]} ]] && B=$(profile "${P[1]}")
  if [[ $C == 'all' ]]; then
    for ((I=0; I < 9; I++)); do
      [[ -z ${AC[$I]+x} ]] && break
      setp "$I" "$A" "$B"
    done
  else C=$(getcard "$C"); [[ -n $C ]] && setp "$C" "$A" "$B"; fi
}
if [[ $A1 == 'set' ]]; then fcards 1; setprofile "$A2" "$A3"; exit 0; fi
seth(){
  local C=${1-} A=${2-} B=${3-} N=${4-} M=${5-} J=''
  J=${AC[$C'a']}; [[ $J == $A || $J == $B ]] && setp "$C" "$N" "$M" || setp "$C" "$A" "$B"
}
toggle(){
  local P=${1-}' ' R=${2-}' ' C=${3-} A='' B='' N='' M='' J='' I=0
  P=(${P// / }); A=$(profile "${P[0]}")
  if [[ -n ${P[1]} ]]; then B=$(profile "${P[1]}"); fi
  R=(${R// / }); N=$(profile "${R[0]}")
  if [[ -n ${R[1]} ]]; then M=$(profile "${R[1]}"); fi
  if [[ $C == 'all' ]]; then
    for ((I=0; I < 9; I++)); do
      [[ -n ${AC[$I]+x} ]] && seth "$I" "$A" "$B" "$N" "$M"
    done
  else C=$(getcard "$C"); [[ -n $C ]] && seth "$C" "$A" "$B" "$N" "$M"; fi
}
if [[ $A1 == 'toggle' ]]; then fcards 1; toggle "$A2" "$A3" "$A4";  exit 0; fi
showcards(){
  local I=0 P='' O='' J='' R='' A='\033[1;34m' B='' G='\033[0;32m' N='\033[0m' D=' Default ' Y='\033[1;30m'
  B=' '$A' '; echo -e '\n\n'$B$D'Card:'$N' '${AC['def']}'\n'$B$D'Sink:'$N' '${AC['sink']}'\n'$B$D'Source:'$N' '${AC['source']}'\n\n'
  for ((I=0; I < 9; I++)); do
    [[ -z ${AC[$I]+x} ]] && continue
    R=${AC[$I'r']}; R=${R//RUNNING/${G}RUNNING${N}}
    J=${AC[$I'i']}; J=${J//,/${A},${N}}; J=${J//: /${A}: ${N}}; J=${J//(available)/${G}(available)${N}}; J=${J//(not available)/${Y}(not available)${N}}
    O=${AC[$I'o']}; O=${O//,/${A},${N}}; O=${O//: /${A}: ${N}}; O=${O//(available)/${G}(available)${N}}; O=${O//(not available)/${Y}(not available)${N}}
    P=${AC[$I'p']}; P=${P//,/${A},${N}}; P=${P//: /${A}: ${N}}
    echo -e $S$B'Card: '$N$I'   '$B'State: '$N$R'   '$B'Name: '$N${AC[$I'd']}'\n\n   '$B'Device: '$N${AC[$I'n']}'   '$B'Bus path: '$N${AC[$I'b']}'\n   '$B'Sink: '$N${AC[$I's']}'   '$B'Sink id: '$N${AC[$I'j']}'\n\n   '$B'Inputs: '$N$J'\n   '$B'Outputs: '$N$O'\n\n   '$B'Active Profile: '$N${AC[$I'a']}'\n   '$B'Profiles: '$N$P'\n\n'
  done
}
if [[ $A1 == 'showcards' ]]; then fcards 1; showcards; exit 0; fi
PDIR=~/.var/app/com.github.wwmm.easyeffects/config/easyeffects/autoload/output/
setp(){
  local I=${1-} P='' J='' D='' N='' T='' O='' K=''
  O=${AC[$I'o']// /§}; O=(${O//,/ }); for ((K=0; K < ${#O[*]}; K++)); do T=${O[$K]/%:§*}; O[$K]=${T//§}; done
  P=${AC[$I'p']// /§}; P=(${P//,§/ })
  for J in ${P[*]}; do
    if [[ $J =~ 'output' && ! $J =~ '+' ]]; then
      T=${AC[$I'd']/#* - }
      J=(${J//output:}); J=${J/%§Output}
      N=${J/#*:§}; N=${N//§/ }
      J=${J/%:§*}
      if [[ -z $A4 ||  $J =~ $A4 ]]; then
        D='alsa_output.'${AC[$I'b']//:/_}'.'$J
        for K in ${O[*]}; do
          if [[ -z $A5 || $K =~ $A5 ]]; then
            echo -e '{\n"device": "'$D'",\n"device-description": "'$T' '$N'",\n"device-profile": "'$K'",\n"preset-name": "'$A2'"\n}' > $PDIR$D':'$K'.json'
          fi
        done
      fi
    fi
  done
  D=${AC[$I'n']}
  J=${AC[$I'a']}
  pactl set-card-profile "$D" 'off'
  pactl set-card-profile "$D" "$J"
}
setpreset(){
  local I=0
  if [[ -z $A2 ]]; then echo 'Error: preset not filed'; return 1; fi
  if [[ -n $A4 && ${#A4} -lt 5 ]]; then I=$(profile "$A4"); I=${I//output:}; A4=${I/%+*}; fi
  if [[ -z $A3 || $A3 == 'all' ]]; then
    for ((I=0; I < 9; I++)); do [[ -n ${AC[$I]+x} ]] && setp "$I"; done
    fcards 1
    for ((I=0; I < 9; I++)); do
      if [[ -n ${AC[$I]+x} ]]; then setv '-1%' "$I"; setv '+1%' "$I"; fi
    done
  else
    I=$(getcard "$A3");
    setp "$I"
    fcards 1
    setv '-1%' "$I"
    setv '+1%' "$I"
  fi
}
if [[ $A1 == 'setpreset' ]]; then mkdir -p $PDIR; fcards 1; setpreset; fi
starticon(){
  local F=${1-} V=${2-} D=~/.config/autostart/
  mkdir -p $D; F=$D$F.desktop
  if [[ -z $A3 ]]; then rm -f "$F"; else echo -e "$V" > $F; chmod +x "$F"; fi
}
usricon(){
  F=/usr/share/applications/$A2.desktop
  if [[ -z $A3 ]]; then sudo rm -f "$F"; else
    echo -e '[Desktop Entry]\nType=Application\nName='$A3'\nComment=fsesound '$A4'\nExec=/usr/bin/fsesound '$A4'\nIcon=preferences-desktop-sound\nCategories=AudioVideo;Audio;\nStartupNotify=false\nTerminal=false' | sudo tee "$F" > /dev/null
    sudo chmod +x "$F"
  fi
}
if [[ $A1 == 'icon' ]]; then
  if [[ $A2 == 'start' ]]; then
    starticon 'fsesound' '[Desktop Entry]\nType=Application\nName=fseSound\nComment=Задать громкость '$A3'%\nExec=/usr/bin/fsesound start '$A3'\nIcon=preferences-desktop-sound\nStartupNotify=false\nTerminal=false'
  elif [[ $A2 == 'starteasyeffects' ]]; then
    starticon 'com.github.wwmm.easyeffects' '[Desktop Entry]\nType=Application\nName=com.github.wwmm.easyeffects\nExec=/usr/bin/flatpak run --command=easyeffects com.github.wwmm.easyeffects --gapplication-service\nX-Flatpak=com.github.wwmm.easyeffects\nIcon=com.github.wwmm.easyeffects\nStartupNotify=false\nTerminal=false'
  else usricon; fi
  exit 0;
fi
lfw(){
  local F=${1-} D=${2-0}
  if (( $D == 0 )); then sudo sed -i -e 's/^.*channelmix.upmix.*$/    #channelmix.upmix = false/g' "$F"
  else sudo sed -i -e 's/^.*channelmix.upmix.*$/    channelmix.upmix = true/g' "$F"; fi
}
lfp(){
  local F=${1-} D=${2-0}
  if (( $D == 0 )); then sudo sed -i -e 's/^.*remixing-produce-lfe.*$/; remixing-produce-lfe = no/g' -e 's/^.*remixing-consume-lfe.*$/; remixing-consume-lfe = no/g' -e 's/^.*lfe-crossover-freq.*$/; lfe-crossover-freq = 0/g' "$F"
  else sudo sed -i -e 's/^.*remixing-produce-lfe.*$/remixing-produce-lfe = yes/g' -e 's/^.*remixing-consume-lfe.*$/remixing-consume-lfe = yes/g' -e 's/^.*lfe-crossover-freq.*$/lfe-crossover-freq = 150/g' "$F"; fi
}
upmix(){
  local D=${1-0} E='/etc' H='/hone/'$USER'/.config' P='/pulse/daemon.conf' T='/usr/share' W='/pipewire/' N='pipewire-pulse.conf'
  D=${D,,}
  if [[ $D == 0 || $D == 'off' ]]; then
    [[ -e $E$P ]] && lfp "$E$P"
    [[ -e $H$P ]] && lfp "$H$P"
    [[ -e $E$W$N ]] && lfw "$E$W$N" # /etc/pipewire/pipewire-pulse.conf
    [[ -e $H$W$N ]] && lfw "$H$P" # ~/.config/pipewire/pipewire-pulse.conf
  else
    [[ -e $E$P ]] && lfp "$E$P" 1
    [[ -e $H$P ]] && lfp "$H$P" 1
    if [[ -e $T$W$N ]]; then
      if ! [[ -e $E$W$N ]]; then sudo mkdir -p "$E$W"; sudo cp -v "$T$W$N" "$E$W"; fi
      lfw "$E$W$N" 1
      [[ -e $H$W$N ]] && lfw "$H$P" 1
      # systemctl --user restart pipewire.service pipewire-pulse
      # systemctl --user daemon-reload
    fi
  fi
}
if [[ $A1 == 'lfe' ]]; then upmix "$A2"; fi
