#!/bin/sh

PROG="${0##*/}"

SYSTEM_CONFIG="/etc/X11/xinit/Xkbmap"
LOCAL_CONFIG="$HOME/.Xkbmap"

### config

cat_config()
{
    touch "$SYSTEM_CONFIG" 2>/dev/null
    if [ -w "$SYSTEM_CONFIG" ];then
	cat "$SYSTEM_CONFIG"
    else
	cat "$LOCAL_CONFIG"
    fi
}

echo_config()
{
    if [ -w "$SYSTEM_CONFIG" ];then
	echo "$@" > "$SYSTEM_CONFIG"
    else
	echo "$@" > "$LOCAL_CONFIG"
    fi
}

### helpers

show_layout()
{
    local layout="$1";shift
    local variant="$1";shift
    local count=1

    local IFS=,
    set -- $variant
    
    for lay in $layout;do
	local var="$(eval echo \$$count)"
	if [ -n "$var" ];then
	    printf '%s(%s)\n' "$lay" "$var"
	else
	    printf '%s\n' "$lay"
	fi
	count=$((count + 1))
    done
}

show_grp()
{
    local IFS=,
    set -- $1
    for i in "$@";do
	if [ "$i" != "${i#grp:}" ];then
	    echo "$i"
	    break
	fi
    done
}

check_grp()
{
    echo "$1"|grep -qs '^grp:[^,]$'
    exit "$?"
}


show_config()
{
    local action="$1"
    local layout= variant= model= option=
    set -- $(cat_config)

    while [ $# -gt 0 ];do
	case "$1" in
	    -layout) layout="$2";shift;shift;;
	    -variant) variant="$2";shift;shift;;
	    -model) model="$2";shift;shift;;
	    -option) option="$2";shift;shift;;
	esac
    done

    layout="${layout#\"}"
    layout="${layout%\"}"
    
    case "$action" in
	model)	echo "$model";;
	grp)	show_grp "$option";;
	check)	check_grp "$option";;
	layout)	show_layout "$layout" "$variant";;
    esac
    
    
    exit
}

show_help()
{
	cat <<EOF
xkbmapconf - read and write ~/.Xkbmap and /etc/X11/xinit/Xkbmap config files

Usage: $PROG [option]

  Read options

  -h, --help		show this text and exit;
  -m, --get-model	read keyboard model;
  -g, --get-grp		read keyboard switch;
  -G, --check-grp	check for custom options;
  -l, --get-layout	read keyboard layout;
  -s, --save		save parameters.
    
Report bugs to http://bugs.altlinux.ru/

EOF
	exit
}

### main

save=
short_opt="h,m,l,g,G,s"
long_opt="help,get-model,get-layout,get-grp,check-grp,save"
temp=`getopt -n $PROG -o "$short_opt" -l "$long_opt" -- "$@"` || show_help
eval set -- "$temp"

while :; do
    case "$1" in
	-h|--help) show_help;;
	-m|--get-model) show_config "model";;
	-l|--get-layout) show_config "layout";;
	-g|--get-grp) show_config "grp";;
	-G|--check-grp) show_config "check";;
	-s|--save) save=1;;
	--)shift; break ;;
	*) echo "$1";show_help;;
    esac
    shift
done

[ -n "$save" ] && echo_config "$@"
