#!/bin/sh

# IVR - Interactive Voice Response Menus.

ast_add_module voicemenu
init_voicemenu() {
	ast_enable_type voicemenu
	ast_enable_type voiceoption
}
check_append_voicemenu() {
	local context="${1}"
	eval "local isadded=\"\${dialplan_add_voicemenu_${context}-0}\""
	if [ "$isadded" != "1" ] ; then
		eval "dialplan_add_voicemenu_${context}=1"
		append voicemenu_contexts "$context"
		return 0
	else
		return 1
	fi
}
voicemenu_list="greeting timeoutlen timeoutsmax invalidmax includelocal localmenu"

handle_voicemenu() {
	opt_voicemenu_context="$1"
	check_append_voicemenu "${opt_voicemenu_context}"

	option_cb() {
		case "$1" in
			greeting|timeoutlen|timeoutsmax|invalidmax|includelocal|localmenu)
				eval "opt_voicemenu_${opt_voicemenu_context}_$1=\"\$2\"" ;;
			_*) ;;
			*) logerror "Invalid Voicemenu option: $1" ;;
		esac
	}
}

voiceoption_list="digit menu dial goto"

check_add_voiceoption() {
	[ -z "${last_vo_voicemenu}" ] && return 0

	if [ -z "${last_vo_dial}" ] ; then
		append opt_voicemenu_${last_vo_voicemenu}_action "exten => ${last_vo_digit},1,Goto(${last_vo_goto},s,1)" "${N}"
	else
		append opt_voicemenu_${last_vo_voicemenu}_action "exten => ${last_vo_digit},1,Dial(${last_vo_dial})" "${N}"
	fi

	append opt_voicemenu_${last_vo_voicemenu}_menu "${last_vo_menu}" "&"

	for i in ${voiceoption_list} ; do
		eval "unset last_vo_$i"
	done

}

handle_voiceoption() {
	opt_voicemenu_context="$1"
	check_add voiceoption

	option_cb() {
		case "$1" in
			voicemenu|digit|menu|dial|goto)
				eval "last_vo_$1=\"\$2\"" ;;
			_*) ;;
			*) logerror "Invalid Voiceoption option in ${opt_voicemenu_context}: $1" ;;
		esac
	}
}

createdialplan_voicemenu(){
	logdebug 0 "Creating Voicemenu dialplans"
	[ -z "${voicemenu_contexts}" ]  && return 0

	for curvm in ${voicemenu_contexts} ; do
		check_add_context "${curvm}"
		for i in ${voicemenu_list} menu action ; do
			eval "vmc_${i}=\"\${opt_voicemenu_${curvm}_${i}}\""
		done

		[ -z "${vmc_timeoutlen}" ] && vmc_timeoutlen=5
		[ -z "${vmc_timeoutsmax}" ] && vmc_timeoutsmax=3
		[ -z "${vmc_invalidmax}" ] && vmc_invalidmax=0

		# Construct a voicemenu - with as small as possible code.
		local nn=1
		if [ ! -z "${vmc_greeting}" ] ; then
			append_dialplan_context $curvm "exten => s,${nn},Background(${vmc_greeting})"
			nn=n
		fi

		local againtimeout="(againtimeout)"
		if [ ${vmc_invalidmax} -gt 0 ] ; then
			append_dialplan_context $curvm "exten => s,${nn},Set(NUMINVALID=${vmc_invalidmax})"
			nn=n
		fi

		if [ ${vmc_timeoutsmax} -gt 0 ] ; then
			local labagaininvalid="(againinvalid)"
			if [ ${vmc_invalidmax} -le 0 ] ; then
				labagaininvalid=""
			fi
			append_dialplan_context $curvm "exten => s,${nn}${labagaininvalid},Set(NUMTIMEOUTS=${vmc_timeoutsmax})"
			nn=n
		else
			if [ ${vmc_invalidmax} -gt 0 ] ; then
				againtimeout="(againinvalid)"
			else
				againtimeout=
			fi
		fi
		if [ ! -z "${vmc_localmenu}" ] ; then
			append_dialplan_context $curvm "exten => s,${nn}${againtimeout},Background(${vmc_localmenu})"
			nn=n
			againtimeout=
		fi
		if [ ! -z "${vmc_menu}" ] ; then
			append_dialplan_context $curvm "exten => s,${nn}${againtimeout},Background(${vmc_menu})"
			againtimeout=
			nn=n
		fi
		append_dialplan_context $curvm "exten => s,${nn}${againtimeout},WaitExten(${vmc_timeoutlen})
exten => s,n,Goto(t,1)
exten => s,n(goodbye),Playback(vm-goodbye)
exten => s,n,Hangup()"
		if [ ${vmc_timeoutsmax} -gt 0 ] ; then
			append_dialplan_context $curvm "exten => t,1,Set(NUMTIMEOUTS=\$[\${NUMTIMEOUTS} - 1])
exten => t,n,Gotoif(\$[\${NUMTIMEOUTS} >= 0]?s,againtimeout:s,goodbye)"
		else
			append_dialplan_context $curvm "exten => t,1,Goto(s,goodbye)"
		fi
		append_dialplan_context ${curvm} "${vmc_action}"
		[ -z "${vmc_includelocal}" ] || append_dialplan_context ${curvm} "include => ${vmc_includelocal}"
		if [ ${vmc_invalidmax} -gt 0 ] ; then
			append_dialplan_context $curvm "exten => i,1,Set(NUMINVALID=\$[\${NUMINVALID} - 1])
exten => i,n,Background(invalid)
exten => i,n,Gotoif(\$[\${NUMINVALID} >= 0]?s,againinvalid:s,goodbye)"
		else
			append_dialplan_context $curvm "exten => i,1,Background(invalid)${N}exten => i,n,Goto(s,goodbye)"
		fi
	done

}


# vim: ts=2 sw=2 noet foldmethod=indent
