# Copyright (c) 2002-2007 Infrae. All rights reserved.
# See also LICENSE.txt
# Zope
from AccessControl import getSecurityManager
from zope.component import getView
# Five
from Products.Five import BrowserView
from Products.Five import StandardMacros as BaseMacros
# SilvaLayout
from Products.SilvaLayout import interfaces
from Products.SilvaLayout.browser.tree import NotPublic

class SilvaView(BrowserView):

    def __init__(self, *args):
        BrowserView.__init__(self, *args)
        self.metadata = interfaces.IMetadata(self.context.aq_inner)

    def getRootMetadata(self, set, element):
        root = self.context.aq_inner.get_root().aq_inner
        return root.service_metadata.getMetadataValue(root, set, element)
        
    def title(self):
        """title for object
        """
        context = self.context.aq_inner
        return context.get_title()
    
    def render_public_preview(self):
        context = self.context.aq_inner
        return context.get_previewable().preview()
        
    def render(self):
        """default public rendering
        """
        context = self.context.aq_inner
        return context.view()
    
    def modificationtime(self):
        context = self.context.aq_inner
        metadata = interfaces.IMetadata(context)
        return metadata('silva-extra', 'modificationtime')

class Content(SilvaView):

    def context_or_default(self):
        return self.context.aq_inner
    
    def PUT(self, REQUEST, RESPONSE=None):
        """Proxy HTTP PUT requests. 
        """
        # A bit hackish, but it works.
        context = self.context_or_default()
        func = context.PUT
        getSecurityManager().validate(None, context, 'PUT', func)
        if RESPONSE is None:
            return func(REQUEST)
        return func(REQUEST, RESPONSE)

class Container(SilvaView):

    def context_or_default(self):
        context = self.context.aq_inner
        default = context.get_default()
        return default
    
    def render(self):
        """public rendering for folders
        """
        default = self.context_or_default()
        if default is None:
            return ''
        # Delegate actual rendering to the view for this object
        view_for_default = getView(
            default, 'index.html', self.request).__of__(default)
        return view_for_default.render()
            
    def render_public_preview(self):
        default = self.context_or_default()
        if default is None:
            return ''
        # Delegate actual rendering to the view for this object
        view_for_default = getView(
            default, 'preview_html', self.request).__of__(default)
        return view_for_default.render_public_preview()

    def modificationtime(self):
        default = self.context_or_default()
        if default:
            metadata = interfaces.IMetadata(default)
        else:
            metadata = interfaces.IMetadata(context)
        return metadata('silva-extra', 'modificationtime')
    
class AutoTOCView(SilvaView):
    """AutoTOCView with filtering 
    """
    def __init__(self, *args, **kwargs):
        SilvaView.__init__(self, *args)
        self.filters = kwargs.get('filters', [])

    def context_or_default(self):
        return self.context.aq_inner

    def getTocNodes(self, depth=-1):
        # XXX This implementation should've reused the ITreeNode adapters;
        # filtering is handled much better there. However, the output HTML
        # for this view should be identical to Silva's core rendering
        # for AutoTOC objects and thus we mimic that rendering here.
        items = []
        context = self.context_or_default()
        container = context.get_container()
        depth_flag = None
        for indent, obj in container.get_public_tree_all():
            # Skip all items 'deeper' than the one that needed filtering
            if depth_flag is not None:
                if indent > depth_flag:
                    continue
                else:
                    depth_flag = None
            # XXX code copied from adapters.treenode. Should be refactored.
            if self._filter(obj, self.filters):
                # Continue with next object, since the current one is
                # filtered out.
                depth_flag = indent
                continue
            items.append((indent, obj.absolute_url(), obj.get_title(),))
        return items
            
    def _filter(self, object, filters):
        # XXX code copied from adapters.treenode. Should be refactored.
        for klass in filters:
            filter = klass(object) # implements ITreeNodeFilter
            if filter():
                return True
        return False
    
    def render(self):
        """public rendering for autoTOC
        """
        request = self.request
        context = self.context_or_default()
        autotocview = getView(context, 'autotoc', request).__of__(context)
        return autotocview()
