# Copyright (c) 2002-2008 Infrae. All rights reserved.
# See also LICENSE.txt
# Zope 3
from zope.interface import implements
# Five
from Products.Five import BrowserView
# SilvaLayout
from Products.SilvaLayout import interfaces

class NotPublic:
    
    implements(interfaces.ITreeNodeFilter)
    
    def __init__(self, context):
        self.context = context
        
    def __call__(self):
        return not bool(self.context.is_published())

class NotVisible:
    
    implements(interfaces.ITreeNodeFilter)
    
    def __init__(self, context):
        self.context = context
        self.metadata = interfaces.IMetadata(self.context.aq_inner)
        
    def __call__(self):
        context = self.context.aq_inner
        visible = self.metadata('silva-extra', 'hide_from_tocs')
        return visible == 'hide'
    
class TreeView(BrowserView):

    def __call__(self):
        return self.renderHTML()

    def getRootNode(self, node):
        rootnode = node.getPublicationNode()
        return rootnode
    
    def renderHTML(self, maxdepth=3):
        node = interfaces.ITreeNode(self.context.aq_inner)
        rootnode = self.getRootNode(node)

        snippet = ['']
        add = snippet.append

        filters = self.getFilters()

        # XXX: rendering doesn't close nested ul/li's properly, fails validators
        add("""<ul class="treeroot">""")
        if rootnode.hasChildNodes():
            for node in rootnode.childNodes(filters):
                snippet.extend(self.renderTreeNode(node, 0, maxdepth))
        add("""</ul>""")
        add('')
        return '\n'.join(snippet)
    
    def renderTreeNode(self, node, depth, maxdepth):
        styles = ['treeitem', ]
        
        onbranch = node.onBranch(self)
        if onbranch:
            styles.append('current')
        
        haschildren = node.hasChildNodes()
        if haschildren:
            styles.append('container')
        else:
            styles.append('content')
            
        styles.append('level%i' % (depth+1))
            
        anchor_style = ''
        if self.context == node.getObject():
            # the actual selected node get's a selected
            # class on the anchor
            anchor_style = ' class="selected"'
        snippet = []
        add = snippet.append

        # XXX: the '-' delimiter is an awful hack, but IE5 doesn't support
        # multiple css classes 
        add("""<li class="%s">""" % '-'.join(styles))
        add("""<a href="%s"%s>%s</a>""" % (
            node.context.absolute_url(), 
            anchor_style, 
            node.context.get_short_title()))
            
        if haschildren and self.continueRecursion(node, depth, maxdepth):
            if onbranch:
                add("""<ul class="current">""")
            else:
                add("""<ul>""")
            filters = self.getFilters()
            children = node.childNodes(filters)
            for childnode in children:
                snippet.extend(
                    self.renderTreeNode(childnode, depth+1, maxdepth))
            add("""</ul>""")
        add("""</li>""")
        
        return snippet

    def continueRecursion(self, node, depth, maxdepth):
        if depth >= maxdepth:
            return False
        return True

    def getFilters(self):
        return (NotPublic, NotVisible)
