from yattag import Doc, indent
from sys import stderr

def _inner_recurse_tags(obj, tree, doc, tag, text):
    """Execute inner loop structure of HTML generation.

    Params:
        obj (Object): The object currently being looped over
        tree (Object): A VOTL Object containing the subtree-to-be
                       -generated
        doc: yattag Doc().doc
        tag: yattag Doc().tag
        text: yattag Doc().text
    """
    if obj.object_type == "header":
        # Only generate a header element for headers
        with tag("h{:d}".format(obj.level + 1)):
            text(obj.first_line)
    elif obj.object_type == "body":
        paragraphs = []
        current = []
        for line in obj.lines:
            if line == "":
                if len(current) > 0:
                    paragraphs.append("\n".join(current))
                    current = []
            else:
                current.append(line)

        # Last paragraph
        if len(current) > 0:
            paragraphs.append("\n".join(current))

        for paragraph in paragraphs:
            with tag("p"):
                text(paragraph)
    elif obj.object_type == "body-pre":
        # Just print the content in a pre-tag
        with tag("pre"):
            for line in obj.lines:
                text(line, "\n")
    elif obj.object_type[-4:] == "-pre":
        # Class is name without -pre
        klass = obj.object_type[:-4]
        # Custom preformatted
        with tag("pre", klass=klass):
            for line in obj.lines:
                text(line, "\n")
    else:
        # Body, but custom
        klass = obj.object_type
        paragraphs = []
        current = []
        for line in obj.lines:
            # Construct paragraphs into paragraphs from lines in obj
            if line == "":
                if len(current) > 0:
                    paragraphs.append("\n".join(current))
                    current = []
            else:
                current.append(line)

        if len(current) > 0:
            paragraphs.append("\n".join(current))

        for paragraph in paragraphs:
            # Each generated paragraph becomes a <p> tag
            with tag("p", klass=klass):
                text(paragraph)

    _recurse_tags(obj, doc, tag, text)


def _recurse_tags(tree, doc, tag, text):
    """Recursively generate HTML from children.

    Params:
        tree (Object): A VOTL Object containing the subtree-to-be
                       -generated
        doc: yattag Doc().doc
        tag: yattag Doc().tag
        text: yattag Doc().text
    """
    if len(tree.children) > 0:
        for o in tree.children:
            if len(o.children) > 0:
                # Only create divs for objects with children
                with tag("div"):
                    _inner_recurse_tags(o, tree, doc, tag, text)
            else:
                _inner_recurse_tags(o, tree, doc, tag, text)


def html_from_tree(tree):
    """Generate indented HTML from VOTL Object tree.

    Params:
        tree (Object): A VOTL Object containing the tree, from which HTML will
                       be generated.

    Returns: String containing a pretty-formatted HTML document.
    """
    doc, tag, text = Doc().tagtext()

    doc.asis("<!DOCTYPE html>")

    try:
        first = tree.children[0]
    except IndexError:
        print("Error generating markdown: Tree has no children!", file=stderr)
        return ""
    if first.object_type == "header":
        title = first.first_line
    else:
        title = "Untitled"

    with tag("html"):
        with tag("head"):
            with tag("title"):
                text(title)
            doc.stag("meta", charset="utf-8")
        with tag("body"):
            _recurse_tags(tree, doc, tag, text)

    return indent(doc.getvalue())
