#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import string
import subprocess
import sys


KEYMATRIX = {'`': (3, 1), '1': (6, 1), '2': (6, 4), '3': (6, 2), '4': (6, 3),
             '5': (3, 3), '6': (3, 6), '7': (6, 6), '8': (6, 5), '9': (6, 9),
             '0': (6, 8), '-': (3, 8), '=': (0, 8), 'q': (7, 1), 'w': (7, 4),
             'e': (7, 2), 'r': (7, 3), 't': (2, 3), 'y': (2, 6), 'u': (7, 6),
             'i': (7, 5), 'o': (7, 9), 'p': (7, 8), '[': (2, 8), ']': (2, 5),
             '\\': (3, 11), 'a': (4, 1), 's': (4, 4), 'd': (4, 2), 'f': (4, 3),
             'g': (1, 3), 'h': (1, 6), 'j': (4, 6), 'k': (4, 5), 'l': (4, 9),
             ';': (4, 8), '\'': (1, 8), 'z': (5, 1), 'x': (5, 4), 'c': (5, 2),
             'v': (5, 3), 'b': (0, 3), 'n': (0, 6), 'm': (5, 6), ',': (5, 5),
             '.': (5, 9), '/': (5, 8), ' ': (5, 11), '<right>': (6, 12),
             '<alt_r>': (0, 10), '<down>': (6, 11), '<tab>': (2, 1),
             '<f10>': (0, 4), '<shift_r>': (7, 7), '<ctrl_r>': (4, 0),
             '<esc>': (1, 1), '<backspace>': (1, 11), '<f2>': (3, 2),
             '<alt_l>': (6, 10), '<ctrl_l>': (2, 0), '<f1>': (0, 2),
             '<search>': (0, 1), '<f3>': (2, 2), '<f4>': (1, 2), '<f5>': (3, 4),
             '<f6>': (2, 4), '<f7>': (1, 4), '<f8>': (2, 9), '<f9>': (1, 9),
             '<up>': (7, 11), '<shift_l>': (5, 7), '<enter>': (4, 11),
             '<left>': (7, 12)}


UNSHIFT_TABLE = { '~': '`', '!': '1', '@': '2', '#': '3', '$': '4',
                  '%': '5', '^': '6', '&': '7', '*': '8', '(': '9',
                  ')': '0', '_': '-', '+': '=', '{': '[', '}': ']',
                  '|': '\\',
                  ':': ';', '"': "'", '<': ',', '>': '.', '?': '/'}

for c in string.ascii_lowercase:
    UNSHIFT_TABLE[c.upper()] = c


def inject_event(key, press):
    if len(key) >= 2 and key[0] != '<':
        key = '<' + key + '>'
    if key not in KEYMATRIX:
        print "%s: invalid key: %s" % (this_script, key)
        sys.exit(1)
    (row, col) = KEYMATRIX[key]
    subprocess.call(["ectool", "kbpress", str(row), str(col),
                     "1" if press else "0"])


def inject_key(key):
    inject_event(key, True)
    inject_event(key, False)


def inject_string(string):
    for c in string:
        if c in KEYMATRIX:
            inject_key(c)
        elif c in UNSHIFT_TABLE:
            inject_event("<shift_l>", True)
            inject_key(UNSHIFT_TABLE[c])
            inject_event("<shift_l>", False)
        else:
            print "unimplemented character:", c
            sys.exit(1)


def usage():
    print "Usage: %s [-s <string>] [-k <key>]" % this_script, \
          "[-p <pressed-key>] [-r <released-key>] ..."
    print "Examples:"
    print "%s -s MyPassw0rd -k enter" % this_script
    print "%s -p ctrl_l -p alt_l -k f3 -r alt_l -r ctrl_l" % this_script


def help():
    usage()
    print "Valid keys are:"
    i = 0
    for key in KEYMATRIX:
        print "%12s" % key,
        i += 1
        if i % 4 == 0:
            print
    print
    print "angle brackets may be omitted"


def usage_check(asserted_condition, message):
    if asserted_condition:
        return
    print "%s:" % this_script, message
    usage()
    sys.exit(1)


# -- main

this_script = sys.argv[0]
arg_len = len(sys.argv)

if arg_len > 1 and sys.argv[1] == "--help":
    help()
    sys.exit(0)

usage_check(arg_len > 1, "not enough arguments")
usage_check(arg_len % 2 == 1, "mismatched arguments")

for i in range(1, arg_len, 2):
    usage_check(sys.argv[i] in ("-s", "-k", "-p", "-r"),
                "unknown flag: %s" % sys.argv[i])

for i in range(1, arg_len, 2):
    flag = sys.argv[i]
    arg = sys.argv[i+1]
    if flag == "-s":
        inject_string(arg)
    elif flag == "-k":
        inject_key(arg)
    elif flag == "-p":
        inject_event(arg, True)
    elif flag == "-r":
        inject_event(arg, False)
