"""Routes configuration

The more specific and detailed routes should be defined first so they
may take precedent over the more generic routes. For more information
refer to the routes manual at http://routes.groovie.org/docs/
"""
import os

from routes import Mapper, url_for
from routes.util import controller_scan as dir_controller_scan
from pylons.i18n.translation import get_lang

from spline.lib.plugin.load import run_hooks
from spline.i18n import Translator

class I18nMapper(Mapper):
    def connect(self, *args, **kwargs):
        translator_class = kwargs.pop('i18n_class', None)
        super(I18nMapper, self).connect(*args, **kwargs)
        for lang in Translator.available_languages():
            try:
                name, url = args
            except ValueError:
                name = None
                (url, ) = args
            if translator_class:
                url_parts = ['', lang]
                _ = translator_class(languages=[lang])
                for part in url.split('/'):
                    if not part:
                        pass
                    elif '{' not in part and '*' not in part:
                        url_parts.append(_(part, context='url').encode('utf-8'))
                    else:
                        url_parts.append(part)
                translated_url = '/'.join(url_parts)
            else:
                if url == '/':
                    url = ''
                translated_url = '/' + lang + url
            kwargs['_lang'] = lang
            if name:
                name = lang + '!!' + name
            super(I18nMapper, self).connect(name, translated_url, **kwargs)

    def generate(self, route=None, *args, **kwargs):
        try:
            lang = get_lang()[0]
        except TypeError:
            lang = None
        else:
            kwargs.setdefault('_lang', lang)
        if route and lang and '!!' not in route.name:
            return url_for(kwargs['_lang'] + '!!' + route.name, *args, **kwargs)
        else:
            return super(I18nMapper, self).generate(*args, **kwargs)

def controller_scan(config, directory):
    """Looks for a controller in the plugin list, defaulting to the usual
    Routes directory scan if it isn't found."""

    controllers = config['spline.plugins.controllers'].keys()
    controllers.extend(dir_controller_scan(directory))
    return controllers

def make_map(config, content_dirs=[]):
    """Create, configure and return the routes Mapper"""
    map = I18nMapper(
        controller_scan=lambda directory: controller_scan(config, directory),
        directory=config['pylons.paths']['controllers'],
        always_scan=config['debug'])
    map.minimization = False

    # Content files get explicitly mapped so we don't have to pull any cheap
    # tricks like looking for them in a 404 handler.  We do them first so
    # controllers can't be clobbered by bad choices of filenames
    for content_dir in content_dirs:
        for root, dirs, files in os.walk(content_dir):
            for name in files:
                localpath = os.path.join(root, name)
                webpath, ext = os.path.splitext(localpath)

                # Skip over hidden files.
                # For now, also require a .html extension.
                if webpath[0] == '.' or ext != '.html':
                    continue

                # Use the full path as a route name so url() can easily route
                # to a static page
                map.connect('/' + os.path.relpath(webpath, content_dir),
                            '/' + os.path.relpath(webpath, content_dir),
                            controller='main', action='content', path=localpath)

    # The ErrorController route (handles 404/500 error pages); it should
    # likely stay at the top, ensuring it can always be resolved
    map.connect('/error/{action}', controller='error')
    map.connect('/error/{action}/{id}', controller='error')

    map.connect('/css', controller='main', action='css')
    map.connect('/cron', controller='main', action='cron')

    # Allow plugins to map routes without the below defaults clobbering them
    run_hooks('routes_mapping', config=config, map=map)

    map.connect('/', controller='main', action='index')

    return map

@@ -538,57 +538,551 @@
     
-translator_class = kwargs.pop('i18n_class', None)
+%22%22%22Create and connect a new Route to the Mapper.%0A%0A        In addition to the what Routes' connect() does, this method will%0A        connect language-specific routes for all languages available to Spline.%0A%0A        For named routes, the language-specific entries will have the language%0A        identifier prepended, separated from the name by '!!'.%0A        The string '!!' shouldn't be used in route names for other purposes.%0A        %22%22%22%0A        translator_class = kwargs.pop('i18n_class', None)%0A        # Connect the URL for the default language
 %0A   
@@ -1126,32 +1126,83 @@
 *args, **kwargs)
+%0A%0A        # Now connect for all available languages
 %0A        for lan
@@ -1369,15 +1369,13 @@
     
-(url, )
+%5Burl%5D
  = a
@@ -1431,30 +1431,210 @@
     
-url_parts = %5B'', lang%5D
+# The first part of the URL is '/%3Clang%3E'%0A                url_parts = %5B'', lang%5D%0A                # Chop the URL into parts, translate each one individually,%0A                # then join them back together
 %0A   
@@ -1849,24 +1849,70 @@
 ot in part:%0A
+                        # Skip variable parts%0A
             
@@ -2155,16 +2155,82 @@
 == '/':%0A
+                    # Make bare language prefix work (e.g. '/de')%0A
         
@@ -2300,16 +2300,89 @@
 g + url%0A
+            # Add the %60_lang%60 kwarg, and the language tag if we're named%0A
         
@@ -2471,16 +2471,45 @@
  + name%0A
+            # And we're off!%0A
         
@@ -2622,32 +2622,290 @@
 rgs, **kwargs):%0A
+        %22%22%22Generate a route from a set of keywords%0A%0A        If the %60_lang%60 argument is not given, the curent language used for it.%0A%0A        For a named route, a language tag will be prepended to the name%0A        depending on the %60_lang%60 arument.%0A        %22%22%22%0A
         try:%0A   

Comment the big blob of Mapper override