"""
Modern based cms theme
======================

If you want to use a wiki as a tool to create a regular site easily,
this theme is for you. The wiki looks like a plain site to visitors or
users without edit rights, and a wiki to users with edits rights. 

This is also a replacement for the readonly theme that was part of release 1.2.


Problems
--------
Some actions are not available for visitors:

- Show Raw Text
- Show Print Preview
- Show Like Pages
- Show Local Site Map
- Delete Cache

Most of these are not really needed for a visitor. Print style sheet is
used transparently when you print a page. Like Pages and Local Site Map
should be available, but are not really needed if you have a good
search.

Missing page will suggest visitors to create a new page, but they will
always fail because they don't have acl rights. This should be fixed in
other place.


Install
-------

1. Put in your wiki/data/plugin/theme/

2. Prevent visitors from writing using acl::

    acl_rights_before = (u"WikiAdmin:read,write,delete,revert,admin "
                         u"EditorsGroup:read,write,delete,revert ")
    acl_rights_default = u"All:read "
                          
Remember that acl you put on a page will override the default acl!

3. Make it the default and only theme on your site::

    theme_default = 'modern_cms'
    theme_force = True
    
    
Compatibility
--------------
Tested with release 1.3.5, should work with any 1.3 release.


Legal
-----
@copyright (c) 2005 Nir Soffer <nirs@freeshell.org>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""

from MoinMoin import wikiutil, config
from MoinMoin.Page import Page
from MoinMoin.theme import modern


class Theme(modern.Theme):
    
    # Uses modern CSS and images
    name = "modern"

    def shouldShowEditbar(self, page):
        """ Hide the edit bar if you can't edit """
        if self.request.user.may.write(page.page_name):
            return modern.Theme.shouldShowEditbar(self, page)
        return False

    def navigation(self, d):
        """ Return page navigation interface 
        
        e.g. Parent/Child/Child, where each part is a link to that part. Some
        people call this bread crumbs.
        """
        if not config.allow_subpages:
            return ''
        links = []
        parents = d['page'].page_name.split('/')[:-1]
        parts = []
        for name in parents:
            parts.append(name)
            leaf = '/'.join(parts)
            link = Page(self.request, leaf).link_to(self.request, name)
            links.append(link)
        links = '/'.join(links)
        return u'<div id="navigation">\n%s\n</div>\n' % links
        
    def title(self, d):
        """ Return page title with optional navigation interface """
        _ = self.request.getText
        title = '<h1 id="title">%s</h1>'
        if d['title_link']:
            # Page views
            name = d['title_text']
            content = ('<a title="%(title)s" href="%(href)s">%(text)s</a>') % {
                'title': _('Click to do a full-text search for this title'),
                'href': d['title_link'],
                'text': wikiutil.escape(self.pageLastName(name)),
                }
            return self.navigation(d) + title % content
        else:
            # Search results and other actions
            return title % wikiutil.escape(d['title_text'])

    def pageLastName(self, name):
        """ This should be in the Page class, but its not """
        if not config.allow_subpages:
            return name
        return name[name.rfind('/') + 1:]

    def shortenPagename(self, name):
        """ Shorten page names
        
        This is a modified copy from theme/__init__.py. Modified to
        show only the last name of a page, even if there is room for
        the full name.
        """
        name = self.pageLastName(name)
        maxLength = self.maxPagenameLength()
        if len(name) > maxLength:
            half, left = divmod(maxLength - 3, 2)
            name = u'%s...%s' % (name[:half + left], name[-half:])
        return name

    def editbar(self, d):
        """ Return edit bar interface
        
        This is a copy of modern editbar, modified to remove the
        'Show Parent' link.
        """
        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
        
        # 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 execute(request):
    return Theme(request)
