# -*- coding: iso-8859-1 -*-
"""
    SiteIndex Macro 2014.4.29

    List wiki pages in the site (regular ones, system ones or both).
    It works like TitleIndex, but without letter indexing.

    @copyright: 2009 Renato Silva
    @license: GNU GPLv2
"""

Dependencies = ["namespace"]
from MoinMoin import wikiutil
from MoinMoin.Page import Page
import re

def add_spaces(wiki_name):
    wiki_name = re.compile('([^A-Z\s])([A-Z])').sub(ur'\1 \2', wiki_name)
    wiki_name = re.compile('(\d)(\D)').sub(ur'\1 \2', wiki_name)
    wiki_name = wiki_name.replace('_', ' ')
    return wiki_name.replace('/', ' /')

def macro_SiteIndex(macro, subpages=True, count=False, system_pages=False, regular_pages=True, spaces=True, max_name=0):
    hide_subpages = not subpages
    request = macro.request
    fmt = macro.formatter
    _ = macro._
    output = []

    def get_root_page_name(subpage_name): return subpage_name.split('/')[0]
    def is_system_page(name): return wikiutil.isSystemPage(request, name)
    def is_regular_page(name): return not is_system_page(name)
    def is_root_page(name): return name.find('/') < 0

    system_page_filter = is_system_page if system_pages else None
    regular_page_filter = is_regular_page if regular_pages else None
    allowed = None if regular_pages and system_pages else regular_page_filter or system_page_filter

    page_names = request.rootpage.getPageList(filter=allowed)
    if allowed == None: allowed = (lambda name: True)
    total_pages = len(page_names)
    if total_pages == 0:
        return _('No page found...')

    page_names.sort()
    missing_pages = []
    subpage_count = 0
    subpage_counts = {}
    last_root_page = page_names[0]
    for page_name in page_names:
        subpage_counts[page_name] = -1

    for index, page_name in enumerate(page_names):
        if hide_subpages and count:
            found_root_page = is_root_page(page_name)
            found_subpage = not found_root_page
            found_last_page = index == (total_pages - 1)

            if found_subpage:
                subpage_count += 1
                root_page_name = get_root_page_name(page_name)
                missing_page = not Page(request, root_page_name).exists()

                if missing_page and root_page_name not in missing_pages:
                    missing_pages.append(root_page_name)
                    last_root_page = root_page_name
                elif not allowed(root_page_name):
                    last_root_page = root_page_name

            if (found_root_page or found_last_page) and (subpage_count > 0 or is_root_page(last_root_page)):
                subpage_counts[last_root_page] = subpage_count
                subpage_count = 0
                if found_root_page:
                    last_root_page = page_name

    page_names += missing_pages
    page_names.sort()
    output.append(fmt.bullet_list(1))

    for page_name in page_names:
        page = Page(request, page_name)
        root_page_found = is_root_page(page_name)

        if not hide_subpages or root_page_found:
            output.append(fmt.listitem(1))
            prepared_page_name = add_spaces(page_name) if spaces else page_name
            if max_name > 0:
                link_title = re.compile('(.{%d}).+' % max_name).sub(ur'\1...', prepared_page_name)
            else:
                link_title = prepared_page_name
            output.append(page.link_to(request, text=link_title, attachment_indicator=0))
            subpage_count = subpage_counts[page_name]

            if root_page_found and count and subpage_count > 0:
                _text = _('%d subpages') % subpage_count if subpage_count > 1 else _('one subpage')
                link = page.link_to(request, text=(' (%s)' % _text), querystr={'action': 'LocalSiteMap'}, css_class='site_index_show_subpages')
                output.append(link)

            output.append(fmt.listitem(0))

    output.append(fmt.bullet_list(0))
    return ''.join(output)
