#! /bin/ksh

#
# Name        : ${HOME}/bin/GetKey.ksh
#
# Version     : 1.0
#
# Author      : Gerard van Wageningen
#
# Description : Read character or character sequence
#
# 1.0   First Version
#

\whence set_debug 1>/dev/null 2>&1 && eval $( set_debug ${0##*/} )

typeset KEY		; set -A KEY
typeset CAPACITY	; set -A CAPACITY
typeset SEQUENCE	; set -A SEQUENCE
typeset -i i
typeset -i j
typeset tmp
typeset chars
typeset matchingChars
typeset -i found=2
typeset -i max
typeset -i candidate
typeset -i length 
typeset OLD_STTY

OLD_STTY=$( stty -g )
(( $? != 0 )) && exit 1

i=0
for tmp in \
  'kf1 <F1>' \
  'kf2 <F2>' \
  'kf3  F3>' \
  'kf4 <F4>' \
  'kf5 <F5>' \
  'kf6 <F6>' \
  'kf7 <F7>' \
  'kf8 <F8>' \
  'kf9 <F9>' \
  'kf10 <F10>' \
  'kf11 <F11>' \
  'kf12 <F12>' \
  'kcuu1 <CursorUp>' \
  'kcud1 <CursorDown>' \
  'kcuf1 <CursorForward>' \
  'kcub1 <CursorBack>' \
  'kpp <PageUp>' \
  'knp <PageDown>' \
  'kdch1 <Del>' \
  'kbs <Backspace>' \
  'kend <End>' \
  'khome <Home>'
do
  KEY[i]="${tmp#*\ }"
  CAPACITY[i]="${tmp%\ *}"
  SEQUENCE[i]=$( tput "${CAPACITY[i]}" 2>/dev/null )
  if (( $? == 0 ))
  then
    i=i+1
  fi
done
# stty -a | grep = | tr -s ';' '\n' | tr -d ' '
for tmp in \
  '\033[A <CursorUp>' \
  '\033[B <CursorDown>' \
  '\033[C <CursorForward>' \
  '\033[D <CursorBack>' \
  '\r <Enter>' \
  '\b <Backspace>' \
  '\033[\0364 <Home>' \
  '\033[1\0176 <Home>' \
  '\033[ <End>' \
  '\033[4\0176 <End>' \
  '\003 <Control-C>' \
  '\006 <Control-F>' \
  '\032 <Control-Z>'
do
  KEY[i]="${tmp#*\ }"
  SEQUENCE[i]=$( print -n "${tmp%\ *}" )
  j=0
  while (( j < i ))
  do
    if [[ "${SEQUENCE[j]}" = "${SEQUENCE[i]}" ]]
    then
      break
    fi
    j=j+1
  done
  if (( j == i ))
  then
    i=i+1
  fi
done
max=i

chars=''
matchingChars=''
found=2
length=0


stty -icanon -echo raw

while (( found > 1 ))
do

  tmp=$( dd if=/dev/tty bs=1 count=1 2>/dev/null )
  chars="${chars}${tmp}"
  case "${tmp}"
  in
    \[|\(|\|) tmp="\\${tmp}" ;;
    *) ;;
  esac
  matchingChars="${matchingChars}${tmp}"
  length=length+1


  found=0
  i=0
  while (( i < max )) && (( found < 2 ))
  do
    [[ -n "${DEBUG:-}" ]] && print -u2 [[ "${SEQUENCE[i]}" = ${matchingChars}* ]]
    if [[ "${SEQUENCE[i]}" = ${matchingChars}* ]]
    then
      found=found+1
      candidate=i
    fi
    i=i+1
  done

  case "${found}"
  in
    0) print -n "${chars}" ;;
    1) if (( length == ${#SEQUENCE[candidate]} ))
       then
         print -n "${KEY[candidate]}"
       else 
	 found=2
       fi
       ;;
    *) ;;
  esac
  [[ -n "${DEBUG:-}" ]] && print -u2 "${#chars}: ${found} ${candidate} $( print -n ${chars} | xxd )"
done

stty ${OLD_STTY}

[[ -n "${DEBUG:-}" ]] && print -u2 "${#chars}: ${found} ${candidate}"

return 0


################################## EOF ################################
