from Screens.Screen import Screen
from Screens.ParentalControlSetup import ProtectedScreen
from Components.Sources.List import List
from Components.ActionMap import NumberActionMap
from Components.Sources.StaticText import StaticText
from Components.config import configfile
from Components.PluginComponent import plugins
from Components.config import config
from Components.SystemInfo import SystemInfo
from Tools.BoundFunction import boundFunction
from Tools.Directories import resolveFilename, SCOPE_SKIN
import xml.etree.cElementTree
from Screens.Setup import Setup, getSetupTitle
mainmenu = _('Main menu')
file = open(resolveFilename(SCOPE_SKIN, 'menu.xml'), 'r')
mdom = xml.etree.cElementTree.parse(file)
file.close()

class MenuUpdater():

    def __init__(self):
        self.updatedMenuItems = {}

    def addMenuItem(self, id, pos, text, module, screen, weight):
        if not self.updatedMenuAvailable(id):
            self.updatedMenuItems[id] = []
        self.updatedMenuItems[id].append([text,
         pos,
         module,
         screen,
         weight])

    def delMenuItem(self, id, pos, text, module, screen, weight):
        self.updatedMenuItems[id].remove([text,
         pos,
         module,
         screen,
         weight])

    def updatedMenuAvailable(self, id):
        return self.updatedMenuItems.has_key(id)

    def getUpdatedMenu(self, id):
        return self.updatedMenuItems[id]


menuupdater = MenuUpdater()

class MenuSummary(Screen):
    pass


