# -*- coding: iso-8859-1 -*-
"""
    MoinMoin moose theme

    Based on the classic theme.

    @copyright: 2006 by RadomirDopieralski (moose@sheep.prv.pl)
    @license: GNU GPL, see COPYING for details.
"""

from MoinMoin import wikiutil, version
from MoinMoin import caching
from MoinMoin.theme import ThemeBase
from MoinMoin.Page import Page


class Theme(ThemeBase):
    """ here are the functions generating the html responsible for
        the look and feel of your wiki site
    """
    
    name = "moose"

    # fake _ function to get gettext recognize those texts:
    _ = lambda x: x

    # TODO: remove icons that are not used any more.
    icons = {
        # key         alt                        icon filename      w   h
        # ------------------------------------------------------------------
        # navibar
        'help':       ("%(page_help_contents)s", "moin-help.gif",   24, 24),
        'find':       ("%(page_find_page)s",     "moin-search.gif", 24, 24),
        'diff':       (_("Diffs"),               "moin-diff.gif",   24, 24),
        'info':       (_("Info"),                "moin-info.gif",   24, 24),
        'edit':       (_("Edit"),                "moin-edit.gif",   24, 24),
        'unsubscribe':(_("Unsubscribe"),         "moin-unsubscribe.gif",  24, 24),
        'subscribe':  (_("Subscribe"),           "moin-subscribe.gif", 24, 24),
        'raw':        (_("Raw"),                 "moin-raw.gif",    24, 24),
        'xml':        (_("XML"),                 "moin-xml.gif",    24, 24),
        'print':      (_("Print"),               "moin-print.gif",  24, 24),
        'view':       (_("View"),                "moin-show.gif",   24, 24),
        'home':       (_("Home"),                "moin-home.gif",   24, 24),
        'up':         (_("Up"),                  "moin-parent.gif", 23, 23),
        # FileAttach
        'attach':     ("%(attach_count)s",       "moin-attach.gif", 24, 24),
        # RecentChanges
        'rss':        (_("[RSS]"),               "moin-rss.png",    36, 14),
        'deleted':    (_("[DELETED]"),           "moin-delete.gif", 24, 24),
        'updated':    (_("[UPDATED]"),           "moin-show.gif",24, 24),
        'new':        (_("[NEW]"),               "moin-edit.gif",    24, 24),
        'diffrc':     (_("[DIFF]"),              "moin-diff.gif",   24, 24),
        # General
        'bottom':     (_("[BOTTOM]"),            "moin-bottom.gif", 14, 10),
        'top':        (_("[TOP]"),               "moin-top.gif",    14, 10),
        'www':        ("[WWW]",                  "moin-www.gif",    11, 11),
        'mailto':     ("[MAILTO]",               "moin-email.gif",  14, 10),
        'news':       ("[NEWS]",                 "moin-news.gif",   10, 11),
        'telnet':     ("[TELNET]",               "moin-telnet.gif", 10, 11),
        'ftp':        ("[FTP]",                  "moin-ftp.gif",    11, 11),
        'file':       ("[FILE]",                 "moin-ftp.gif",    11, 11),
        # search forms
        'searchbutton': ("[?]",                  "moin-search.gif", 12, 12),
        'interwiki':  ("[%(wikitag)s]",          "moin-inter.gif",  16, 16),
    }
    del _

    def footer(self, d, **keywords):
        """ Assemble wiki footer
        
        @param d: parameter dictionary
        @keyword ...:...
        @rtype: unicode
        @return: page footer html
        """
        page = d['page']
        dict = {
            'search_form_html': self.searchform(d),
            'username_html':  self.username(d),
            'iconbar_html': self.iconbar(d),
            'page_footer1': self.emit_custom_html(self.cfg.page_footer1),
            'page_footer2': self.emit_custom_html(self.cfg.page_footer2),
            'page_info': self.pageinfo(page),
            'end_page': self.endPage(),
            'editbar': self.editbar(d, **keywords),
            'credits': self.credits(d),
            'version': self.showversion(d, **keywords),
        }
        return u'''
%(page_info)s
%(end_page)s
<div id="footer">
    %(page_footer1)s
    %(iconbar_html)s
    %(editbar)s
    %(search_form_html)s
    %(username_html)s
    %(page_footer2)s
</div>
%(credits)s
%(version)s
'''%dict

    def editbar(self, d, **keywords):
        if not self.shouldShowEditbar(d['page']):
            return ''
        parts = [ self.edit_link(d, **keywords), self.availableactions(d), ]
        return ''.join(parts)

    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 header(self, d):
        """
        Assemble page header
        
        @param d: parameter dictionary
        @rtype: string
        @return: page header html
        """
        dict = {
            'config_header1_html': self.emit_custom_html(self.cfg.page_header1),
            'config_header2_html': self.emit_custom_html(self.cfg.page_header2),
            'logo_html':  self.logo(),
            'title_html':  self.title(d),
            'navibar_html': self.navibar(d),
            'msg_html': self.msg(d),
            'trail_html': self.trail(d),
            'startpage_html': self.startPage(),
            'interwiki_html':  self.interwiki(d),
        }
        dict.update(d)

        html = """
%(config_header1_html)s
<div id="header"> 
%(logo_html)s
<div id="navidiv">%(navibar_html)s</div>
<div id="traildiv">%(trail_html)s</div>
<div id="locationline">%(interwiki_html)s%(title_html)s</div>
%(msg_html)s
<div class="clear"></div>
</div>

%(config_header2_html)s

%(startpage_html)s
""" % dict
        return html

    def editorheader(self, d):
        """
        Assemble page header for editor
        
        @param d: parameter dictionary
        @rtype: string
        @return: page header html
        """
        dict = {
            'config_header1_html': self.emit_custom_html(self.cfg.page_header1),
            'config_header2_html': self.emit_custom_html(self.cfg.page_header2),
            'title_html': self.title(d),
            'msg_html': self.msg(d),
            'startpage_html': self.startPage(),
        }
        dict.update(d)

        html = """
%(config_header1_html)s

%(title_html)s
%(msg_html)s

%(config_header2_html)s

%(startpage_html)s
""" % dict
        return html

    def navibar(self, d):
        """ Assemble the navibar

        @param d: parameter dictionary
        @rtype: unicode
        @return: navibar html
        """
        request = self.request
        found = {} # pages we found. prevent duplicates
        items = [] # navibar items
        item = u'<li class="%s">%s</li>'
        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 == current:
                    cls = 'wikilink current'
                else:
                    cls = 'wikilink'
                items.append(item % (cls, link))
                found[pagename] = 1

        # Add user links to wiki links, eliminating duplicates.
        userlinks = request.user.getQuickLinks()
        for text in userlinks:
            # Split text without localization, user knows what he wants
            pagename, link = self.splitNavilink(text, localize=0)
            if not pagename in found:
                if pagename == current:
                    cls = 'userlink current'
                else:
                    cls = 'userlink'
                items.append(item % (cls, link))
                found[pagename] = 1

        # Add current page at end
