
__debug_sxmoconf()
{
	if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
		echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
	fi
}

__prepare_sxmoconf()
{
	# Call _init_completion from the bash-completion package
	# to prepare the arguments properly
	if declare -F _init_completion >/dev/null 2>&1; then
		_init_completion -n =: || return
	fi

	if [ -z "$cur" ]; then
		max=$cword
	else
		max=$((cword - 1))
	fi
	csubs=$cword
	for i in $(seq 1 $max); do
		case "${words[i]}" in
		-*)
			csubs=$((csubs-1))
			;;
		"") ;;
		*)
			subs+=("${words[i]}")
			;;
		esac
	done
}

__matching_sxmoconf()
{
	# Count how many words are matching against sub-commands
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "list" ]; then
		msubs=1
	fi
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "set" ]; then
		msubs=1
	fi
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "get" ]; then
		msubs=1
	fi
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "del" ]; then
		msubs=1
	fi
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "toggle" ]; then
		msubs=1
	fi
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "is" ]; then
		msubs=1
	fi
	if [ "${#subs}" -ge "1" ] \
			&& [ "${subs[0]}" = "hooks" ]; then
		msubs=1
	fi
}

__suggestion_sxmoconf()
{
	# Compute suggestion list
	suggestions+=("-h	(Help)")
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("<subcommand>	(Argument)")
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("<args>	(Argument)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "list" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("[scope]	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("[section]	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("list	(Subcommand list)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "set" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<scope>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<section>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<config>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<value>	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("set	(Subcommand set)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "get" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<scope>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<section>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<config>	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("get	(Subcommand get)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "del" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<scope>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<section>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<config>	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("del	(Subcommand del)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "toggle" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<scope>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<section>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<config>	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("toggle	(Subcommand toggle)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "is" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<expected>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<scope>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<section>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<config>	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("is	(Subcommand is)")
	fi
	if [ "${#subs}" -gt "0" ] \
			&& [ "${subs[0]}" = "hooks" ]; then
	true # placeholder
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<scope>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<section>	(Argument)")
	fi
	if [ "${msubs}" -eq 1 ]; then
		suggestions+=("<config>	(Argument)")
	fi
	fi
	if [ "${msubs}" -eq 0 ]; then
		suggestions+=("hooks	(Subcommand hooks)")
	fi
}

__completion_sxmoconf()
{
	local cur prev words cword split max subs=() csubs=1 msubs=0
	local suggestions=() matching longest=0 temp

	__prepare_sxmoconf
	__matching_sxmoconf

	__debug_sxmoconf
	__debug_sxmoconf "========= starting completion logic =========="
	__debug_sxmoconf "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword"
	__debug_sxmoconf "subs[*] is ${subs[*]}, csubs is $csubs, msubs is $msubs"

	__suggestion_sxmoconf

	local IFS=$'\n'
	__debug_sxmoconf "suggestions[*] is:"
	__debug_sxmoconf "${suggestions[*]}"

	matching=($(compgen -W "${suggestions[*]}" -- "${words[${cword}]}"))
	__debug_sxmoconf "initial matching[*] is:"
	__debug_sxmoconf "${matching[*]}"

	if [ "${#matching[@]}" == "1" ]; then
		if [ "${matching[0]#*	}" = "(Argument)" ]; then
			unset matching[0]
		else
			matching[0]="${matching[0]%%	*}"
		fi
	else
		# Duplicate completion, or one single matching
		temp="${matching[0]%%	*}"
		for i in "${!matching[@]}"; do
			if [ "$temp" != "${matching[i]%%	*}" ]; then
				temp=
			fi
		done
		if [ -n "$temp" ]; then
			__debug_sxmoconf "truncated matching[*]"
			COMPREPLY=("${matching[0]%%	*}")
			return
		fi

		for i in "${!matching[@]}"; do
			temp="${matching[i]%%	*}"
			if [ $longest -lt "${#temp}" ]; then
				longest="${#temp}"
			fi
		done
		for i in "${!matching[@]}"; do
			matching[$i]="$(printf '%*s%*s' \
				"-$((longest+2))" \
				"${matching[i]%%	*}" \
				"-$((COLUMNS-longest-2))" \
				"${matching[i]#*	}")"
		done
	fi
	__debug_sxmoconf "final matching is:"
	__debug_sxmoconf "${matching[*]}"
	COMPREPLY=("${matching[@]}")
}

if [[ $(type -t compopt) = "builtin" ]]; then
	complete -o default -o nosort \
		-F __completion_sxmoconf sxmoconf
else
	complete -o default -o nosort -o nospace \
		-F __completion_sxmoconf sxmoconf
fi
