#format python
#language fr
#acl All:read
# -*- coding: iso-8859-1 -*-
"""MoinMoin theme "err404" by Boris Ganne.
Inspired by MoinMoin theme "Mandarin" by Radomir Dopieralski. (SideBar)
Inspired by MoinMoin theme "sinorca4moin" by David Linke.

MoinMoin theme "sinorca4moin" by David Linke.
See MoinMoin:DavidLinke/Sinorca4Moin for more infos.

Version 0.5b   : changing css a bit (also made css2.1. compatible) and 
                 updating the theme for MoinMoin Version 1.8 
                 Attention: this is not an official release, more a
                 personal update (Marcel Haefner)!
Version 0.5    : Version adjusted for moin-1.6.x (2007-12-29)
Version 0.4    : Extended version adjusted for moin-1.5.x (2006-08-13)
Version 0.1-0.3: Initial version for moin-1.3.x (2005)

Inspired by Haran's sinorca-design published at www.oswd.org.

$Id: sinorca4moin.py 159 2007-12-29 21:43:07Z linke $
"""

import os
from MoinMoin.theme import ThemeBase
from MoinMoin.Page import Page
from MoinMoin.config.multiconfig import _url_re_list, _makeConfig, _getConfigName
from MoinMoin import wikiutil, error

