# -*- coding: utf-8 -*-
#
# Copyright (C) 2007-2008 Edgewall Software
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://trac.edgewall.org/wiki/TracLicense.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://trac.edgewall.org/log/.

"""Utilities for text translation with gettext."""

import re
try:
    import threading
except ImportError:
    import dummy_threading as threading

import pkg_resources

from genshi.builder import tag


__all__ = ['gettext', 'ngettext', 'gettext_noop', 'ngettext_noop', 
           'tgettext', 'tgettext_noop', 'tngettext', 'tngettext_noop']


def gettext_noop(string, **kwargs):
    return kwargs and string % kwargs or string
N_ = gettext_noop

def ngettext_noop(singular, plural, num, **kwargs):
    string = (plural, singular)[num == 1]
    if '%(num)' in string:
        kwargs.update(num=num)
    return kwargs and string % kwargs or string

_param_re = re.compile(r"%\((\w+)\)(?:s|[\d]*d|\d*.?\d*[fg])")
def _tag_kwargs(trans, kwargs):
    trans_elts = _param_re.split(trans)
    for i in xrange(1, len(trans_elts), 2):
        trans_elts[i] = kwargs.get(trans_elts[i], '???')
    return tag(*trans_elts)
    
def tgettext_noop(string, **kwargs):
    return kwargs and _tag_kwargs(string, kwargs) or string

def tngettext_noop(singular, plural, num, **kwargs):
    string = (plural, singular)[num == 1]
    if '%(num)' in string:
        kwargs.update(num=num)
    return kwargs and _tag_kwargs(string, kwargs) or string


try:
    from babel.support import LazyProxy, Translations
    from gettext import NullTranslations

    _current = threading.local()

    def gettext(string, **kwargs):
        def _gettext():
            trans = get_translations().ugettext(string)
            return kwargs and trans % kwargs or trans
        if not hasattr(_current, 'translations'):
            return LazyProxy(_gettext)
        return _gettext()
    _ = gettext

    def ngettext(singular, plural, num, **kwargs):
        kwargs = kwargs.copy()
        def _ngettext():
            trans = get_translations().ungettext(singular, plural, num)
            if '%(num)' in trans:
                kwargs.update(num=num)
            return kwargs and trans % kwargs or trans
        if not hasattr(_current, 'translations'):
            return LazyProxy(_ngettext)
        return _ngettext()

    def tgettext(string, **kwargs):
        def _tgettext():
            trans = get_translations().ugettext(string)
            return kwargs and _tag_kwargs(trans, kwargs) or trans
        if not hasattr(_current, 'translations'):
            return LazyProxy(_tgettext)
        return _tgettext()
    tag_ = tgettext

    def tngettext(singular, plural, num, **kwargs):
        kwargs = kwargs.copy()
        def _tngettext():
            trans = get_translations().ungettext(singular, plural, num)
            if '%(num)' in trans:
                kwargs.update(num=num)
            return kwargs and _tag_kwargs(trans, kwargs) or trans
        if not hasattr(_current, 'translations'):
            return LazyProxy(_tngettext)
        return _tngettext()

    def activate(locale):
        locale_dir = pkg_resources.resource_filename(__name__, '../locale')
        _current.translations = Translations.load(locale_dir, locale)

    _null_translations = NullTranslations()

    def get_translations():
        return getattr(_current, 'translations', _null_translations)

    def deactivate():
        del _current.translations

    def get_available_locales():
        """Return a list of locale identifiers of the locales for which
        translations are available.
        """
        return [dirname for dirname
                in pkg_resources.resource_listdir(__name__, '../locale')
                if '.' not in dirname]

except ImportError: # fall back on 0.11 behavior, i18n functions are no-ops
    gettext = _ = gettext_noop
    ngettext = ngettext_noop
    tgettext = tag_ = tgettext_noop
    tngettext = tngettext_noop

    def activate(locale):
        pass

    def deactivate():
        pass

    def get_translations():
        return []

    def get_available_locales():
        return []

@@ -1040,57 +1040,33 @@
     
-if '%25(num)' in string:%0A        kwargs.update(num=
+kwargs.setdefault('num', 
 num)
@@ -1073,35 +1073,24 @@
 %0A    return 
-kwargs and 
 string %25 kwa
@@ -1092,26 +1092,16 @@
 %25 kwargs
- or string
 %0A%0A_param
@@ -1362,13 +1362,9 @@
 ts)%0A
-    
 %0A
+
 def 
@@ -1560,57 +1560,33 @@
     
-if '%25(num)' in string:%0A        kwargs.update(num=
+kwargs.setdefault('num', 
 num)
@@ -1593,35 +1593,24 @@
 %0A    return 
-kwargs and 
 _tag_kwargs(
@@ -1624,26 +1624,16 @@
  kwargs)
- or string
 %0A%0A%0Atry:%0A
@@ -2137,32 +2137,70 @@
 = kwargs.copy()%0A
+        kwargs.setdefault('num', num)%0A
         def _nge
@@ -2284,81 +2284,8 @@
 um)%0A
-            if '%25(num)' in trans:%0A                kwargs.update(num=num)%0A
     
@@ -2295,35 +2295,24 @@
      return 
-kwargs and 
 trans %25 kwar
@@ -2309,33 +2309,24 @@
 ans %25 kwargs
- or trans
 %0A        if 
@@ -2828,32 +2828,70 @@
 = kwargs.copy()%0A
+        kwargs.setdefault('num', num)%0A
         def _tng
@@ -2976,81 +2976,8 @@
 um)%0A
-            if '%25(num)' in trans:%0A                kwargs.update(num=num)%0A
     
@@ -2987,35 +2987,24 @@
      return 
-kwargs and 
 _tag_kwargs(
@@ -3013,33 +3013,24 @@
 ans, kwargs)
- or trans
 %0A        if 

Improve the `ngettext`-style functions to automaticaly add a `num` parameter, similar to [7423] on 0.11-stable.