##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################

import Globals
from Post import Post
from ForumPermissions import AddForumPosting, AddForum, ViewForum
from DateTime import DateTime
from Products.CMFCore.utils import getToolByName
from Products.CMFCore.PortalFolder import PortalFolder
from Products.CMFCore.PortalContent import PortalContent
from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
from Products.CMFDefault.SkinnedFolder import SkinnedFolder
from Products.CMFCore.CMFCorePermissions import View, ManageProperties, ListFolderContents, \
     ModifyPortalContent, AddPortalContent
from AccessControl import ClassSecurityInfo
from interfaces.Forum import IForum

factory_type_information = { 'id'             : 'Forum'
			     , 'portal_type'	: 'Forum'
                             , 'meta_type'      : 'Forum'
                             , 'description'    : """\
Forums hold threaded discussions."""
                             , 'icon'           : 'forum_icon.gif'
                             , 'product'        : 'CMFForum'
                             , 'factory'        : 'addForum'
                             , 'filter_content_types' : 1
                             , 'allowed_content_types' : ('Post', ) 
                             , 'immediate_view' : 'folder_edit_form'
                             , 'actions'        :
                                ( { 'id'            : 'view'
                                  , 'name'          : 'View'
                                  , 'action'        : 'forum_listing'
                                  , 'permissions'   : (View,)
                                  , 'category'      : 'folder'
                                  }
                                , { 'id'            : 'home'
                                  , 'name'          : 'Forum Home'
                                  , 'action'        : 'forum_listing'
                                  , 'permissions'   : (View,)
                                  , 'category'      : 'object'
                                  }
                                , { 'id'            : 'edit'
                                  , 'name'          : 'Edit'
                                  , 'action'        : 'folder_edit_form'
                                  , 'permissions'   : (ManageProperties,)
                                  , 'category'      : 'folder'
                                  }
                                , { 'id'            : 'localroles'
                                  , 'name'          : 'Local Roles'
                                  , 'action'        : 'folder_localrole_form'
                                  , 'permissions'   : (ManageProperties,)
                                  , 'category'      : 'folder'
                                  }
                                , { 'id'            : 'forum_post_message'
                                  , 'name'          : 'Post Message'
                                  , 'action'        : 'forum_post_message'
                                  , 'permissions'   : (AddForumPosting, )
                                  , 'category'      : 'folder'
                                  }
                                , { 'id'            : 'forum_search'
                                  , 'name'          : 'Search Forum'
                                  , 'action'        : 'forum_search_form'
                                  , 'permissions'   :(View, )
                                  , 'category'      : 'object'
                                  }
                                )
                             }
                           
# we sub CMFCatalogAware first to avoid PortalFolder's noping of the
# cataloging methods
class Forum(CMFCatalogAware, SkinnedFolder, PortalContent):

    meta_type = 'Forum'
    __implements__= (IForum, )

    manage_options = SkinnedFolder.manage_options
    
    security = ClassSecurityInfo()

    security.declareProtected(ModifyPortalContent, 'edit')
    def edit(self, title='', description=''):
        "Edit attributes, then reindex."
        Forum.inheritedAttribute('edit')(self, title, description)        
        self.reindexObject()

    security.declareProtected(ViewForum, 'posts')
    def posts(self, REQUEST=None):
	"""Return the top-level posts"""
	if REQUEST is None:
	    REQUEST=self.REQUEST
        
	posts = []
        for child in self.contentValues(['Post']):
            posts.append(child)
	return posts

    children = posts

    security.declareProtected(ViewForum, 'getForum')
    def getForum(self):
        """
        Return the Forum object.
        """
        return self

    security.declarePrivate('generate_id')
    def generate_id(self):
        """Find an available ID"""
        id = DateTime().millis()
        str_id = 'msg_%s'
        while hasattr(self, str_id % id):
            id = DateTime().millis()
        
        return str_id % id

    # XXX it is errorprone that addPost is a class method and module method and
    # duplicated in Forum and Post.  Should use the Forum module method IMHO.
    security.declareProtected(AddForumPosting, 'addPost')
    addPost = Post.addPost

    security.declareProtected(AddForum, 'addForum')
    def addForum(self, id, title='', REQUEST=None):
        """Add a Forum object"""

        forum = Forum(id, title)
        self._setObject(id, forum)
        forum = getattr(self, id)
        forum._setPortalTypeName('Forum')
        if REQUEST is not None:
            return self.manage_main(self, REQUEST)

addForum = Forum.addForum

Globals.InitializeClass(Forum)
