#!/usr/bin/env python
#
# manjaro-kb: a script to read openbox's rc.xml and write out the keybinds
# Copyright (C) 2010 wlourf
# Copyright (C) 2015 damo <damo@bunsenlabs.org>
#
# forked by manjaro <fhatmanjaroorg>
#
# fixed zenity display by using --font=monospace
#

import sys
import os
import datetime
import argparse

try:
    from lxml import etree
except ImportError:
    import xml.etree.ElementTree as etree

ICON = "/usr/share/icons/manjaro/maia/48x48.png"
FILENAME = "$HOME/.config/openbox/kbinds.txt"
DLG_HEIGHT = "500"
DLG_WIDTH = "900"
DLG_FONT = "monospace 6"

# path and name of the rc.xml and saved keybinds files
rc_fpath = os.environ["HOME"] + "/.config/openbox/rc.xml"
kb_fpath = os.environ["HOME"] + "/.config/openbox/kbinds.txt"
arrShortcut = []
gui = False

def cmdargs():
    """get command arguments"""
    if len(sys.argv) > 1:
        if sys.argv[1] == "--gui":
            gui = True
            return gui
        else:
            msg = "\n\n\tUSAGE: to display keybinds in a text window use 'manjaro-kb --gui'\n\n"
            msg += "\tRunning the script without args will send output to the terminal\n\n"
            print(msg)
            sys.exit()


def keyboard():
    """read keyboard shorcuts"""
    # Parse xml
    str_root = "{http://openbox.org/3.4/rc}"
    tree = etree.parse(rc_fpath)
    root = tree.getroot()

    for k in root.findall(str_root + "keyboard/" + str_root + "keybind"):
        key = k.get("key")
        action_element = k.find(str_root + "action")
        str_txt = ""
        str_type = "o "  # flag for pipemenu: Openbox window command
        if action_element is not None:
            arrShortcut.append((key, "", ""))
            if action_element.get("name") == "Execute":
                name_element = action_element.find(str_root + "name")
                command_element = action_element.find(str_root + "command")
                exec_element = action_element.find(str_root + "execute")
                str_type = "x "  # flag for pipemenu: Run command

                if name_element is not None:
                    str_txt = name_element.text
                elif command_element is not None:
                    str_txt = command_element.text
                elif exec_element is not None:
                    str_txt = exec_element.text
            elif action_element.get("name") == "ShowMenu":
                menu_element = action_element.find(str_root + "menu")
                if menu_element is not None:
                    str_txt = menu_element.text
            else:
                action_name = action_element.get("name")
                if action_name is not None:
                    str_txt = action_name
            arrShortcut[len(arrShortcut) - 1] = (str_type, key, str_txt)


def output_keybinds(shortcut_arr, is_gui):
    """loop through array, and format output then write to file"""
    for i in range(0, len(shortcut_arr)):
        exe = str(shortcut_arr[i][0])
        keybinding = str(shortcut_arr[i][1]).strip()
        execute = str(shortcut_arr[i][2]).strip()
        if is_gui:  # format output for text window
            if len(execute) > 80:
                execute = execute[:70] + "..."
            line = "{:2}".format(i) + "\t" + "{:<16}".format(keybinding) + "\t" + execute
            # if len(keybinding) >= 15:
            #     line = "{:2}".format(i) + "\t" + "{:<16}".format(keybinding) + "\t" + execute
            # elif len(keybinding) >= 10:
            #     line = "{:2}".format(i) + "\t" + "{:<15}".format(keybinding) + "\t\t\t" + execute
            # elif len(keybinding) >= 8:
            #     line = "{:2}".format(i) + "\t" + "{:<14}".format(keybinding) + "\t\t\t\t" + execute
            # else:
            #     line = "{:2}".format(i) + "\t" + "{:<13}".format(keybinding) + "\t\t\t\t" + execute
        else:  # format text for pipemenu
            line = exe + "{:<16}".format(keybinding) + "\t" + execute
            print(line)
        write_file(line)


def check_rcfile(fpath, mode):
    """Check if rc.xml exists, and is accessible"""
    try:
        f = open(fpath, mode)
    except IOError as e:
        return False
    return True


def write_file(line):
    """Text file to store keybinds"""
    f = open(kb_fpath, 'a')
    f.write(line + "\n")
    f.close()


def check_txtfile(kb_filepath):
    """Create Text file to store keybinds"""
    try:
        f = open(kb_filepath, 'w')
    except IOError as e:
        return False
    return True


if __name__ == "__main__":

    ap = argparse.ArgumentParser(description="Display keybinds")
    ap.add_argument("-g", "--gui", help="display keybinds in a text window", action="store_true")
    opts = ap.parse_args(sys.argv[1:])
    gui = opts.gui
    check_txtfile(kb_fpath)
    if gui:  # output formatted keybinds text in text window
        write_file(str(datetime.date.today()) + "\trc.xml KEYBINDS")
        write_file("-------------------------------\n")

    if check_rcfile(rc_fpath, "r"):
        keyboard()
        output_keybinds(arrShortcut, gui)
    else:
        MSG = "\nCan't open rc.xml for parsing\n\
        Check the filepath given: " + rc_fpath + "\n"
        print(MSG)
        sys.exit(1)

    if gui:  # output formatted keybinds text in text window
        DLG = f"zenity --text-info --title='Openbox Keybinds' "
        DLG += f"--window-icon={ICON} "
        DLG += f"--filename={FILENAME} "
        DLG += f"--width={DLG_WIDTH} --height={DLG_HEIGHT} "
        DLG += f"--font={DLG_FONT}"
        os.system(DLG)
