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

class Node:
    
    implements(interfaces.ITreeNode)
    
    def __init__(self, context):
        self.context = context
    
    # XXX a better name could be 'isAncestorFor'
    def onBranch(self, node):
        browsingcontext = node.context.aq_inner
        context = self.context.aq_inner 
        if browsingcontext == context:
            return True
        return context in browsingcontext.aq_chain
        
    def getContainerNode(self):
        context = self.context.aq_inner
        container = context.aq_parent
        node = interfaces.ITreeNode(container)
        return node

    def getPublicationNode(self):
        context = self.context.aq_inner
        pub = context.get_publication()
        node = interfaces.ITreeNode(pub)
        return node

    def getVirtualHostRootNode(self):
        context = self.context.aq_inner
        request = context.REQUEST
        service_metadata = context.service_metadata
        vhroot = context.get_publication()
        # XXX this appears to be needed for the WuWLayout extension
        # but should probably be moved to that extensions completely.
        while 1:
            if IRoot.providedBy(vhroot):
                # if vhroot is not found, search the request for a var set by 
                # the vhost monster
                # XXX should this be removed entirely for WuW's usecase?
                virtualrootpath = request.get('VirtualRootPhysicalPath', None)
                if virtualrootpath is not None:
                    vhroot = context.restrictedTraverse(virtualrootpath)
                break
            is_vhost = service_metadata.getMetadataValue(vhroot, 
                                            'silva-layout-vhost-root',
                                            'vhostroot')
            if is_vhost:
                break
            vhroot = vhroot.aq_parent.get_publication()
        return interfaces.ITreeNode(vhroot)
    
    def getObject(self):
        return self.context.aq_inner
        
    def hasChildNodes(self):
        return False
    
    def childNodes(self, filters=()):
        return []
        
class ContainerNode(Node):
    
    def hasChildNodes(self):
        return bool(self.context._ordered_ids)
    
    def childNodes(self, filters=()):
        for obj in self.context.get_ordered_publishables():
            if self._filter(obj, filters):
                # Continue with next object, since the current one is
                # filtered out.
                continue
            yield interfaces.ITreeNode(obj)
            
    def _filter(self, object, filters):
        for klass in filters:
            filter = klass(object) # implements ITreeNodeFilter
            if filter():
                return True
        return False
            
class RootNode(ContainerNode):
    
    def getContainerNode(self):
        return self

    def getPublicationNode(self):
        return self    
        
