from maya import cmds, mel
from dmptools.setup.items import markingMenuItems as MARKING_MENU_ITEMS
from dmptools.setup.items import hotkeyItems as HOTKEY_ITEMS
from dmptools.setup.items import shelfItems as SHELF_ITEMS

# the concataneted dicts
ITEMS = MARKING_MENU_ITEMS+HOTKEY_ITEMS+SHELF_ITEMS
# the concataneted list of the item strs
SCROLL_ITEMS = []

def printHelp(item):
    """experimental help printer"""

    itemCommand = item['command']
    # strip the pyton strings
    command = itemCommand.replace('python("', '').replace('");', '')
    # split the command to find modules
    cmdSplit = command.split(';')
    # normal command is to have 3 executions: 0- import 1- reload 2- function execution
    if len(cmdSplit) == 3:
        evalCmd = cmdSplit[0]
        reloadCmd = cmdSplit[1]
        function = cmdSplit[2]
        # eval the command for the print to work
        exec(evalCmd)
        # find and print the function doc
        func = function.split('(')[0]

        # print help
        print '\n', evalCmd, '->', function
        print eval(func).__doc__,

    # unknown command split
    else:
        print 'wrong command'

def filterItems(*args):
    """
    function that's triggered every time a letter is added to the filter field
    clear the scrolllist and append the filtered ones """

    hotkeyFilter = cmds.textFieldGrp('itemsFilterField', text=True, q=True)
    filteredItems = []
    # for item in cmds.textScrollList('dmptoolsItemsScrollList', allItems=True, q=True):
    if 'key ' in hotkeyFilter:
        tmpitem = 'type a letter/number to find what hotkey it is mapped to.'
        filteredItems.append(tmpitem)

        for item in SCROLL_ITEMS:
            try:
                if hotkeyFilter.split()[1].lower() in item.split():
                    filteredItems.append(item)
                    filteredItems.remove(tmpitem)
            except:
                pass
    else:
        for item in SCROLL_ITEMS:
            if hotkeyFilter in item.lower():
                filteredItems.append(item)

    # remove all items and refill with the filtered one
    cmds.textScrollList('dmptoolsItemsScrollList', e=True, removeAll=True)
    cmds.textScrollList('dmptoolsItemsScrollList', e=True, append=filteredItems)

def showHelp():
    """Prints out the help for the selected item"""

    itemName = cmds.textScrollList('dmptoolsItemsScrollList', q=True, si=True)[0].split('\t')[-1].replace('| ', '')

    for item in ITEMS:
        if item['name'] == itemName:
            printHelp(item)
        if 'menu' in item.keys():
            if item['menu']:
                for menu_item in item['menuItems']:
                    if menu_item['name'] == itemName:
                        printHelp(item)

def executeCommand():
    """Action of double clicking on item"""

    itemName = cmds.textScrollList('dmptoolsItemsScrollList', q=True, si=True)[0].split('\t')[-1].replace('| ', '')
    # find command on item
    for item in ITEMS:
        # assume the item is in hotkeys or marking menu
        if 'command' in item.keys():
            if item['name'] == itemName:
                command = item['command']
        # assume the item is in shelf menu items
        if 'menu' in item.keys():
            if item['menu']:
                for menu_item in item['menuItems']:
                    if not 'divider' in menu_item['name'] and menu_item['name'] == itemName:
                        command = menu_item['command']
    # check if the command is in python or mel
    if not 'python' in command:
        commandExec = 'python("'+command+'");'
    else:
        commandExec = command
    # execute the command in mel
    mel.eval(commandExec)

def createScrollList():
    """Go through all the items lists and generate a string list for the scrollList UI"""

    scrollList = []
    # get values of hotkey items
    for item in HOTKEY_ITEMS:
        name = item['name']
        key = [item['key'] if not 'space' in item['key'] else 'spac'][0].lower()
        ctl = item['ctrl']
        alt = item['alt']
        command = item['command']
        release = item['release']
        shift = ['shift ' if item['key'].isupper() else ''][0]

        namePart1 = ['ctrl' if ctl else ''][0]+[' alt' if alt else ''][0]+' '+shift+str(key)

        appendName = namePart1+'\thotkey\t'+str(name)
        scrollList.append(appendName)

    # get values of marking menu items
    for item in MARKING_MENU_ITEMS:
        name = item['name']
        command = item['command']
        if not 'separator' in name:
            scrollList.append('\tmarking menu\t'+str(name))

    # get values of shelf menu items
    for item in SHELF_ITEMS:
        if 'menu' in item.keys():
            if item['menu']:
                for menu_item in item['menuItems']:
                    if not 'divider' in menu_item['name']:
                        scrollList.append('\tshelf\t'+str(menu_item['name']))

    # returning the list of strings for the UI
    return scrollList

def showItemsUI():
    """Shows a window with all items available"""

    windowName = 'dmptools_items_window'
    controlName = 'dmptools_items_ctrl'
    title = 'dmptools item list'
    try:
        cmds.deleteUI(controlName, control=True)
    except:
        pass
    try:
        cmds.deleteUI(windowName, window=True)
    except:
        pass

    cmds.window(windowName, title=title)
    form = cmds.formLayout()
    itemsFilterField = cmds.textFieldGrp('itemsFilterField', l='filter:', tcc=filterItems, annotation='start typing something to filter the list of hotkeys.\
                                            \ntype: "key <letter/number>" to filter only by hotkey key.')
    scrollListField = cmds.textScrollList('dmptoolsItemsScrollList')

    # use the string list and generate the scroll list for the UI
    for item in createScrollList():
        # append to global var
        SCROLL_ITEMS.append(item)
        # append to the actual scroll list
        cmds.textScrollList('dmptoolsItemsScrollList', e=True, append=item, dcc=executeCommand, sc=showHelp, ann='Click on the item to print the help about it.\
                                                                                                        \nYou can double click the item to execute the associated command.')
    closeButton = cmds.button('itemsCloseButton',
                label="Close",
                c='import maya.cmds as cmds;cmds.deleteUI("'+controlName+'", control=True)')
    
    # attach the ui elements to the main form layout
    cmds.formLayout(form, e=True,
                        attachForm=[
                                        (itemsFilterField, 'top', 5),
                                        (itemsFilterField, 'left', 5),
                                        (itemsFilterField, 'right', 5),
                                        (scrollListField, 'left', 5),
                                        (scrollListField, 'right', 5),
                                        (closeButton, 'left', 5),
                                        (closeButton, 'right', 5),
                                        (closeButton, 'bottom', 5),
                                    ],
                        attachControl=[
                                        (scrollListField, "top", 5, itemsFilterField),
                                        (scrollListField, "bottom", 5, closeButton)
                                    ]
                    )
    # create a dockable window if dockable is true
    cmds.dockControl(controlName, label=title, floating=False, area='right', content=windowName)

def main():
    """UI that shows a list of all the available executable items (from hotkeys to marking menu items)"""
    
    controlName = 'dmptools_items_ctrl'
    try:
        cmds.deleteUI(controlName, control=True)
    except:
        showItemsUI()