# Monkey-Patch which makes the Page constructor be a function which
# does language-dependant page lookup under the hood. Funky multilingual
# support for MoinMoin!
#
# USAGE
# ~~~~~
#   1. Copy in the same directory as your wikiconfig.py resides
#
#   2. Add "import i18n_hack" to your wikiconfig.
#
#   3. (Optional, recommended) Add an 'available_languages' variable to your
#      configuration, with a list of strings with the available languages:
#
#        available_languages = ["en", "jp", "es"]
#
#      The order of the list will determine the order in which the languages
#      will be tried until a page is found.
#
from MoinMoin import Page
MoinPage = Page.Page


def languagesForRequest(request):
    """
    Returns preferred languages based upon the request, thus based upon the
    Accept-Language header sent by the user agent, with some fallback ones
    based upon Moin's configuration.
    """
    language  = getattr(request, "lang", None)
    available = getattr(request.cfg, "available_languages", None)

    if language and ((available is None) or (language in available)):
        yield language
    for language in available:
        yield language


def HackedPage(request, name, *arg, **kw):
    """
    Find a (probably) translated Page. Search order is determined by the
    languagesForRequest() function above.
    """
    if not name:
        return MoinPage(request, name, *arg, **kw)

    for lang in languagesForRequest(request):
        page = MoinPage(request, "%s/%s" % (lang, name), *arg, **kw)
        if page.exists():
            return page
    return MoinPage(request, name, *arg, **kw)



from mmpp import hook

@hook
def patch_i18n():
    from MoinMoin import wikiaction
    from new import function

    hacked_globals = {}
    hacked_globals.update(wikiaction.do_show.func_globals)
    hacked_globals["Page"] = HackedPage

    # Overwrites the wikiaction.do_show() function by dynamically creating
    # a new function with the same code, name and default values, but with
    # its globals changed so it uses our HackedPage function instead of the
    # Page constructor.
    #
    wikiaction.do_show = function(
            wikiaction.do_show.func_code,
            hacked_globals,
            wikiaction.do_show.func_name,
            wikiaction.do_show.func_defaults)

