#
# ask
#
# Ask a question.
#

set -ue

exprpfx="#"                     # To avoid expr "/" bug

exprnum="^${exprpfx}[0-9][0-9]*$"
exprpath="^${exprpfx}/[-a-zA-Z0-9_./]*$"
exprstr="^${exprpfx}[-a-zA-Z0-9_./]*$"

aflag=
choice=
default=
help=
hidden=
menu=
num_max=
num_min=
pflag=
question=
split=' '

while [ $# -ne 0 ]
do
       case "${1}" in
       -H) hidden="${hidden} ${2}" ; shift 2 ;;
       -a) aflag=y ; shift 1 ;;
       -c) choice="${choice} ${2}" ; shift 2 ;;
       -d) default="${2}" ; shift 2 ;;
       -h) help="${2}" ; shift 2 ;;
       -m) menu="${2}" ; shift 2 ;;
       -p) pflag=y ; shift 1 ;;
       -q) question="${2}" ; shift 2 ;;
       -s) split='\n' ; shift 1 ;;
       -n)
               eval `echo "${2}" | (IFS="${IFS}:" ; read num_min num_max ;\
                        echo num_min=\'${num_min}\' num_max=\'${num_max}\')`
               shift 2 ;;
       -*)
               echo "${0}: \"${1}\": Unknown option" >&2
               exit 1 ;;
       *)
               echo "${0}: \"${1}\": Unknown operand" >&2
               exit 1 ;;
       esac
done

if [ -n "${num_min}" -a -n "${default}" ]
then
       if expr "${exprpfx}${default}" : "${exprnum}" > /dev/null
       then
               if [ ${default} -lt ${num_min} ]
               then
                       default=${num_min}
               elif [ ${default} -gt ${num_max} ]
               then
                       default=${num_max}
               fi
       fi
fi

while true
do
       if [ -n "${menu}" ]
       then
               echo "\n${menu}" >&2
       fi
       while true
       do
               echo "\n${question:-Choice?}${split}[${num_min:+ (${num_min} - ${num_max})}${aflag:+ (alphanumeric string)}${pflag:+ (pathname)}${choice}${help:+ help} ]${default:+ (default ${default})} \07\c" >&2
               if read answer
               then
                       :
               else
                       echo "EOF" >&2
                       continue
               fi
               if [ "'${answer}'" = "''" ]
               then
                       if [ -z "${default}" ]
                       then
                               echo "\nThere is no default answer." >&2
                               continue
                       fi
                       answer="${default}"
               fi
               if [ "'${answer}'" = "'magic mode'" ]
               then
                       if [ -n "${hidden}" ]
                       then
                               choice=" `echo ${choice} ${hidden}`"
                               hidden=
                               echo "\nPOOF!" >&2
                       else
                               echo "\nYour incantation has no effect." >&2
                       fi
                       continue
               fi
               if [ -n "${num_min}" ]
               then
                       if expr "${exprpfx}${answer}" : "${exprnum}" > /dev/null
                       then
                               if [ ${answer} -ge ${num_min} -a ${answer} -le ${num_max} ]
                               then
                                       echo ${answer}
                                       exit 0
                               fi
                       fi
               fi
               if [ -n "${help}" -a "'${answer}'" = "'help'" ]
               then
                       echo "\n${help}\n\nPress RETURN to continue \c" >&2
                       read x
                       break
               fi
               if [ ${aflag:-n} = y ]
               then
                       if expr "${exprpfx}${answer}" : "${exprstr}" > /dev/null
                       then
                               echo "${answer}"
                               exit 0
                       fi
               fi
               if [ ${pflag:-n} = y ]
               then
                       if expr "${exprpfx}${answer}" : "${exprpath}" > /dev/null
                       then
                               echo "${answer}"
                               exit 0
                       fi
               fi
               for x in ${choice}
               do
                       if [ "'${answer}'" = "'${x}'" ]
                       then
                               echo "${answer}"
                               exit 0
                       fi
               done
               echo "\nInvalid response ... please enter one of:" >&2
               if [ -n "${num_min}" ]
               then
                       echo "\to A number from ${num_min} thru ${num_max}" >&2
               fi
               if [ ${aflag:-n} = y ]
               then
                       echo "\to A string made up of letters, numbers, '-', '_' and '.'" >&2
               fi
               if [ ${pflag:-n} = y ]
               then
                       echo "\to An absolute pathname (\"/name[/name ...]\")" >&2
               fi
               for x in ${choice}
               do
                       echo "\to ${x}" >&2
               done
               if [ -n "${help}" ]
               then
                       echo "\to help" >&2
               fi
       done
done