# -*- coding: iso-8859-1 -*-
"""
    MoinMoin theme by and for crw.
"""

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

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

    name = "wallpaper"

    def header(self, d):
        """
        Assemble page header

        @param d: parameter dictionary
        @rtype: string
        @return: page header html
        """
        _ = self.request.getText

        html = [
            # Custom html above header
            self.emit_custom_html(self.cfg.page_header1),

            # Header
            u'<div id="header">',
            self.logo(),
            self.searchform(d),
            u'</div>',

            # Custom html below header (not recomended!)
            self.emit_custom_html(self.cfg.page_header2),

            # TODO. send sidebar and editbar at the end of the content, so 
            # they don't get in the way for screenreaderss.
            # need to work more on CSS positioning before this!

            u'<div id="sidebar">',
            self.username(d),
            self.navibar(d),
            self.trail(d),
            u'</div>',


            u'<div id="pagetop" class="editbardiv">',
		    self.editbar(d),
		    u'</div>',

            self.msg(d),

            # Page
            self.startPage(),
            self.title(d),
            ]
        return u'\n'.join(html)

    def footer(self, d, **keywords):
        """ Assemble page footer

        @param d: parameter dictionary
        @keyword ...:...
        @rtype: string
        @return: page footer html
        """
        page = d['page']
        html = [
            # Page end
            # Used to extend the page to the bottom of the sidebar

            self.pageinfo(page),
            self.endPage(),


             u'<div id="pagebottom" class="editbardiv">',
		     self.editbar(d),
		     u'</div>',
            
            # Custom html above footer
            self.emit_custom_html(self.cfg.page_footer1),
            self.credits(d),
		     # And below
            self.emit_custom_html(self.cfg.page_footer2)
            ]
        return u'\n'.join(html)

    def searchform(self, d):
        """
        copy-pasted from the base class, modified to add a class=submit to
        the form buttons
        
        @param d: parameter dictionary
        @rtype: unicode
        @return: search form html
        """
        _ = 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'''
<form id="searchform" method="get" action="">
<div>
<input type="hidden" name="action" value="fullsearch">
<input type="hidden" name="context" value="180">
<label for="searchinput">%(search_label)s</label>
<input id="searchinput" type="text" name="value" value="%(search_value)s" size="20"
    onfocus="searchFocus(this)" onblur="searchBlur(this)"
    onkeyup="searchChange(this)" onchange="searchChange(this)" alt="Search">
<input id="titlesearch" class="submit" name="titlesearch" type="submit"
    value="%(search_title_label)s" alt="Search Titles">
<input id="fullsearch" class="submit" name="fullsearch" type="submit"
    value="%(search_full_label)s" alt="Search Full Text">
</div>
</form>
<script type="text/javascript">
<!--// Initialize search form
var f = document.getElementById('searchform');
f.getElementsByTagName('label')[0].style.display = 'none';
var e = document.getElementById('searchinput');
searchChange(e);
searchBlur(e);
//-->
</script>
''' % d
        return html


    def editbar(self, d):
        """ Assemble the page edit bar.

        Display on existing page. Replace iconbar, showtext, edit text,
        refresh cache and available actions.
        
        @param d: parameter dictionary
        @rtype: unicode
        @return: iconbar html
        """
        page = d['page']       
        if not self.shouldShowEditbar(page):
            return ''

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

        # Make new edit bar
        request = self.request
        _ = self.request.getText
        link = wikiutil.link_tag
        quotedname = wikiutil.quoteWikinameURL(page.page_name)
        links = []
        add = links.append
        
        # Parent page
        parent = page.getParentPage()
        if parent:
           add(parent.link_to(request, _("Show Parent", formatted=False))) 
        
        # Page actions
        if page.isWritable() and request.user.may.write(page.page_name):
            add(link(request, quotedname + '?action=edit', _('Edit')))
        else:
            add(_('Immutable Page', formatted=False))              
        
        add(link(request, quotedname + '?action=diff',
                 _('Show Changes', formatted=False)))
        add(link(request, quotedname + '?action=info',
                 _('Get Info', formatted=False)))
        add(self.subscribeLink(page))
        add(self.actionsMenu(page))
        
        # Format
        items = '\n'.join(['<li>%s</li>' % item for item in links if item != ''])
        html = u'<ul class="editbar">\n%s\n</ul>\n' % items
        
        # cache for next call
        self._cache[cacheKey] = html
        return html


    def actionsMenu(self, page):
        """ Hacked version of the actionsMenu from the base class.  Turn
        the menu into a list and let the css turn it into a menu.

        TODO 
        - Not sure what the javascript stuff in the main themes does, or if
        this breaks things by overriding it
        - this could be a lot neater
        - Add access keys to the links
        - I've broken the il8n by using shorter names for the actions
        - Would be good if the actions could specify their own help string

        @param page: current page, Page object
        @rtype: unicode
        @return: actions menu html fragment
        """
        request = self.request
        _ = request.getText

        spacer = (0, '--------', None)
        menuTitle = _('More Actions...')
        menu = [
            ('raw', _('Raw Text'), _('View the raw wiki text markup for this page')),
            ('print', _('Print View'), _('A page view suitable for printing')),
            ('refresh', _('Delete Cache'), _('Refresh the stored cache for this page')),
            spacer,
            ('AttachFile', _('Attach File'), _('Attach a file to this page')),
            ('SpellCheck', _('Check Spelling'), _('Check spelling')),
            ('LikePages', _('Like Pages'), _('Show pages similar to the current one')),
            ('LocalSiteMap', _('Local Pages'), _('Show pages linked to the current one')),
            spacer,
            ('RenamePage', _('Rename Page'), _('Rename Page')),
            ('DeletePage', _('Rename Page'), _('Rename Page'))
            ]
        actions = [item[0] for item in menu]

        items = []
        quotedname = wikiutil.quoteWikinameURL(page.page_name)
        link = wikiutil.link_tag
        available = request.getAvailableActions(page)
        for action, text, description in menu:
            # Enable delete cache only if page can use caching
            enabled = action
            if enabled:
                if action == 'refresh':
                    if not page.canUseCache():
                        enabled = 0

                if action[0].isupper() and not action in available:
                    enabled = 0

            if enabled:
                url = '%s?action=%s' % (quotedname, action)
                attrs = 'title="%s"' % description
                items.append(link(request, url, text, formatted=False, attrs=attrs))
            else:
                items.append(text)

        # Add custom actions not in the standard menu
        more = [item for item in available if not item in actions]
        more.sort()
        if more:
            # Add separator
            items.append(spacer[1])

            # Add more actions (all enabled)
            for action in more:
                # Always add spaces: AttachFile -> Attach File
                # XXX TODO do not create page just for using split_title
                title = Page(request, action).split_title(request, force=1)
                # Use translated version if available
                title = _(title, formatted=False)

                url = '%s?action=%s' % (quotedname, action)
                attrs = 'title="%s"' % title
                items.append(link(request, url, title, formatted=False, attrs=attrs))

        html = '''
%s
<ul>
%s
</ul>
''' % (menuTitle, '\n'.join(['<li>%s</li>' % item for item in items]))
        return html

def execute(request):
    """
    Generate and return a theme object

    @param request: the request object
    @rtype: MoinTheme
    @return: Theme object
    """
    return Theme(request)

