import es
import keyvalues
import playerlib
import popuplib

import psyco
psyco.full()

#plugin information
info = es.AddonInfo()
info.name = "Keymenu EventScripts python library"
info.version = "oy5a"
info.author = "Hunter"
info.url = "http://www.eventscripts.com/pages/Keymenu/"
info.description = "Provides menu and pop-up creation from keygroups"

#global variables:
## gKeymenus holds all the keymenus by their names for backwards compatibility
gKeymenus = {}

# Get this library handle for registering events dynamically:
selfmodule = __import__('keymenulib')



# Keymenu_keymenu is the normal keymenu class
class Keymenu_keymenu(object):
    def __init__(self, gKeymenuid, returnvar, block, keygroup, menudisplay, menureturn, titletext, update=None):
        #initialization of keymenu
        self.name = gKeymenuid          #keymenu name for backwards compatibility
        self.keygroup = keygroup        #keygroup that is used to create the menu
        self.block = block              #block/function that executes on menuselect
        self.returnvar = returnvar      #variable that contains the menu-return
        self.titletext = titletext      #title of the keymenu
        self.menudisplay = menudisplay  #indicator for the display key or keyvalue
        self.menureturn = menureturn    #indicator for the return key or keyvalue
        self.popup = None               #contains the popup object
        self.keyvalues = None           #contains the keyvalues object
        self.pagecount = 0              #number of pages
        self.linecount = 0              #number of options in the menu
        if update==None:                #checking for keymenu update
            self.backmenuvar = 0        #backmenu that displays on 0. Cancel
        if es.exists("keygroup", self.keygroup) or isinstance(self.keygroup, keyvalues.KeyValues):
            if "#" in self.menudisplay and "#" in self.menureturn:
                menudisplay = self.menudisplay.split(" ")
                menureturn = self.menureturn.split(" ")
                if len(menudisplay) == 1:
                    menudisplay.append(0)
                if len(menureturn) == 1:
                    menureturn.append(0)
                self.menudisplay = menudisplay
                self.menureturn = menureturn
                if len(self.titletext) > 0:
                    self.popup = popuplib.easymenu("_keymenu_"+str(self.name), "_keymenu_choice", _submit)
                    self.popup.keymenuid = self.name
                    if not ("\\n" in self.titletext):
                        self.popup.c_titleformat = self.titletext + (" "*(30-len(self.titletext))) + " (%p/%t)"
                    else:
                        title = self.titletext.split("\\n")
                        self.popup.c_titleformat = title[0] + (" "*(30-len(title[0]))) + " (%p/%t)\n" + title[1]
                    if not isinstance(self.keygroup, keyvalues.KeyValues):
                        self.keyvalues = keyvalues.getKeyGroup(self.keygroup)
                    else:
                        self.keyvalues = self.keygroup
                        self.keygroup = self.keyvalues.getName()
                    if menudisplay[0] == "#key" and menureturn[0] == "#key":
                        for k in self.keyvalues:
                            kname = k.getName()
                            self.popup.addoption(kname, kname)
                            self.linecount += 1
                    elif menudisplay[0] == "#key" and menureturn[0] == "#keyvalue":
                        for k in self.keyvalues:
                            kname = k.getName()
                            kvaluereturn = k[menureturn[1]]
                            self.popup.addoption(kvaluereturn, kname)
                            self.linecount += 1
                    elif menudisplay[0] == "#keyvalue" and menureturn[0] == "#key":
                        for k in self.keyvalues:
                            kname = k.getName()
                            kvaluedisplay = k[menudisplay[1]]
                            self.popup.addoption(kname, kvaluedisplay)
                            self.linecount += 1
                    elif menudisplay[0] == "#keyvalue" and menureturn[0] == "#keyvalue":
                        for k in self.keyvalues:
                            kname = k.getName()
                            kvaluedisplay = k[menudisplay[1]]
                            kvaluereturn = k[menureturn[1]]
                            self.popup.addoption(kvaluereturn, kvaluedisplay)
                            self.linecount += 1
                    if self.linecount == 0:
                        self.popup.delete()
                        self.popup = None
                        self.keyvalues = None
                        raise ValueError("Keymenulib: No keys or keyvalues found in %s"%keygroup)
                else:
                    raise ArgumentError("Keymenulib: No titletext")
            else:
                raise ArgumentError("Keymenulib: No #key or #keyvalue found in the commandstring")
        else:
            raise ValueError("Keymenulib: The keygroup %s does not exists"%keygroup)
    def delete(self):
        delete(self.name)
    def information(self, listlevel):
        es.dbgmsg(0, self.name)
        if self.popup:
            self.pagecount = self.popup.getPageCount()
        if listlevel >= 1:
            es.dbgmsg(0, "  Keygroup:     "+str(self.keygroup))
            es.dbgmsg(0, "  Block:        "+str(self.block))
            es.dbgmsg(0, "  ReturnVar:    "+str(self.returnvar))
            es.dbgmsg(0, "  Titletext:    "+str(self.titletext))
            es.dbgmsg(0, "  Menudisplay:  "+str(self.menudisplay))
            es.dbgmsg(0, "  Menureturn:   "+str(self.menureturn))
            es.dbgmsg(0, "  Backmenu:     "+str(self.backmenuvar))
            es.dbgmsg(0, "  Pagecount:    "+str(self.pagecount))
            es.dbgmsg(0, "  Linecount:    "+str(self.linecount))
            es.dbgmsg(0, " ")
    def send(self, pUsers, pPage=None):
        try:
            # try if pUsers is just a single userid
            userid = int(pUsers)
            pUsers = [userid]
        except TypeError:
            pass
        try:
            pPage = int(pPage)
        except TypeError:
            pass
        if self.popup:
            for userid in pUsers:
                es.dbgmsg(1, "Keymenulib: Send keymenu '"+str(self.name)+"' to user "+str(userid))
                if pPage > 1:
                    self.popup.sendPage(userid, pPage)
                else:
                    self.popup.send(userid)
    def unsend(self, pUsers, pPage=None):
        try:
            # try if pUsers is just a single userid
            userid = int(pUsers)
            pUsers = [userid]
        except TypeError:
            pass
        try:
            pPage = int(pPage)
        except TypeError:
            pass
        if self.popup:
            for userid in pUsers:
                es.dbgmsg(1, "Keymenulib: Unsend keymenu '"+str(self.name)+"' from user "+str(userid))
                if pPage > 1:
                    self.popup.unsendPage(userid, pPage)
                else:
                    self.popup.unsend(userid)
    def update(self, keygroup=None):
        if keygroup==None:
            keygroup = self.keygroup
        menudisplay = str(self.menudisplay[0]) + " " + str(self.menudisplay[1])
        menureturn = str(self.menureturn[0]) + " " + str(self.menureturn[1])
        self.__init__(self.name, self.returnvar, self.block, keygroup, menudisplay, menureturn, self.titletext, True)
    def getpages(self):
        if self.popup:
            self.pagecount = self.popup.getPageCount()
        return self.pagecount
    def changeblock(self, block):
        self.block = block
    def backmenu(self, backmenu):
        if popuplib.exists(backmenu):
            self.popup.submenu(10, backmenu)
            self.backmenuvar = backmenu
            es.dbgmsg(1, "Keymenulib: Set backmenu of '"+str(self.name)+"' to popup '"+str(self.backmenuvar)+"'")
            return True
        elif backmenu in gKeymenus:
            self.popup.submenu(10, gKeymenus[backmenu].popup.name)
            self.backmenuvar = gKeymenus[backmenu].popup.name
            es.dbgmsg(1, "Keymenulib: Set backmenu of '"+str(self.name)+"' to popup '"+str(self.backmenuvar)+"'")
            return True
        else:
            es.dbgmsg(0, "keymenu: Could not set backmenu of '"+str(self.name)+"' to '"+str(backmenu)+"'")
            return False

