#!/usr/bin/python3
import re
import subprocess
import os
import sys
import getopt

variant_re = re.compile(r" *([^ ]*) *([^ ]*): (.*)")

#apply the keyboard layout choice
def apply_choice(choice):
    if choice == "none":
        # Reset user defined keyboard settings
        try:
            fp = open(vm_layout, 'w')
            fp.write("")
            fp.close()
            subprocess.check_call(['gsettings', 'reset', 'org.gnome.libgnomekbd.keyboard', 'layouts'])
        except:
            pass
    elif choice != "":
        try:
            file = open(vm_layout, 'w')
            file.write(choice)
            file.close()
            subprocess.check_call(['gsettings', 'set', 'org.gnome.libgnomekbd.keyboard', 'layouts', "['%s']" % choice])
        except:
            pass
    if os.path.exists('/etc/X11/xinit/xinitrc.d/qubes-keymap.sh'):
        # Fedora
        subprocess.check_call(['/etc/X11/xinit/xinitrc.d/qubes-keymap.sh'])
    elif os.path.exists('/etc/X11/Xsession.d/90qubes-keymap'):
        # Debian
        subprocess.check_call(['/etc/X11/Xsession.d/90qubes-keymap'])


#check for cmd line parameters
usage = "Usage: qubes-change-keyboard-layout [-h] [--help] [--layout=<keyboard-layout>]"
cmd_param_layout = ""
try:
    opts, args = getopt.getopt(sys.argv[1:], "h", ["help", "layout="])
except getopt.GetoptError:
    print(usage)
    sys.exit()
for opt, arg in opts:
    if opt in ("-h", "--help"):
        print(usage)
        sys.exit()
    elif opt in ("-l", "--layout"):
        cmd_param_layout = arg

#get the current userset layout
vm_layout = "%s/.config/qubes-keyboard-layout.rc" % os.getenv("HOME")
cur_user_layout = ""
if os.path.isfile(vm_layout):
    try:
        fp = open(vm_layout,'r')
        cur_user_layout = fp.read().strip()
        fp.close()
    except IOError:
        pass

#In case command lines were passed (do not show gui)
if cmd_param_layout != "":
    apply_choice(cmd_param_layout)
    sys.exit()


# get the list of all xkb layouts
xkb_rules_base = "/usr/share/X11/xkb/rules/base.lst"

layouts = []
xkb_rules = open( xkb_rules_base)

l = xkb_rules.readline()
while not (l.startswith("!") and l.startswith("! layout")):
    l = xkb_rules.readline()

#layouts section starts

l = xkb_rules.readline().strip()
while l.strip() != "":
    pair = re.split("\s+", l, maxsplit=1)
    layouts.append(pair)
    l = xkb_rules.readline().strip()

while not (l.startswith("!") and l.startswith("! variant")):
    l = xkb_rules.readline()

while l.strip() != "":
    m = variant_re.match(l.strip())
    if m:
        layouts.append(("%s+%s" % (m.group(2), m.group(1)), m.group(3)))
    l = xkb_rules.readline().strip()

xkb_rules.close()

layouts.sort(key=lambda x: x[1])

# create  list dialog
zenity_cmd = ['zenity', '--list', '--text', "Choose desired keyboard layout.", '--radiolist']
zenity_cmd.append( "--title='Keyboard Layout'")
zenity_cmd.append("--height=500")
zenity_cmd.append("--width=350")
zenity_cmd.append('--column')
zenity_cmd.append("")
zenity_cmd.append('--column')
zenity_cmd.append("Code")
zenity_cmd.append('--column')
zenity_cmd.append("Full name")

if cur_user_layout == "":
    zenity_cmd.append("TRUE")
else:
    zenity_cmd.append("FALSE")

zenity_cmd.append("none")
zenity_cmd.append("Qubes default layout")

for l in layouts:
    if l[0] == cur_user_layout:
        zenity_cmd.append("TRUE")
    else:
        zenity_cmd.append("FALSE")
    zenity_cmd.append(l[0])
    zenity_cmd.append(l[1])

p = subprocess.Popen(zenity_cmd, stdout=subprocess.PIPE)
choice = p.communicate()[0]
choice = choice.strip()
apply_choice(choice)


