"""
Mostly stolen from www.djangoproject.com, with a slight change that involves putting
<a>'s on headings back into the mix - TOC didn't want to work without them for me.
"""

from docutils import nodes, utils
from docutils.core import publish_parts
from docutils.writers import html4css1


def build_document(input_string, source_path=None, destination_path=None,
                    input_encoding='unicode', doctitle=1, initial_header_level=1):
    overrides = {'input_encoding': input_encoding,
                 'doctitle_xform': doctitle,
                 'initial_header_level': initial_header_level}
    writer = DjangoHTMLWriter()
    parts = publish_parts(
        input_string,
        writer=writer,
        settings_overrides=overrides,
        )
    return {'html_body' : parts['html_body'], 'toc' : parts['toc']}



class DjangoHTMLWriter(html4css1.Writer):
    def __init__(self):
        html4css1.Writer.__init__(self)
        self.translator_class = DjangoHTMLTranslator

    def translate(self):
        # build the document
        html4css1.Writer.translate(self)

        # build the contents
        contents = self.build_contents(self.document)
        contents_doc = self.document.copy()
        contents_doc.children = contents
        contents_visitor = self.translator_class(contents_doc)
        contents_doc.walkabout(contents_visitor)
        self.parts['toc'] = "<ul class='toc'>%s</ul>" % ''.join(contents_visitor.fragment)

    def build_contents(self, node, level=0):
        level += 1
        sections = []
        i = len(node) - 1
        while i >= 0 and isinstance(node[i], nodes.section):
            sections.append(node[i])
            i -= 1
        sections.reverse()
        entries = []
        autonum = 0
        depth = 4   # XXX FIXME
        for section in sections:
            title = section[0]
            entrytext = title
            try:
                reference = nodes.reference('', '', refid=section['ids'][0], *entrytext)
            except IndexError:
                continue
            ref_id = self.document.set_id(reference)
            entry = nodes.paragraph('', '', reference)
            item = nodes.list_item('', entry)
            if level < depth:
                subsects = self.build_contents(section, level)
                item += subsects
            entries.append(item)
        if entries:
            contents = nodes.bullet_list('', *entries)
            return contents
        else:
            return []

class DjangoHTMLTranslator(html4css1.HTMLTranslator):
    def visit_table(self, node):
        """Remove the damn border=1 from the standard HTML writer"""
        self.body.append(self.starttag(node, 'table', CLASS='docutils'))

    def visit_title(self, node, move_ids=1):
        """Only 6 section levels are supported by HTML."""
        check_id = 0
        close_tag = '</p>\n'
        if isinstance(node.parent, nodes.topic):
            self.body.append(
                  self.starttag(node, 'p', '', CLASS='topic-title first'))
            check_id = 1
        elif isinstance(node.parent, nodes.sidebar):
            self.body.append(
                  self.starttag(node, 'p', '', CLASS='sidebar-title'))
            check_id = 1
        elif isinstance(node.parent, nodes.Admonition):
            self.body.append(
                  self.starttag(node, 'p', '', CLASS='admonition-title'))
            check_id = 1
        elif isinstance(node.parent, nodes.table):
            self.body.append(
                  self.starttag(node, 'caption', ''))
            check_id = 1
            close_tag = '</caption>\n'
        elif isinstance(node.parent, nodes.document):
            self.body.append(self.starttag(node, 'h1', '', CLASS='title'))
            self.context.append('</h1>\n')
            self.in_document_title = len(self.body)
        else:
            assert isinstance(node.parent, nodes.section)
            h_level = self.section_level + self.initial_header_level - 1
            atts = {}
            if (len(node.parent) >= 2 and
                isinstance(node.parent[1], nodes.subtitle)):
                atts['CLASS'] = 'with-subtitle'
            self.body.append(
                  self.starttag(node, 'h%s' % h_level, '', **atts))
            atts = {}
            # !!! conditional to be removed in Docutils 0.5:
            if move_ids:
                if node.parent['ids']:
                    atts['ids'] = node.parent['ids']
            if node.hasattr('refid'):
                atts['class'] = 'toc-backref'
                atts['href'] = '#' + node['refid']
            if atts:
                self.body.append(self.starttag({}, 'a', '', **atts))
                self.context.append('</a></h%s>\n' % (h_level))
            else:
                self.context.append('</h%s>\n' % (h_level))
        # !!! conditional to be removed in Docutils 0.5:
        if check_id:
            if node.parent['ids']:
                atts={'ids': node.parent['ids']}
                self.body.append(
                    self.starttag({}, 'a', '', **atts))
                self.context.append('</a>' + close_tag)
            else:
                self.context.append(close_tag)