#keymenu commands begin here
#usage from other Python scripts for example:
#  import es
#  import keymenu
#  from keymenu import keymenu
#  es.server.cmd("es_xcreateplayerlist playerlist")
#  a = keymenu.create("insertnamehere", "_keymenu_select", "myscript/myblock", "playerlist", "#keyvalue name", "#key", "Playerlist\nSelect a player")
#  a.send(es.getuserid("Hunter"))
#  a.delete
def create(pKeymenuid, returnvar, block, keygroup, menudisplay, menureturn, titletext):
    gKeymenus[pKeymenuid] = Keymenu_keymenu(pKeymenuid, returnvar, block, keygroup, menudisplay, menureturn, titletext)
    return gKeymenus[pKeymenuid]

def delete(pKeymenuid):
    if pKeymenuid in gKeymenus:
        k = gKeymenus[pKeymenuid]
        k.popup.unsend(es.getUseridList())
        k.popup.delete()
        del gKeymenus[pKeymenuid]
    else:
        raise ValueError("Keymenulib: Cannot delete keymenu %s, it does not exist"%pKeymenuid)

def exists(pKeymenuid):
    return (pKeymenuid in gKeymenus)

def find(pKeymenuid):
    if pKeymenuid in gKeymenus:
        return gKeymenus[pKeymenuid]
    return None

def send(pKeymenuid, pUserid, pPage=None):
    if pKeymenuid in gKeymenus:
        gKeymenus[pKeymenuid].send(int(pUserid), pPage)
    else:
        raise ValueError("Keymenulib: Cannot send keymenu %s, it does not exist"%pKeymenuid)

def unsend(pKeymenuid, pUserid, pPage=None):
    if pKeymenuid in gKeymenus:
        gKeymenus[pKeymenuid].unsend(int(pUserid), pPage)
    else:
        raise ValueError("Keymenulib: Cannot unsend keymenu %s, it does not exist"%pKeymenuid)
    
def getmenuname(pPopupid):
    if popuplib.exists(pPopupid):
        page = popuplib.find(pPopupid)
        if page.keymenu:
            return page.keymenu
    return False

###################
#Helper functions #
###################

def _submit(userid, choice, name):
    # handling selected option popup/keymenu
    if popuplib.exists(name):
        page = popuplib.find(name)
        menu = page.keymenuid
        if menu:
            es.dbgmsg(1, "Keymenulib: Handling selected option of '"+str(menu)+"'")
            k = find(menu)
            if k.block != "":
                es.dbgmsg(1, "Keymenulib: block='"+str(k.block)+"'"+str(type(k.block)))
                es.set(k.returnvar, choice)
                if callable(k.block):
                    k.block(userid, choice, k.name)
                else:
                    es.doblock(k.block)
