#!/bin/bash

if test "${1:0:4}" != /dev ; then
    echo "Usage: keysymtab.sh /dev/input/event?"
    exit
fi

function display_selection {
    local VAL
    PS3="Your selection: "
    select VAL in "${@}" ; do
	if test -n "$VAL" ; then
	    REPLY="$VAL"
	    return
	fi
	echo "Invalid item!"
    done
}

echo "========================================="
echo "| keysymtab keyboard definition utility |"
echo "========================================="
echo
echo "If you have preliminary key binding table, please apply it now and restart"
echo "this utility."

# Read and parse keys.txt
unset ${!KEYGROUP_*}
exec 3<./keys.txt
exec 4>mykeymap.sh
echo >&4 "#!/bin/sh"
echo >&4 "source keycodes"

IFS_save="$IFS"
IFS=$'\t'
while read -u3 KEY KEYNAME GROUP ; do
    eval KEYGROUP_GROUP_${KEYNAME//[ \/-]/_}\=$GROUP
    eval KEYGROUP_INDEX_${KEYNAME//[ \/-]/_}\=\${#KEYGROUP_KEYNAME_$GROUP[@]}
    eval KEYGROUP_KEY_$GROUP[\${#KEYGROUP_KEY_$GROUP[@]}]\=\"\$KEY\"
    eval KEYGROUP_KEYNAME_$GROUP[\${#KEYGROUP_KEYNAME_$GROUP[@]}]\=\"\$KEYNAME\"
done
exec 3<&-
IFS="$IFS_save"
KEYGROUPS=${!KEYGROUP_KEY_*}
KEYGROUPS=${KEYGROUPS//KEYGROUP_KEY_}

# Main loop

OLD_GROUP=BasicKeyboard
while : ; do

    # Read key
    echo
    sleep 1
    echo -n "Press extended key, q for quit..."
    SCANCODE=$(./evdev_scancode $1)
    echo
    echo
    # Read possible garbage
    read -t1 -n1 -s
    KEYNAME=${SCANCODE##* }
    if test "$KEYNAME" = "$SCANCODE" ; then
	KEYNAME=
	KEYNUM=
    else
    KEYNUM=${SCANCODE#* }
    KEYNUM=${KEYNUM% *}
    fi
    SCANCODE=${SCANCODE%% *}

    if test "$KEYNAME" = Q ; then
	break
    fi

    if test -z "$KEYNAME" ; then
	GROUP=$OLD_GROUP
	echo "There is no candidate for this key."
	KEYNAME=
	PROMPT="Return, K, P) another Key from group $GROUP
G) select Group and key
Your choice: "
    else
	eval GROUP\=\"\$KEYGROUP_GROUP_${KEYNAME//[ \/-]/_}\"
	echo "Candidate is $GROUP/$KEYNAME."
	PROMPT="Return) OK
K) another Key from this group $GROUP
P) select key from previous group $OLD_GROUP
G) select Group and key
Your choice: "
    fi

	while : ; do

	read -n1 -p "$PROMPT"
	echo

    case $REPLY in
	K | k | "" )
	    if test -z "$KEYNAME" ; then
		REPLY=k
	    fi
	    break
	    ;;
	P | p )
	    GROUP=$OLD_GROUP
	    break
	    ;;
	G | g )
	    break
	    ;;
    esac
    done

while : ; do

    if test -z "$REPLY" ; then
    break
    fi

    if test "$REPLY" = G -o "$REPLY" = g ; then
    # Ask for group
    echo "Select key group:"
    display_selection ${KEYGROUPS[@]}
    GROUP="$REPLY"
    fi

    # Ask for key
    echo "Please select key:"
    eval display_selection \"Show\ groups\" \"\$\{KEYGROUP_KEYNAME_$GROUP\[@\]\}\"
    if test "$REPLY" = "Show groups" ; then
	REPLY=g
    else
    KEYNAME=$REPLY
    break
    fi
    done

    eval INDEX\=\"\$KEYGROUP_INDEX_${KEYNAME//[ \/-]/_}\"
    eval KEY\=\${KEYGROUP_KEY_$GROUP[\$INDEX]}

    echo
    echo "# $GROUP/$KEYNAME
setkeycodes $SCANCODE \$$KEY"
    echo >&4 "# $GROUP/$KEYNAME
setkeycodes $SCANCODE \$$KEY"


    OLD_GROUP=$GROUP
done

echo "Your key table was written to mykeymap.sh."
