# -*- coding: iso-8859-1 -*-

import re
from MoinMoin import config, wikiutil
from MoinMoin.support import difflib
from MoinMoin.Page import Page
from MoinMoin.action import get_available_actions

# Ripped from the LikePages action
# renamed by clauz
def executeold(pagename, request):
    _ = request.getText
    from MoinMoin.formatter.text_html import Formatter
    request.formatter = Formatter(request)

    request.emit_http_headers()

    # This action generate data using the user language
    request.setContentLanguage(request.lang)
    request.theme.send_title(_('Actions for %s') % pagename, page_name=pagename)
        
    # Start content - IMPORTANT - without content div, there is no
    # direction support!
    request.write(request.formatter.startContent("content"))

    # Just list the actions
    request.write(availableactions(request))

    # End content and send footer
    request.write(request.formatter.endContent())
    request.theme.send_footer(pagename)

# copied from LikePages by Clauz
def closeMatches(pagename, pages):
    """ Get close matches.

    Return all matching pages with rank above cutoff value.

    @param pagename: page name to match
    @param pages: list of page names
    @rtype: list
    @return: list of matching pages, sorted by rank
    """
    # Match using case insensitive matching
    # Make mapping from lowerpages to pages - pages might have same name
    # with different case (although its stupid).
    lower = {}
    for name in pages:
        key = name.lower()
        if key in lower:
            lower[key].append(name)
        else:
            lower[key] = [name]

    # Get all close matches
    all_matches = difflib.get_close_matches(pagename.lower(), lower.keys(),
                                            len(lower), cutoff=0.6)

    # Replace lower names with original names
    matches = []
    for name in all_matches:
        matches.extend(lower[name])

    return matches


# copied from LikePages by Clauz
def findMatches(pagename, request, s_re=None, e_re=None):
    """ Find like pages

    @param pagename: name to match
    @param request: current reqeust
    @param s_re: start re for wiki matching
    @param e_re: end re for wiki matching
    @rtype: tuple
    @return: start word, end word, matches dict
    """
    # Get full list of pages, with no filtering - very fast. We will
    # first search for like pages, then filter the results.
    pages = request.rootpage.getPageList(user='', exists='')

    # Remove current page
    try:
        pages.remove(pagename)
    except ValueError:
        pass

    # Get matches using wiki way, start and end of word
    start, end, matches = wikiMatches(pagename, pages, start_re=s_re,
                                      end_re=e_re)

    # Get the best 10 close matches
    close_matches = {}
    found = 0
    for name in closeMatches(pagename, pages):
        # Skip names already in matches
        if name in matches:
            continue

        # Filter deleted pages or pages the user can't read
        page = Page(request, name)
        if page.exists() and request.user.may.read(name):
            close_matches[name] = 8
            found += 1
            # Stop after 10 matches
            if found == 10:
                break

    # Filter deleted pages or pages the user can't read from
    # matches. Order is important!
    for name in matches.keys(): # we need .keys() because we modify the dict
        page = Page(request, name)
        if not (page.exists() and request.user.may.read(name)):
            del matches[name]

    # Finally, merge both dicts
    matches.update(close_matches)

    return start, end, matches

# Ripped from the LikePages action by clauz
def execute(pagename, request):
    _ = request.getText
    #start, end, matches = findMatches(pagename, request)

    # Error?
    #if isinstance(matches, (str, unicode)):
    #    request.theme.add_msg(wikiutil.escape(matches), "info")
    #    Page(request, pagename).send_page()
    #    return


    # One match - display it
    #if len(matches) == 1:
    #    request.theme.add_msg(_('Exactly one page like "%s" found, redirecting to page.') % (wikiutil.escape(pagename), ), "info")
    #    Page(request, matches.keys()[0]).send_page()
    #    return

    # more than one match, list 'em
    # This action generate data using the user language
    request.setContentLanguage(request.lang)

    request.theme.send_title(_('Actions for "%s"') % (pagename), pagename=pagename)

    # Start content - IMPORTANT - without content div, there is no
    # direction support!
    request.write(request.formatter.startContent("content"))

    request.write(availableactions(request))

    # End content and send footer
    request.write(request.formatter.endContent())
    request.theme.send_footer(pagename)
    request.theme.send_closing_html()

# Make a link to action
def actionlink(request, action, title, comment=''):
    page = request.page
    _ = request.getText
    # Always add spaces: AttachFile -> Attach File 
    # XXX TODO do not make a page object just for split_title
    title = Page(request, title).split_title(request) #, force=1)
    # Use translated version if available
    title = _(title, formatted=False)
    params = '%s?action=%s' % (page.page_name, action)
    link = wikiutil.link_tag(request, params, _(title))
    return u''.join([ u'<li>', link, comment, u'</li>' ])


# Rippped from the theme code
# Renamed by Clauz
def oldavailableactions(request):
    page = request.page
    _ = request.getText
    html = ''
    links = []
    available = request.getAvailableActions(page)
#    try:
#        available = available.keys()
#    except AttributeError:
#        pass
    for action in available:
        links.append(actionlink(request, action, action))
    if page.isWritable() and request.user.may.write(page.page_name):
        links.append(actionlink(request, 'edit', 'EditText'))
    if request.user.valid and request.user.email:
        action = ("Subscribe", "Unsubscribe")[request.user.isSubscribedTo([page.page_name])]
        links.append(actionlink(request, 'subscribe', action))
    if request.user.valid:
        links.append(actionlink(request, 'userform&logout=logout', 'Logout'))
    links.append(actionlink(request, 'print', 'PrintView'))
    links.append(actionlink(request, 'raw', 'ViewRawText'))
    links.append(actionlink(request, 'refresh', 'DeleteCache'))
    html = u'<ul>%s</ul>' % u''.join(links)
    return html

# copied from classic.py by Clauz
def availableactions(d):
    """
    assemble HTML code for the available actions

    @param d: parameter dictionary
    @rtype: string
    @return: available actions html
    """
    request = d
    _ = request.getText
    html = []
    page = request.page
    available = get_available_actions(request.cfg, page, request.user)
    if available:
        available = list(available)
        available.sort()
        for action in available:
            # Always add spaces: AttachFile -> Attach File
            # XXX do not make a page object just for split_title
            #title = Page(request, action).split_title(force=1)
            title = action
            # Use translated version if available
            title = _(title)
            querystr = {'action': action}
            link = page.link_to(request, text=title, querystr=querystr, rel='nofollow')
            html.append(link)

    title = _("DeleteCache")
    link = page.link_to(request, text=title, querystr={'action': 'refresh'}, rel='nofollow')

    html = u'<p>%s %s</ul></p>\n' % (_('Available actions: <ul><li>'),
                                   u'</li><li>'.join(html))
    return html



