# -*- coding: iso-8859-1 -*-
"""
    MoinMoin monobook theme.  Uses the css sheet from
    http://wikipedia.org, adapting the moin output to fit it.

    Adapted by Jim Clark <jim AT clarkster DOT co DOT uk>

    Version 0.4 for MoinMoin 1.5.x :
        Jean-Michel Grimaldi <jm AT via DOT ecp DOT fr>

    @license: GNU GPL, see COPYING for details.
"""

from MoinMoin.theme import ThemeBase
from MoinMoin import wikiutil, i18n
from MoinMoin.Page import Page

class Theme(ThemeBase):

    name = "monobook"

    # Standard set of style sheets
    stylesheets = (
        # media         basename
        ('all',         'common'),
        ('screen',      'monobook'),
        ('screen',      'screen'),
        ('print',       'print'),
        ('projection',  'projection'),
        )


# Public functions #####################################################

    def header(self, d, **kw):
        """ Assemble wiki header
        Here we don't add any menu bars, search bars, etc - instead wait
        until the footer.  This keeps the HTML cleaner and more accessible,
        making sure the main content arrives first.
        """
        html = [
            u'<div id="globalWrapper">',
            u'<div id="column-content">',
            self.startPage(),
            self.msg(d),
            self.title(d),
        ]
        return u'\n'.join(html)

    def footer(self, d, **keywords):
        """ Assemble wiki footer
        """
        html = [
            # End of page
            u'<div class="visualClear"></div>',
            self.endPage(),
            u'</div>',
            self.columnone(d),
            u'</div>'
            ]
        return u'\n'.join(html)

    def columnone(self, d):
        """ assemble all the navigation aids for the page
        """
        page = d['page']
        html = [
            u'<div id="column-one">',
            self.editbar(d),
            self.username(d),
            u'<div class="portlet" id="p-logo">',
            self.logo(),
            u'</div>',
            self.navibar(d),
            self.searchform(d),
            u'<div class="portlet" id="p-nav">',
            u'<h5>Parcours</h5>',
            u'<div class="pBody">',
	    self.trail(d),
            u'</div>',
            u'</div>',
            self.actionmenu(d),
            u'<div class="visualClear"></div>',
            u'<div id="footer">',
            self.pageinfo(page),
            self.credits(d),
            u'</div>',
            u'</div>'
            ]
        return u'\n'.join(html)

    def headscript(self, d):
        """ Override to not output search/action menu javascript.
        (perhaps not a good idea)
        """
        return ''

    def extendedAttrs(self, title, accesskey):
        """ Helper function for assembling titled access key links
        """
        return 'title="%(title)s [alt-%(accesskey)s]" accesskey=%(accesskey)s' % \
                     {'accesskey' : accesskey,
                      'title' : title}

    def editbar(self, d):
        """ Display a list of actions for the page.  This list will be turned
        into a set of tabbed views on the page by the css.
        """
        page = d['page']       
        if not self.shouldShowEditbar(page):
            return ''

        html = self._cache.get('editbar')
        if html is None:
            items = []
            current = self.request.form.get('action', ['show'])[0]

            params = wikiutil.quoteWikinameURL(page.page_name) + '?action=show'
            articleLink = wikiutil.link_tag(self.request, params, 'article', **{'name': "articleLink"})

            # Remove empty items and format as list
            for item in [articleLink] + self.editbarItems(page):
                if (item.count('<form')):
                    continue

                if item.count('action=%s' % current):
                    cls = 'selected'
                else:
                    cls = 'none'
                items.append('<li class="%s">%s</li>' % (cls, item))

            html = [
                u'<div id="p-cactions" class="portlet">',
                u'<ul class="editbar">%s</ul>\n' % ''.join(items),
                u'</div>'
                ]
            html = ''.join(html)
            self._cache['editbar'] = html

        return html


    def actionmenu(self, d):
        """ different implementation of the actionmenu (aka toolbox) 
        """

        page = d['page']

        # Use cached actionmenu if possible.
        cacheKey = 'actionmenu'
        cached = self._cache.get(cacheKey)
        if cached:
            return cached

        request = self.request
        _ = request.getText
        quotedname = wikiutil.quoteWikinameURL(page.page_name)
        
        menu = [
            'raw',
            'print',
            'RenderAsDocbook',
            'refresh',
            '__separator__',
            'SpellCheck',
            'LikePages',
            'LocalSiteMap',
            '__separator__',
            'RenamePage',
            'DeletePage',
            '__separator__',
            'MyPages',
            'SubscribeUser',
            '__separator__',
            'Despam',
            'PackagePages',
            ]

        titles = {
            # action: menu title
            '__title__': _("More Actions:", formatted=False),
            # Translation may need longer or shorter separator
            '__separator__': _('------------', formatted=False),
            'raw': _('Raw Text', formatted=False),
            'print': _('Print View', formatted=False),
            'refresh': _('Delete Cache', formatted=False),
            'SpellCheck': _('Check Spelling', formatted=False), # rename action!
            'RenamePage': _('Rename Page', formatted=False),
            'DeletePage': _('Delete Page', formatted=False),
            'LikePages': _('Like Pages', formatted=False),
            'LocalSiteMap': _('Local Site Map', formatted=False),
            'MyPages': _('My Pages', formatted=False),
            'SubscribeUser': _('Subscribe User', formatted=False),
            'Despam': _('Remove Spam', formatted=False),
            'PackagePages': _('Package Pages', formatted=False),
            'RenderAsDocbook': _('Render as Docbook', formatted=False),
            }

        links = []
        link = ''
        
        # Format standard actions
        available = request.getAvailableActions(page)
        for action in menu:
            data = {'action': action, 'disabled': 0, 'title': titles[action]}

            # Enable delete cache only if page can use caching
            if action == 'refresh':
                if not page.canUseCache():
                    data['action'] = 'show'
                    data['disabled'] = 1

            # Special menu items. Without javascript, executing will
            # just return to the page.
            elif action.startswith('__'):
                data['action'] = 'show'

            # Actions which are not available for this wiki, user or page
            if (action[0].isupper() and not action in available):
                data['disabled'] = 1

            if (action == '__separator__'):
                link = '<hr>'
            elif (data['disabled']):
                link = '<li>%s</li>' % data['title']
            else:
                link = '<li>%s</li>' % wikiutil.link_tag(self.request, \
                            quotedname + '?action=' + data['action'], data['title'])

            links.append(link)

        # Add custom actions not in the standard menu
        more = [item for item in available if not item in titles and not item in ('AttachFile',)]
        more.sort()
        if more:
            links.append(titles['__separator__'])
            # Add more actions (all enabled)
            for action in more:
                title = Page(request, action).split_title(request, force=1)
                # Use translated version if available
                title = _(title, formatted=False)
                link = '<li>%s</li>' % wikiutil.link_tag(self.request, \
                            quotedname + '?action=' + action, title)
                links.append(link)

        html = [
            u'<div class="portlet" id="p-tb">',
            u'<h5>Toolbox</h5>',
            u'<div class="pBody">',
            u'<ul>',
            u'%s</ul>' % '\n'.join(links),
            u'</ul>',
            u'</div>',
            u'</div>',
            ]
        html = ''.join(html)
        # cache for next call
        self._cache[cacheKey] = html
        return html


    def username(self, d):
        """ Assemble the username / userprefs link
        Copied from the base class, modified to include hotkeys and link titles
        """
        from MoinMoin.Page import Page
        request = self.request
        _ = request.getText
        
        userlinks = []
        # Add username/homepage link for registered users. We don't care
        # if it exists, the user can create it.
        if request.user.valid:
            homepage = Page(request, request.user.name)
            title = homepage.split_title(request)
            attrs = self.extendedAttrs(_('User Page'), '.')
            homelink = homepage.link_to(request, text=title, attrs=attrs)
            userlinks.append(homelink)
        
            # Set pref page to localized Preferences page
            attrs = self.extendedAttrs(_('My Preferences'), 'u') 
            prefpage = wikiutil.getSysPage(request, 'UserPreferences')
            userlinks.append(prefpage.link_to(request, text=_('Preferences'), attrs=attrs))

            # Add a logout link (not sure this is really necessary
            attrs = self.extendedAttrs(_('Logout'), 'o')
            page = d['page']
            url = wikiutil.quoteWikinameURL(page.page_name) + \
                   '?action=userform&logout=1'
            link = wikiutil.link_tag(self.request, url, _('Logout'), attrs=attrs)
            userlinks.append(link)

        else:
            # Add a login link (not sure this is really necessary
            attrs = self.extendedAttrs(_('Login'), 'o')
            page = d['page']
            url = wikiutil.quoteWikinameURL(page.page_name) + \
                   '?action=login'
            link = wikiutil.link_tag(self.request, url, _('Login'), attrs=attrs)
            userlinks.append(link)

            
        html = [
            u'<div class="portlet" id="p-personal">',
            u'<ul id="username">',
            u'<li class="pt-userpage">%s</li></ul>' % '</li>\n<li>'.join(userlinks),
            u'</ul>',
            u'</div>'
            ]
        return ''.join(html)

    def searchform(self, d):
        """ assemble HTML code for the search form
        Tweaks from the bass class to wrap in a 'portlet' class, move the
        description to a header tag, add an access key of 'f' and
        add SearchButton class for the buttons
        """
        _ = self.request.getText
        form = self.request.form
        updates = {
            'search_label' : _('Search:'),
            'search_value': wikiutil.escape(form.get('value', [''])[0], 1),
            'search_full_label' : _('Text', formatted=False),
            'search_title_label' : _('Titles', formatted=False),
            }
        d.update(updates)

        html = u'''
<div class="portlet" id="p-search">
<h5><label for="searchInput">%(search_label)s</label></h5>
<div class="pBody">
<form id="searchform" method="get" action="">
<div>
<input type="hidden" name="action" value="fullsearch">
<input type="hidden" name="context" value="180">
<input id="searchInput" name="value" type="text" accesskey="f"
    value="%(search_value)s">
<input id="titlesearch" name="titlesearch" type="submit" class="searchButton"
    value="%(search_title_label)s" alt="Search Titles">
<input id="fullsearch" name="fullsearch" type="submit" class="searchButton"
    value="%(search_full_label)s" alt="Search Full Text">
</div>
</form>
</div>
</div>
''' % d
        return html

    def navibar(self, d):
        """ Alterations from the base class to include access keys and
        descriptions for FrontPage/RecentChanges
        """
        request = self.request
        found = {} # pages we found. prevent duplicates
        links = [] # navibar items
        current = d['page_name']

        # Process config navi_bar
        if request.cfg.navi_bar:
            for text in request.cfg.navi_bar:
                pagename, link = self.splitNavilink(text)
                if pagename == d['page_front_page']:
                    attrs = self.extendedAttrs('Visit the main page', 'z')
                elif pagename == 'RecentChanges':
                    attrs = self.extendedAttrs('List of recent changes in this wiki', 'r')
                else:
                    attrs = ''

                a = wikiutil.link_tag(request, pagename, attrs=attrs)
                links.append(a)         
                found[pagename] = 1

         # Add user links to wiki links, eliminating duplicates.
        userlinks = request.user.getQuickLinks()
        for text in userlinks:
            # Split text without localization, user know what she wants
            pagename, link = self.splitNavilink(text, localize=0)
            if not pagename in found:
                a = wikiutil.link_tag(request, pagename, attrs=attrs)
                links.append(a)                      
                found[pagename] = 1

        html = [
            u'<div class="portlet" id="p-nav">',
            u'<div class="pBody">',
            u'<ul id="navibar">',
            u'<li>%s</li></ul>' % '</li>\n<li>'.join(links),
            u'</ul>',
            u'</div>',
            u'</div>',
            ]
        return ''.join(html)

    def pageinfo(self, page):
        """ Simple override from base class.
        Remove <p> so footer isn't too big
        """
        _ = self.request.getText
        
        if self.shouldShowPageinfo(page):
            info = page.lastEditInfo()
            if info:
                if info['editor']:
                    info = _("last edited %(time)s by %(editor)s") % info
                else:
                    info = _("last modified %(time)s") % info
                return info
        return ''

    def rtl_stylesheet(self, d):
        """ monobook uses a separate css page for rtl alterations.
        Add the rtl stylesheet if the user needs it
        """
        link = ('<link rel="stylesheet" type="text/css" charset="%s"'
                ' media="%s" href="%s">')
        html = []
        if i18n.getDirection(self.request.lang) == 'rtl':
            prefix = self.cfg.url_prefix
            href = '%s/%s/css/%s.css' % (prefix, self.name, 'rtl')
            html.append(link % (self.stylesheetsCharset, 'all', href))
        return '\n'.join(html)

    def html_head(self, d):
        """ Tweak the sending of the head, to include right-to-left 
        alterations if necessary
        """
        html = [
            u'<title>%(title)s - %(sitename)s</title>' % d,
            self.externalScript('common'),
            self.headscript(d), # Should move to separate .js file
            self.guiEditorScript(d),
            self.html_stylesheets(d),
            self.rtl_stylesheet(d),
            self.rsslink(),
            ]
        return '\n'.join(html)

def execute(request):
    """
    Generate and return a theme object
        
    @param request: the request object
    @rtype: MoinTheme
    @return: Theme object
    """
    return Theme(request)