class Theme(ThemeBase):

    name = "err404"

    def farmWikiList(self):
        """Generate list of links pointing to the wikis of the farm

        Fore each Subwiki a link to Frontpage and RecentChanges (image) is
        created. If interwiki_preferred is specified in the farmconfig the
        links will be created only for these wikis else links to all wikis
        in farmconfig.wiki will be created.
        """
        _ = self.request.getText
        farmwikis =  [wiki_name for wiki_name, reg in _url_re_list()]
        if self.request.cfg.interwiki_preferred:
            wikis = self.request.cfg.interwiki_preferred
            # remove everything that is not a wiki of the farm
            wikis = [w for w in wikis if w in farmwikis]
        else:
            wikis = farmwikis

        if len(wikis) < 2: return []  # creating links is useless for one wiki

        linkList = []
        for wiki_name in wikis:
            cfg = _makeConfig(wiki_name)
            highlight = u''
            if wiki_name == _getConfigName(self.request.url):
                highlight = u' class="highlight"'
            try:
                interwiki_list = wikiutil.load_wikimap(self.request)
                wiki_url = interwiki_list[cfg.interwikiname]
                rc = _("RecentChanges", formatted=False)
                linkList.append( ''.join([
                    u' <a title="%s" href="%s"%s>%s</a>' %
                        (cfg.sitename, wiki_url, highlight, cfg.interwikiname),
                    u'<a title="%s" href="%s%s">' %
                        (rc, wiki_url, wikiutil.quoteWikinameURL(rc)),
                    u'<img src="%s/sinorca4moin/img/moin-diff.png" alt="%s"' %
                            (cfg.url_prefix_static, rc),
                    u' height="11" width="15"></a>'
                    ]))
            except KeyError: # probably no interwikiname in config
                msg = """
Missing the wiki '%s' in the interwiki list.

Please add the interwiki-name and the url of this wiki to 'intermap.txt'.
"""%wiki_name
                #raise error.ConfigurationError(msg)
                pass
        return linkList

    def subheader(self):
        """Make subheader

        Links to subwikis if it's a farm else uses page_header2.
        """
        linkList = self.farmWikiList()
        if len(linkList) > 1:
            subheader = ' |\n'.join(linkList)
        else:
            subheader = self.request.cfg.page_header2
        return '\n'.join([
            u'<div class="subHeader">',
            subheader,
            u'</div>',
            ])

    def title(self, d):
        """ Assemble the title (not as html list as in standard method!)

        Code copied from title-method in __init__.py
        Only one line was changed.

        @param d: parameter dictionary
        @rtype: string
        @return: title html
        """
        _ = self.request.getText
        content = []
        if d['title_text'] == d['page'].split_title(): # just showing a page,
            curpage = ''                               # no action
            segments = d['page_name'].split('/') # was: title_text
            for s in segments[:-1]:
                curpage += s
                # next line is modified compared to method in _init__.py
                content.append("%s&nbsp;/ " % Page(self.request,
                    curpage).link_to(self.request, s))
                curpage += '/'
            link_text = segments[-1]
            link_title = _('Click to do a full-text search for this title',
                           formatted=False)
            link_query = {
                'action': 'fullsearch',
                'value': 'linkto:"%s"' % d['page_name'],
                'context': '180',
            }
            # we dont use d['title_link'] any more, but make it ourselves:
            link = d['page'].link_to(self.request, link_text,
                                     querystr=link_query,
                                     title=link_title, css_class='backlink',
                                     rel='nofollow')
            content.append(('<li>%s</li>') % link)
        else:
            content.append('<li>%s</li>' % wikiutil.escape(d['title_text']))

        html = '''
<ul id="pagelocation">
%s
</ul>
''' % "".join(content)
        return html

    def iconbar(self, d):
        """
        Assemble the iconbar
        
        @param d: parameter dictionary
        @rtype: string
        @return: iconbar html
        """
        iconbar = []
        if self.cfg.page_iconbar and self.request.user.show_toolbar and d['page_name']:
            iconbar.append('<ul id="iconbar">\n')
            icons = self.cfg.page_iconbar[:]
            for icon in icons:
                if icon == "up":
                    if d['page_parent_page']:
                        iconbar.append('<li>%s</li>\n' % self.make_iconlink(icon, d))
                elif icon == "subscribe" and self.cfg.mail_enabled:
                    iconbar.append('<li>%s</li>\n' % self.make_iconlink(
                        ["subscribe", "unsubscribe"][self.request.user.isSubscribedTo([d['page_name']])], d))
                else:
                    iconbar.append('<li>%s</li>\n' % self.make_iconlink(icon, d))
            iconbar.append('</ul>\n')
        return ''.join(iconbar)

    def wikipanel(self, d):
        """ Create wiki panel """
        _ = self.request.getText
        html = [
            u'<div class="sidepanel">',
            u'<h1>%s</h1>' % _("Wiki"),
            self.navibar(d),
            u'</div>',
            ]
        return u'\n'.join(html)

    def pagepanel(self, d):
        """ Create page panel """
        _ = self.request.getText
        if self.shouldShowEditbar(d['page']):
            html = [
                u'<div class="sidepanel">',
                u'<h1>%s</h1>' % _("Page"),
                self.editbar(d),
                u'</div>',
                ]
            return u'\n'.join(html)
        return ''

    def userpanel(self, d):
        """ Create user panel """
        _ = self.request.getText

        html = [
            u'<div class="sidepanel">',
            u'<h1>%s</h1>' %  _("User"),
            self.username(d),
            u'</div>'
            ]
        return u'\n'.join(html)

    def linkedSitename(self):
        """Create title from sitename and link to FrontPage"""
        frontpage = wikiutil.getFrontPage(self.request).page_name
        html = wikiutil.link_tag(self.request,
                                 wikiutil.quoteWikinameURL(frontpage),
                                 self.request.cfg.sitename)
        return html

    def flexible_userhome(self, d):
        """Determine content in superheader and sidebar based on page_header1
        """
        if self.cfg.page_header1:
            superheader = self.cfg.page_header1
            userpanel = self.userpanel(d)
        else:
            #superheader = self.username(d)
            superheader = '\n'.join([
                u'  <div class="right">',
                self.username(d),
                u'  </div>',
                ])
            userpanel = ''
        return superheader, userpanel

    def shortenPagename(self, name):
        """ Shorten page names (overrides default method)

        changed compared to default: for hierarchical names a part of
        the first level is always shown.

        @param name: page name, unicode
        @rtype: unicode
        @return: shortened version of page name
        """
        l1Length = 8   # length to which level1 of page name will be truncated
        maxLength = self.maxPagenameLength()
        if len(name) > maxLength:
            half, left = divmod(maxLength, 2)
            name = name.split('/')
            parts = len(name)
            # select separator based on number of levels
            if parts > 2:
                nameStart, nameEnd = name[0], name[-1]
                if (len(nameStart) + len(nameEnd) > maxLength-4
                    and len(nameStart) > l1Length):
                    # cut from start
                    if len(nameEnd) > maxLength-6-l1Length:
                        name = u'%s../../%s..' % (nameStart[:l1Length],
                                nameEnd[:maxLength-8-l1Length])
                    else:
                        lenStart = max(maxLength-len(nameEnd)-6, l1Length)
                        name = u'%s../../%s' % (nameStart[:lenStart],
                                nameEnd[:maxLength-6-lenStart])
                elif len(nameStart) + len(nameEnd) > maxLength-4:
                    # cut form end only
                    name = u'%s/../%s..' % (nameStart,
                            nameEnd[:maxLength-6-len(nameStart)])
                else:
                    name = u'%s/../%s' % (nameStart, nameEnd)
            elif parts == 2:
                nameStart, nameEnd = name[0], name[-1]
                if (len(nameStart) + len(nameEnd) > maxLength-1
                    and len(nameStart) > l1Length):
                    # cut from start
                    if len(nameEnd) > maxLength-3-l1Length:
                        name = u'%s../%s..' % (nameStart[:l1Length],
                                nameEnd[:maxLength-5-l1Length])
                    else:
                        lenStart = max(maxLength-len(nameEnd)-3, l1Length)
                        name = u'%s../%s' % (nameStart[:lenStart],
                                nameEnd[:maxLength-3-lenStart])
                elif len(nameStart) + len(nameEnd) > maxLength-1:
                    # cut from end only
                    name = u'%s/%s..' % (nameStart,
                            nameEnd[:maxLength-3-len(nameStart)])
                else:
                    name = u'%s/%s' % (nameStart, nameEnd)
            else:
                # simply replace middle with '...' for long pagenames
                half, left = divmod(maxLength-3, 2)
                name = name[0]
                name = u'%s...%s' % (name[:half + left], name[-half:])
        return name
