# -*- coding: utf8 -*-
""" Macro to show the translated pages list. """

__author__ = u'Dirk Stöcker'
' based on a macro by Zhang Cong (ftofficer)'
__version__ = '2.0'

from trac.core import *
from trac.wiki.macros import WikiMacroBase
from StringIO import StringIO
from trac.wiki.formatter import Formatter
from trac.wiki.model import WikiPage
from trac.wiki.api import WikiSystem
import re

class TranslatedPagesMacro(WikiMacroBase):
    """
    Macro to show the translated pages list.
    """

    TRAC_LANGUAGES_PAGE = u'TracLanguages'
    BASE_LANG = u'En'

    def __init__(self):
        self.languages_page_version = 0
        self._update_languages()

    def _parse_languages_list(self, text):
        """
        Parses the list of languages in form
         * <language code> <language name> x <description>
         * <language code> <language name> x <description>
        ...
        
        The x is used to allow better display of page for languages written right to left
        The description contains the "Other languages" text in that language
        """
        langs = {}
        reg = re.compile(u"^ \* ([A-Z][a-z](?:_[A-Z]{2})?) +(.+?) +x +(.+)$")
        for line in text.split(u'\r\n'):
            regres = reg.search(line)
            if regres == None:
                self.env.log.warn(
                    u"Wrong line syntax while parsing languages list: %s" % line)
            else:
                code = regres.group(1)
                name = regres.group(2)
                desc = regres.group(3)
                self.env.log.debug("Adding language %s -> %s (%s)" % (code, name, desc))
                langs[code] = name
                langs["_"+code] = desc
        return langs

    def _update_languages(self):
        languages_page = WikiPage(self.env, self.TRAC_LANGUAGES_PAGE)
        if not languages_page.exists:
            self.env.log.warn(u"Can't find page %s" % self.TRAC_LANGUAGES_PAGE)
            self.languages = {}
            self.languages_page_version = 0
        else:
            if languages_page.version > self.languages_page_version:
                self.languages = self._parse_languages_list(languages_page.text)
                self.languages_page_version = languages_page.version

    def _get_language_name(self, lang_code):
        self._update_languages()
        return self.languages.get(lang_code, lang_code)

    def _get_translated_page(self, name, lang_code):
        if lang_code == self.BASE_LANG:
            return name
        else:
            return lang_code + u':' + name

    def _get_page_info(self, page_name):
        regres = re.compile("^([A-Z][a-z](_[A-Z][A-Z])?):(.+)$").search(page_name)
        if regres == None:
            return (page_name, self.BASE_LANG)
        return (regres.group(3), regres.group(1))

    def _get_translations(self, base_page_name):
        for l in sorted(self.languages.keys()):
            tr = self._get_translated_page(base_page_name, l);
            for subpage in sorted(WikiSystem(self.env).get_pages(tr)):
                if(subpage == tr):
                    yield l

    def _get_lang_link(self, base_name, lang_code):
        page_name = self._get_translated_page(base_name, lang_code)
        return u"  * [wiki:%s %s]" % (page_name, self._get_language_name(lang_code))

    def _get_current_lang_link(self, lang_code):
        return u"  * '''%s'''" % self._get_language_name(lang_code)

    def expand_macro(self, formatter, name, args):
        """
        Return a list of translated pages with the native language names.
        The list of languages supported can be configured by adding new
        entries to TracLanguages page. Refer to ISO 639-1 for more information.
        """

        page_name = formatter.context.resource.id
        (base_page_name, lang_code) = self._get_page_info(page_name)

        lang_link_list = []
        for translation in self._get_translations(base_page_name):
            if translation != lang_code:
                lang_link_list.append(self._get_lang_link(base_page_name, translation))
            else:
                lang_link_list.append(self._get_current_lang_link(lang_code))

        out = StringIO()
        Formatter(self.env, formatter.context).format(u'\n'.join(lang_link_list), out)

        desc = "Languages"
        if self.languages.has_key("_"+lang_code):
            desc = self.languages["_"+lang_code]
        return u"""
<div class="wiki-toc trac-nav" style="clear:both">
<h4>%s:</h4>
%s
</div>""" % (desc, out.getvalue())