#        if not current in found:
#            title = d['page'].split_title(request)
#            title = self.shortenPagename(title)
#            link = d['page'].link_to(request, title)
#            cls = 'current'
#            items.append(item % (cls, link))

        # Assemble html
        items = u''.join(items)
        html = u'''
<ul id="navibar">
%s
</ul>
''' % items
        return html

    def username(self, d):
        """ Assemble the username / userprefs link
        
        @param d: parameter dictionary
        @rtype: unicode
        @return: username html
        """
        request = self.request
        _ = request.getText
        preferencesPage = wikiutil.getSysPage(request, 'UserPreferences')
        
        userlinks = []
        # Add username/homepage link for registered users. We don't care
        # if it exists, the user can create it.
        if request.user.valid and request.user.name:
            interwiki = wikiutil.getInterwikiHomePage(request)
            name = request.user.name
            aliasname = request.user.aliasname
            if not aliasname:
                aliasname = name
            title = "%s @ %s" % (aliasname, interwiki[0])
            homelink = (request.formatter.interwikilink(1, title=title, *interwiki) +
                        request.formatter.text(name) +
                        request.formatter.interwikilink(0))
            userlinks.append(homelink)        
            # Set pref page to localized Preferences page
            title = preferencesPage.split_title(request)
            userlinks.append(preferencesPage.link_to(request, text=title))
            
        if request.cfg.show_login:
            if request.user.valid:
                userlinks.append("""\
<form action="" method="POST">
<input type="hidden" name="action" value="userform">
<input type="submit" name="logout" value="%(logout)s">
</form>
""" % { 'logout': _('Logout') })
            else:
                userlinks.append(preferencesPage.link_to(request, text=_("Login")))

        userlinks = [u'<span>%s</span>' % link for link in userlinks]
        html = u'<div id="username">%s</div>' % ', '.join(userlinks)
        return html

    def title(self, d):
        """ Assemble the title (not using breadcrumbs)
        
        @param d: parameter dictionary
        @rtype: string
        @return: title html
        """
        _ = self.request.getText
        content = []
        if d['title_link']: # having a link means we have a (linked) pagename ONLY as title, not a message title
                            # XXX this method is rather ugly and should be improved
            curpage = ''
            segments = d['page_name'].split('/') # was: title_text
            for s in segments[:-1]:
                curpage += s
                content.append("<span>%s</span>" % Page(self.request, curpage).link_to(self.request, s))
                curpage += '/'
            content.append(('<span><a class="backlink" title="%(title)s" href="%(href)s">%(text)s</a></span>') % {
                'title': _('Click to do a full-text search for this title'),
                'href': d['title_link'],
                'text': wikiutil.escape(segments[-1]),
                })
        else:
            content.append('<span>%s</span>' % wikiutil.escape(d['title_text']))

        html = '''
<div id="pagelocation">
%s
</div>
''' % "".join(content)
        return html

    # Footer stuff #######################################################
    
    def edit_link(self, d, **keywords):
        """
        Assemble EditText link (or indication that page cannot be edited)
        
        @param d: parameter dictionary
        @rtype: string
        @return: edittext link html
        """
        page = d['page']
        return  u'<ul class="editbar"><li>%s, </li>' % self.editorLink(page)

    def availableactions(self, d):    
        """
        assemble HTML code for the available actions
        
        @param d: parameter dictionary
        @rtype: string
        @return: available actions html
        """
        request = self.request
        _ = request.getText
        html = []
        page = d['page']
        available = request.getAvailableActions(page)
        if available:
            available = available.keys()
            available.sort()
            for action in available:
                # Always add spaces: AttachFile -> Attach File 
                # XXX TODO do not make a page object just for split_title
                title = Page(request, action).split_title(request, force=1)
                # Use translated version if available
                title = _(title, formatted=False)
                params = '%s?action=%s' % (d['q_page_name'], action)
                link = wikiutil.link_tag(request, params, title)
                html.append(link)
                
        title = _("DeleteCache", formatted=False)
        params = '%s?action=%s' % (d['page_name'], 'refresh')
        link = wikiutil.link_tag(request, params, title)
        
        cache = caching.CacheEntry(request, page, page.getFormatterName())
        date = request.user.getFormattedDateTime(cache.mtime())
        deletecache = u' <li>%s %s</li>' % (link, _('(cached %s)') % date)

        html = deletecache + u'</ul><p>%s %s</p>\n' % (_('Or try one of these actions:'),
                                       u', '.join(html))
        return html


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