# viens de mandarin.py
    def sidebar(self, d, **keywords):
        """ Display page called SideBar as an additional element on every page

        @param d: parameter dictionary
        @rtype: string
        @return: sidebar html
        """
        request = self.request
        _ = self.request.getText
        sidebar = request.getPragma('sidebar') or u'SideBar';
        page = Page(request, sidebar)
        if not page.exists():
            return u""
        import StringIO
        buff = StringIO.StringIO()
        request.redirect(buff)
        try:
            try:
                page.send_page(content_only=1, content_id="sidebar")
            except TypeError:
                page.send_page(request, content_only=1, content_id="sidebar")
        finally:
            request.redirect()
#        return u'<div class="sidebar">%s</div>' % buff.getvalue()
        return u'<div class="sidepanel">%s</div>' % buff.getvalue()        



    def header(self, d):
        """
        Assemble page header

        @param d: parameter dictionary
        @rtype: string
        @return: page header html
        """
        _ = self.request.getText

        superheader, userpanel = self.flexible_userhome(d)

        html = [
            # Header
            u'<div id="header" class="header">',

            # super-header
            u' <div class="superHeader">',
            superheader,
            u' </div>',
            self.searchform(d),

            # middle header
            u' <div class="midHeader">',
            u'  <div id="locationline">',
            self.logo(),
            #self.interwiki(d), # makes no sense in this theme
            self.linkedSitename(),
            u'  </div>',
            u' </div>',

            # we display all wikis of the farm as links in one line
            # err404: annulation de l'affichage
            #self.emit_custom_html(self.subheader()),

            # Custom html below header (not recomended!)
            #self.emit_custom_html(self.cfg.page_header2),

            self.trail(d),
            u'</div>',

            # Sidebar
            #u'<div id="sidebar" class="sidebar">',
            u'<div class="sidebar">',
            self.wikipanel(d),
            self.pagepanel(d),
# ajout de sidebar:
            self.sidebar(d),

            userpanel,
            u'</div>',

            self.msg(d),

            # Page
            self.startPage(),

            # Iconbar
            self.iconbar(d),

            self.title(d),
            ]
        return u'\n'.join(html)

    def editorheader(self, d):
        """
        Assemble page header for editor

        @param d: parameter dictionary
        @rtype: unicode
        @return: page header html
        """
        _ = self.request.getText
        superheader, userpanel = self.flexible_userhome(d)

        html = [
            # Header
            u' <div id="header" class="header">',

            # super-header
            u' <div class="superHeader">',
            superheader,
            u' </div>',

            # middle header
            u' <div class="midHeader">',
            self.searchform(d),
            u'  <div id="locationline">',
            self.logo(),
            #self.interwiki(d), # makes no sense in this theme
            self.linkedSitename(),
            u'  </div>',
            u' </div>',

            # we display all wikis of the farm as links in one line
            # err404: annulation de l'affichage
#            self.emit_custom_html(self.subheader()),
            u'</div>',

            # Sidebar
            #u'<div id="sidebar" class="sidebar">',
            u'<div class="sidebar">',
            self.wikipanel(d),
            self.pagepanel(d),
# ajout de sidebar:
            self.sidebar(d),            
            
            userpanel,
            u'</div>',

            self.msg(d),

            # Page
            self.startPage(),
            ]
        return u'\n'.join(html)

    def footer(self, d, **keywords):
        """ Assemble page footer

        @param d: parameter dictionary
        @keyword ...:...
        @rtype: unicode
        @return: page footer html
        """
        page = d['page']
        html = [
            # End of page
#?            # Used to extend the page to the bottom of the sidebar
#?            u'<div id="pagebottom"></div>',
            self.pageinfo(page),
            self.endPage(),

            # Pre footer custom html (not recommended!)
            #self.emit_custom_html(self.cfg.page_footer1),

            # Footer
            u'<div id="footer">',
            self.credits(d),
            self.showversion(d, **keywords),
            u'</div>',

            # Post footer custom html
            #self.emit_custom_html(self.cfg.page_footer2),
            ]
        return u'\n'.join(html)

    def splitNavilink_off(self, text, localize=1):
        """ Split navibar links into pagename, link to page

        This overrides the defaut method. In contrast to default quicklinks
        are cut down to a maximum length

        @param text: the text used in config or user preferences
        @rtype: tuple
        @return: pagename or url, link to page or url
        """
        request = self.request

        # Handle [pagename title] or [url title] formats
        if text.startswith('[') and text.endswith(']'):
            try:
                pagename, title = text[1:-1].strip().split(' ', 1)
                title = title.strip()
                localize = 0
            except (ValueError, TypeError):
                # Just use the text as is.
                pagename = title = text

        # Handle regular pagename like "FrontPage"
        else:
            # Use localized pages for the current user
            if localize:
                page = wikiutil.getLocalizedPage(request, text)
            else:
                page = Page(request, text)
            pagename = page.page_name
            title = page.split_title(request)
            title = self.shortenPagename(title)
            link = page.link_to(request, title)


        from MoinMoin import config
        for scheme in self.linkSchemas:
            if pagename.startswith(scheme):
                title = self.shortenPagename(wikiutil.escape(title))  # DL change
                link = '<a href="%s">%s</a>' % (pagename, title)
                return pagename, link

        # remove wiki: url prefix
        if pagename.startswith("wiki:"):
            pagename = pagename[5:]

        # try handling interwiki links
        try:
            interwiki, page = pagename.split(':', 1)
            thiswiki = request.cfg.interwikiname
            if interwiki == thiswiki:
                pagename = page
                title = self.shortenPagename(page)  # DL change
            else:
                return (pagename,
                        self.request.formatter.interwikilink(True, interwiki, page) +
                        page +
                        self.request.formatter.interwikilink(False, interwiki, page)
                        )

        except ValueError:
            pass

        # Normalize page names, replace '_' with ' '. Usually
        # all names use spaces internally, but for
        # [name_with_spaces label] we must save the underscores
        # until this point.
        pagename = request.normalizePagename(pagename)
        link = Page(request, pagename).link_to(request, title)

        return pagename, link

def execute(request):
    """ Generate and return a theme object

    @param request: the request object
    @rtype: MoinTheme
    @return: Theme object
    """
    return Theme(request)
