## WidgetUtil
##
## Provides functions to create new WidgetTypes and supply hover text for them.
##
## WidgetTypes
##
##   createWidget(name)
##     Creates and returns a new unique WidgetTypes constant named <name>.
##
##       <widget name="<name>"/>
##
## Hover Help Text
##
##   setWidgetHelpText(widget, text)
##     Uses static <text> string for the hover help text of <widget>.
##
##       <widget name="<widget-name>" text="<text>"/>
##
##   setWidgetHelpXml(widget, key)
##     Uses <TEXT> CIV4GameText.xml element matching <key> for the hover text of <widget>.
##     This form allows you to use translated strings as it's looked up each time it's shown.
##
##       <widget name="<widget-name>" xml="<key>"/>
##
##   setWidgetHelpFunction(widget, func)
##     Calls <func> to get the hover text of <widget> each time it's shown.
##     Use this method when you want the displayed text to change based on game conditions.
##     The function should have this signature:
##       func(eWidget, iData1, iData2, bOption)
##
##       <widget name="<widget-name>" module="<module-name>" function="<function-name>"/>
##
## Notes
##
##   Must register setWidgetHelp() as a BugGameUtils handler.
##
## Copyright (c) 2009 The BUG Mod.
##
## Author: EmperorFool

from CvPythonExtensions import *
import BugConfig
import BugUtil


## Widget Types

g_nextWidget = WidgetTypes.NUM_WIDGET_TYPES

def createWidget(name):
    """
    Creates and returns the next unique WidgetTypes constant to be used with custom UI widgets.
    
    If <name> already exists, a warning is logged and the widget is returned.
    Otherwise the new widget is assigned to WidgetTypes.<name> and returned.
    """
    if hasattr(WidgetTypes, name):
        BugUtil.warn("WidgetTypes.%s already exists", name)
        return getattr(WidgetTypes, name)
    else:
        global g_nextWidget
        BugUtil.info("WidgetUtil - WidgetTypes.%s = %d", name, g_nextWidget)
        widget = WidgetTypes(g_nextWidget)
        setattr(WidgetTypes, name, widget)
        g_nextWidget += 1
        return widget


## Hover Help Text

g_widgetHelp = {}

def setWidgetHelpText(widget, text):
    """
    Assigns the literal <text> to be used as the hover text for <widget>.
    """
    _setWidgetHelp(widget, "Text", lambda *ignored: text)

def setWidgetHelpXml(widget, key):
    """
    Assigns the XML <key> to be used to lookup the translated hover text for <widget>.
    """
    _setWidgetHelp(widget, "XML", lambda *ignored: BugUtil.getPlainText(key))

def setWidgetHelpFunction(widget, func):
    """
    Assigns the function <func> to be called to get the hover text for <widget>.
    
    The function will be called each time the hover text is needed with these parameters:
    
        eWidgetType         WidgetTypes constant
        data1               int
        data2               int
        bOption             boolean
    
    The first three are the ones used when creating the UI widget.
    I have no idea what <bOption> is or where it comes from as it's supplied by the EXE.
    """
    _setWidgetHelp(widget, "Function", func)

def _setWidgetHelp(widget, type, func):
    """
    Registers the hover text <func> for <widget> if it hasn't been already.
    
    Do not call this function as it is used internally by the registration functions above.
    """
    if widget in g_widgetHelp:
        BugUtil.warn("WidgetTypes %d help already registered", widget)
    else:
        BugUtil.debug("WidgetUtil - registering %s hover help for WidgetTypes %d: %s", type, widget, func)
        g_widgetHelp[widget] = func

    
def getWidgetHelp(argsList):
    """
    Returns the hover help text for <eWidgetType> if registered, otherwise returns an empty string.
    
    This function is a BugGameUtils handler registered in init.xml.
    """
    eWidgetType, iData1, iData2, bOption = argsList
    func = g_widgetHelp.get(eWidgetType)
    if func:
        return func(eWidgetType, iData1, iData2, bOption)
    return u""


## Configuration Handler

class WidgetHandler(BugConfig.Handler):
    
    TAG = "widget"
    
    def __init__(self):
        BugConfig.Handler.__init__(self, WidgetHandler.TAG, "name text xml module function")
        self.addAttribute("name", True)
        self.addAttribute("text")
        self.addAttribute("xml")
        self.addAttribute("module", False, True)
        self.addAttribute("function")
    
    def handle(self, element, name, text, xml, module, function):
        widget = createWidget(name)
        if text:
            setWidgetHelpText(widget, text)
        elif xml:
            setWidgetHelpXml(widget, xml)
        elif module and function:
            setWidgetHelpFunction(widget, BugUtil.lookupFunction(module, function))
