#!/bin/sh

DSESSIONBUS=`ls -t ~/.dbus/session-bus/* | head -n1`
if [ -n "$DSESSIONBUS" -a -f "$DSESSIONBUS" ]; then
 . $DSESSIONBUS
 export DBUS_SESSION_BUS_ADDRESS 
fi

function jackctl {
  dbus-send --session --print-reply --dest=org.jackaudio.service \
            /org/jackaudio/Controller \
             org.jackaudio.JackControl.$1
}

function jackcfg {
  dbus-send --session --print-reply --dest=org.jackaudio.service \
            /org/jackaudio/Controller \
             org.jackaudio.Configure.SetParameterValue \
            array:string:$1,$2 \
            variant:$3:"$4" >/dev/null
}

function jackget {
  dbus-send --session --print-reply --dest=org.jackaudio.service \
            /org/jackaudio/Controller \
             org.jackaudio.Configure.GetParameterValue \
            array:string:$1,$2
}

function jackports {
  dbus-send --session --print-reply --dest=org.jackaudio.service \
            /org/jackaudio/Controller \
             org.jackaudio.JackPatchbay.GetAllPorts \
  | awk '/string "(.*)"/{match($0, /string "(.*)"/, a); printf "\"%s\"\n", a[1]; }'
}

function jackconnections {
  dbus-send --session --print-reply --dest=org.jackaudio.service \
            /org/jackaudio/Controller \
             org.jackaudio.JackPatchbay.GetGraph \
            uint64:0 \
  | awk 'BEGIN{i=0;} /^   array/{i++;} /^      }/{if (i==2) printf "\n";} /string "(.*)"/ {if (i==2) {match($0, /string "(.*)"/, a); printf "string:\"%s\" ", a[1]; } }'
}

function connect_ports {
  eval `echo \
  dbus-send \
    --session \
    --print-reply \
    --dest=org.jackaudio.service \
    /org/jackaudio/Controller \
    org.jackaudio.JackPatchbay.ConnectPortsByName \
    $@` > /dev/null
}

function switch2 {
  CONNECTIONS=$(jackconnections)
  # TODO: remember device name of old interface
  jackctl SwitchMaster > /dev/null
  jack_wait -w -t 5 > /dev/null
  # TODO: get device name of new interface

	# TODO restore connections to physical ports: 'system' and similar phyical IDs!!)
  CONNECTIONS=$(echo "$CONNECTIONS" | grep '"system"')
	# TODO Map connections e.g.
  # replace    string:"system" string:"playback_1" -> string:"ffado" string:"playback_7" 
  # replace    string:"system" string:"playback_2" -> string:"ffado" string:"playback_8"
  IFS=$'\n'
  for line in $CONNECTIONS; do 
    #echo "connect ${line}"
		connect_ports ${line}
  done
}

function start {
  DRIVER=${1-"alsa"}
  DEVICE=${2-"hw:0"}
  if [ "$DRIVER" == "dummy" ];then
		PNUMP=${3-"2"}
		PNUMC=${4-"2"}
		PERIOD=0
		RATE=0
		NPERIODS=0
		MIDI=""
	else
		PERIOD=${3-"1024"}
		RATE=${4-"48000"}
		NPERIODS=${5-"3"}
		MIDI=${6-"none"}
  fi

  jackcfg engine driver string "$DRIVER"
  test "$DRIVER" == "dummy" -o -z "$DEVICE"|| jackcfg driver device string "$DEVICE"
  test "$DRIVER" == "dummy" -a -n "$PNUMP" && jackcfg driver playback uint32 "$PNUMP"
  test "$DRIVER" == "dummy" -a -n "$PNUMC" && jackcfg driver capture  uint32 "$PNUMC"

  test $RATE -eq 0   || jackcfg driver rate uint32 $RATE
  test $PERIOD -eq 0 || jackcfg driver period uint32 $PERIOD
  test $NPERIODS -eq 0 -o "$DRIVER" == "dummy" || \
		                    jackcfg driver nperiods  uint32 $NPERIODS
  test "$DRIVER" == "dummy" -o -n "$MIDI" || jackcfg driver midi-driver string "$MIDI"

  jackctl IsStarted | grep "boolean false" >/dev/null && (
		jackcfg engine realtime boolean true
		jackcfg engine realtime-priority int32 70
		jackcfg engine sync boolean true
	  jackctl StartServer > /dev/null
	)
}

if [ "$1" == "config" ];then
  jackget engine driver | tail -n1 | awk '{printf "SNDDRV=%s\n",$3;}'
  jackget driver device | tail -n1 | awk '{printf "SNDDEV=%s\n",$3;}'
	#echo "PNUMC=\"`jack_lsp | grep system:capture  | wc -l`\""
  echo "PNUMC=\"`jackports |  grep system:capture  | wc -l`\""
	#echo "PNUMP=\"`jack_lsp | grep system:playback | wc -l`\""
	echo "PNUMP=\"`jackports | grep system:playback | wc -l`\""
  exit
fi

#dbus-send --system /org/rncbc/qjackctl org.rncbc.qjackctl.stop
start $@
switch2

#test "$1" == "dummy" || \
#  dbus-send --system /org/rncbc/qjackctl org.rncbc.qjackctl.start