class Menu(Screen, ProtectedScreen):
    ALLOW_SUSPEND = True

    def okbuttonClick(self):
        selection = self['menu'].getCurrent()
        if selection is not None:
            selection[1]()
        return

    def execText(self, text):
        exec text

    def runScreen(self, arg):
        if arg[0] != '':
            exec 'from ' + arg[0] + ' import *'
        self.openDialog(*eval(arg[1]))

    def nothing(self):
        pass

    def gotoStandby(self, *res):
        from Screens.Standby import Standby2
        self.session.open(Standby2)
        self.close(True)

    def openDialog(self, *dialog):
        self.session.openWithCallback(self.menuClosed, *dialog)

    def openSetup(self, dialog):
        self.session.openWithCallback(self.menuClosed, Setup, dialog)

    def addMenu(self, destList, node):
        requires = node.get('requires')
        if requires:
            if requires[0] == '!':
                if SystemInfo.get(requires[1:], False):
                    return
            elif not SystemInfo.get(requires, False):
                return
        MenuTitle = _(node.get('text', '??').encode('UTF-8'))
        entryID = node.get('entryID', 'undefined')
        weight = node.get('weight', 50)
        x = node.get('flushConfigOnClose')
        if x:
            a = boundFunction(self.session.openWithCallback, self.menuClosedWithConfigFlush, Menu, node)
        else:
            a = boundFunction(self.session.openWithCallback, self.menuClosed, Menu, node)
        destList.append((MenuTitle,
         a,
         entryID,
         weight))

    def menuClosedWithConfigFlush(self, *res):
        configfile.save()
        self.menuClosed(*res)

    def menuClosed(self, *res):
        if res and res[0]:
            self.close(True)

    def addItem(self, destList, node):
        requires = node.get('requires')
        if requires:
            if requires[0] == '!':
                if SystemInfo.get(requires[1:], False):
                    return
            elif not SystemInfo.get(requires, False):
                return
        configCondition = node.get('configcondition')
        if configCondition and not eval(configCondition + '.value'):
            return
        else:
            item_text = node.get('text', '').encode('UTF-8')
            entryID = node.get('entryID', 'undefined')
            weight = node.get('weight', 50)
            for x in node:
                if x.tag == 'screen':
                    module = x.get('module')
                    screen = x.get('screen')
                    if screen is None:
                        screen = module
                    if module:
                        module = 'Screens.' + module
                    else:
                        module = ''
                    args = x.text or ''
                    screen += ', ' + args
                    destList.append((_(item_text or '??'),
                     boundFunction(self.runScreen, (module, screen)),
                     entryID,
                     weight))
                    return
                if x.tag == 'plugin':
                    extensions = x.get('extensions')
                    system = x.get('system')
                    screen = x.get('screen')
                    if extensions:
                        module = extensions
                    elif system:
                        module = system
                    if screen is None:
                        screen = module
                    if extensions:
                        module = 'Plugins.Extensions.' + extensions + '.plugin'
                    elif system:
                        module = 'Plugins.SystemPlugins.' + system + '.plugin'
                    else:
                        module = ''
                    args = x.text or ''
                    screen += ', ' + args
                    destList.append((_(item_text or '??'),
                     boundFunction(self.runScreen, (module, screen)),
                     entryID,
                     weight))
                    return
                if x.tag == 'code':
                    destList.append((_(item_text or '??'),
                     boundFunction(self.execText, x.text),
                     entryID,
                     weight))
                    return
                if x.tag == 'setup':
                    id = x.get('id')
                    if item_text == '':
                        item_text = _(getSetupTitle(id))
                    else:
                        item_text = _(item_text)
                    destList.append((item_text,
                     boundFunction(self.openSetup, id),
                     entryID,
                     weight))
                    return

            destList.append((item_text,
             self.nothing,
             entryID,
             weight))
            return

    def __init__(self, session, parent):
        Screen.__init__(self, session)
        list = []
        menuID = None
        for x in parent:
            if not x.tag:
                continue
            if x.tag == 'item':
                item_level = int(x.get('level', 0))
                if item_level <= config.usage.setup_level.index:
                    self.addItem(list, x)
                    count += 1
            elif x.tag == 'menu':
                self.addMenu(list, x)
                count += 1
            elif x.tag == 'id':
                menuID = x.get('val')
                count = 0
            if menuID is not None:
                if menuupdater.updatedMenuAvailable(menuID):
                    for x in menuupdater.getUpdatedMenu(menuID):
                        if x[1] == count:
                            list.append((x[0], boundFunction(self.runScreen, (x[2], x[3] + ', ')), x[4]))
                            count += 1

        self.menuID = menuID
        if config.ParentalControl.configured.value:
            ProtectedScreen.__init__(self)
        if menuID is not None:
            for l in plugins.getPluginsForMenu(menuID):
                plugin_menuid = l[2]
                for x in list:
                    if x[2] == plugin_menuid:
                        list.remove(x)
                        break

                if len(l) > 4 and l[4]:
                    list.append((l[0],
                     boundFunction(l[1], self.session, self.close),
                     l[2],
                     l[3] or 50))
                else:
                    list.append((l[0],
                     boundFunction(l[1], self.session),
                     l[2],
                     l[3] or 50))

        self.skinName = []
        if menuID is not None:
            self.skinName.append('menu_' + menuID)
        self.skinName.append('Menu')
        self.menuID = menuID
        ProtectedScreen.__init__(self)
        if config.usage.sort_menus.value:
            list.sort()
        else:
            list.sort(key=lambda x: int(x[3]))
        self['menu'] = List(list)
        self['actions'] = NumberActionMap(['OkCancelActions', 'MenuActions', 'NumberActions'], {'ok': self.okbuttonClick,
         'cancel': self.closeNonRecursive,
         'menu': self.closeRecursive,
         '1': self.keyNumberGlobal,
         '2': self.keyNumberGlobal,
         '3': self.keyNumberGlobal,
         '4': self.keyNumberGlobal,
         '5': self.keyNumberGlobal,
         '6': self.keyNumberGlobal,
         '7': self.keyNumberGlobal,
         '8': self.keyNumberGlobal,
         '9': self.keyNumberGlobal})
        a = parent.get('title', '').encode('UTF-8') or None
        a = a and _(a)
        if a is None:
            a = _(parent.get('text', '').encode('UTF-8'))
        self['title'] = StaticText(a)
        Screen.setTitle(self, a)
        self.menu_title = a
        return

    def isProtected(self):
        if config.ParentalControl.setuppinactive.value:
            if config.ParentalControl.config_sections.main_menu.value and self.menuID == 'mainmenu':
                return True
            if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup':
                return True
            if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu':
                return True
            if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown':
                return True

    def keyNumberGlobal(self, number):
        number -= 1
        if len(self['menu'].list) > number:
            self['menu'].setIndex(number)
            self.okbuttonClick()

    def closeNonRecursive(self):
        self.close(False)

    def closeRecursive(self):
        self.close(True)

    def createSummary(self):
        return MenuSummary

    def isProtected(self):
        if config.ParentalControl.setuppinactive.value:
            if config.ParentalControl.config_sections.main_menu.value:
                return self.menuID == 'mainmenu'
            if config.ParentalControl.config_sections.configuration.value and self.menuID == 'setup':
                return True
            if config.ParentalControl.config_sections.timer_menu.value and self.menuID == 'timermenu':
                return True
            if config.ParentalControl.config_sections.standby_menu.value and self.menuID == 'shutdown':
                return True


class MainMenu(Menu):

    def __init__(self, *x):
        self.skinName = 'Menu'
        Menu.__init__(self, *x)
