# -*- coding: utf-8 -*-
#*****************************************************************************
#       Copyright (C) 2003-2006 Gary Bishop.
#       Copyright (C) 2006  Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#*****************************************************************************
from __future__ import print_function, unicode_literals, absolute_import
import System
from .common import validkey, KeyPress, make_KeyPress_from_keydescr

c32 = System.ConsoleKey
Shift = System.ConsoleModifiers.Shift
Control = System.ConsoleModifiers.Control
Alt = System.ConsoleModifiers.Alt
# table for translating virtual keys to X windows key symbols
code2sym_map = {#c32.CANCEL:    'Cancel',
                c32.Backspace:  'BackSpace',
                c32.Tab:        'Tab',
                c32.Clear:      'Clear',
                c32.Enter:      'Return',
#                c32.Shift:     'Shift_L',
#                c32.Control:   'Control_L',
#                c32.Menu:      'Alt_L',
                c32.Pause:      'Pause',
#                c32.Capital:   'Caps_Lock',
                c32.Escape:     'Escape',
#                c32.Space:     'space',
                c32.PageUp:     'Prior',
                c32.PageDown:   'Next',
                c32.End:        'End',
                c32.Home:       'Home',
                c32.LeftArrow:  'Left',
                c32.UpArrow:    'Up',
                c32.RightArrow: 'Right',
                c32.DownArrow:  'Down',
                c32.Select:     'Select',
                c32.Print:      'Print',
                c32.Execute:    'Execute',
#                c32.Snapshot:  'Snapshot',
                c32.Insert:     'Insert',
                c32.Delete:     'Delete',
                c32.Help:       'Help',
                c32.F1:         'F1',
                c32.F2:         'F2',
                c32.F3:         'F3',
                c32.F4:         'F4',
                c32.F5:         'F5',
                c32.F6:         'F6',
                c32.F7:         'F7',
                c32.F8:         'F8',
                c32.F9:         'F9',
                c32.F10:        'F10',
                c32.F11:        'F11',
                c32.F12:        'F12',
                c32.F13:        'F13',
                c32.F14:        'F14',
                c32.F15:        'F15',
                c32.F16:        'F16',
                c32.F17:        'F17',
                c32.F18:        'F18',
                c32.F19:        'F19',
                c32.F20:        'F20',
                c32.F21:        'F21',
                c32.F22:        'F22',
                c32.F23:        'F23',
                c32.F24:        'F24',
#                c32.Numlock:    'Num_Lock,',
#                c32.Scroll:     'Scroll_Lock',
#                c32.Apps:       'VK_APPS',
#                c32.ProcesskeY: 'VK_PROCESSKEY',
#                c32.Attn:       'VK_ATTN',
#                c32.Crsel:      'VK_CRSEL',
#                c32.Exsel:      'VK_EXSEL',
#                c32.Ereof:      'VK_EREOF',
#                c32.Play:       'VK_PLAY',
#                c32.Zoom:       'VK_ZOOM',
#                c32.Noname:     'VK_NONAME',
#                c32.Pa1:        'VK_PA1',
                c32.OemClear:  'VK_OEM_CLEAR',
                c32.NumPad0:    'NUMPAD0',
                c32.NumPad1:    'NUMPAD1',
                c32.NumPad2:    'NUMPAD2',
                c32.NumPad3:    'NUMPAD3',
                c32.NumPad4:    'NUMPAD4',
                c32.NumPad5:    'NUMPAD5',
                c32.NumPad6:    'NUMPAD6',
                c32.NumPad7:    'NUMPAD7',
                c32.NumPad8:    'NUMPAD8',
                c32.NumPad9:    'NUMPAD9',
                c32.Divide:     'Divide',
                c32.Multiply:   'Multiply',
                c32.Add:        'Add',
                c32.Subtract:   'Subtract',
                c32.Decimal:    'VK_DECIMAL'
               }

# function to handle the mapping
def make_keysym(keycode):
    try:
        sym = code2sym_map[keycode]
    except KeyError:
        sym = ''
    return sym

sym2code_map = {}
for code,sym in code2sym_map.items():
    sym2code_map[sym.lower()] = code

def key_text_to_keyinfo(keytext):
    '''Convert a GNU readline style textual description of a key to keycode with modifiers'''
    if keytext.startswith('"'): # "
        return keyseq_to_keyinfo(keytext[1:-1])
    else:
        return keyname_to_keyinfo(keytext)


def char_to_keyinfo(char, control=False, meta=False, shift=False):
    vk = (ord(char))
    if vk & 0xffff == 0xffff:
        print('VkKeyScan("%s") = %x' % (char, vk))
        raise ValueError('bad key')
    if vk & 0x100:
        shift = True
    if vk & 0x200:
        control = True
    if vk & 0x400:
        meta = True
    return (control, meta, shift, vk & 0xff)

def keyname_to_keyinfo(keyname):
    control = False
    meta = False
    shift = False

    while 1:
        lkeyname = keyname.lower()
        if lkeyname.startswith('control-'):
            control = True
            keyname = keyname[8:]
        elif lkeyname.startswith('ctrl-'):
            control = True
            keyname = keyname[5:]
        elif lkeyname.startswith('meta-'):
            meta = True
            keyname = keyname[5:]
        elif lkeyname.startswith('alt-'):
            meta = True
            keyname = keyname[4:]
        elif lkeyname.startswith('shift-'):
            shift = True
            keyname = keyname[6:]
        else:
            if len(keyname) > 1:
                return (control, meta, shift, sym2code_map.get(keyname.lower()," "))
            else:
                return char_to_keyinfo(keyname, control, meta, shift)

def keyseq_to_keyinfo(keyseq):
    res = []
    control = False
    meta = False
    shift = False

    while 1:
        if keyseq.startswith('\\C-'):
            control = True
            keyseq = keyseq[3:]
        elif keyseq.startswith('\\M-'):
            meta = True
            keyseq = keyseq[3:]
        elif keyseq.startswith('\\e'):
            res.append(char_to_keyinfo('\033', control, meta, shift))
            control = meta = shift = False
            keyseq = keyseq[2:]
        elif len(keyseq) >= 1:
            res.append(char_to_keyinfo(keyseq[0], control, meta, shift))
            control = meta = shift = False
            keyseq = keyseq[1:]
        else:
            return res[0]

def make_keyinfo(keycode, state):
    control = False
    meta  =False
    shift = False
    return (control, meta, shift, keycode)


def make_KeyPress(char, state, keycode):

    shift = bool(int(state) & int(Shift))
    control = bool(int(state) & int(Control))
    meta = bool(int(state) & int(Alt))
    keyname = code2sym_map.get(keycode, "").lower()
    if control and meta: #equivalent to altgr so clear flags
        control = False
        meta = False    
    elif control:
        char = str(keycode)
    return KeyPress(char, shift, control, meta, keyname)

