from AccessControl import ClassSecurityInfo
from OFS.SimpleItem import SimpleItem
from Globals import InitializeClass
from Products.ZCatalog.CatalogPathAwareness import CatalogPathAware

from Products.Silva.IVersion import IVersion
from Products.Silva import SilvaPermissions


class Version(SimpleItem):

    __implements__ = IVersion

    security = ClassSecurityInfo()

    object_type = 'versioned_content'
    _title = '[No title yet]'
    
    def __init__(self, id, title):
        self.id = id
        self._title = title
        
    security.declareProtected(
        SilvaPermissions.ChangeSilvaContent, 'set_title')
    def set_title(self, title):
        """Set title of version.
        """
        # FIXME: Ugh. I get unicode from formulator but this will not validate
        # when using the metadata system. So first make it into utf-8 again..
        # XXX Could set it directly with _setData instead?
        title = title.encode('utf-8')
        binding = self.service_metadata.getMetadata(self)
        binding.setValues(
            'silva-content', {'maintitle': title})

    security.declareProtected(
        SilvaPermissions.AccessContentsInformation, 'get_title')
    def get_title(self):
        """get title of version.
        """
        binding = self.service_metadata.getMetadata(self)
        return binding.get(
            'silva-content', element_id='maintitle')

    security.declareProtected(
        SilvaPermissions.AccessContentsInformation, 'get_short_title')
    def get_short_title(self):
        """Get the title of the version.
        """
        binding = self.service_metadata.getMetadata(self)
        short_title = binding.get(
            'silva-content', element_id='shorttitle')
        if not short_title:
            return self.get_title()
        return short_title
        
    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'version_status')
    def version_status(self):
        """Returns the status of the current version
        Can be 'unapproved', 'approved', 'public', 'last_closed' or 'closed'
        """
        status = None
        unapproved_version = self.get_unapproved_version(0)
        approved_version = self.get_approved_version(0)
        public_version = self.get_public_version(0)
        previous_versions = self.get_previous_versions()
        if unapproved_version and unapproved_version == self.id:
            status = "unapproved"
        elif approved_version and approved_version == self.id:
            status = "approved"
        elif public_version and public_version == self.id:
            status = "public"
        else:
            if previous_versions and previous_versions[-1] == self.id:
                status = "last_closed"
            elif self.id in previous_versions:
                status = "closed"
            else:
                # this is a completely new version not even registered
                # with the machinery yet
                status = 'unapproved' 
        return status

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'object_path')
    def object_path(self):
        """Returns the physical path of the object
        (for identification-purposes)
        """
        return self.aq_inner.aq_parent.getPhysicalPath()

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'version')
    def version(self):
        """Returns the version
        """
        return (self.id,
                self.publication_datetime(),
                self.expiration_datetime())

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'object')
    def object(self):
        """Returns the object this version belongs to
        """
        return self.aq_inner.aq_parent


    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'object')
    def get_version(self):
        """Returns itself. Used by acquisition to get the
           neared version.
        """
        return self.aq_inner


    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'publication_datetime')
    def publication_datetime(self):
        """Returns the publication_datetime of this version (if any)
        """
        status = self.version_status()
        if status == 'closed' or status == 'last_closed':
            return None
        else:
            return getattr(self,
                           'get_%s_version_publication_datetime' % status)(0)

    security.declareProtected(SilvaPermissions.AccessContentsInformation,
                              'expiration_datetime')
    def expiration_datetime(self):
        """Returns the expiration_datetime of this version (if any)
        """
        status = self.version_status()
        if status == 'closed' or status == 'last_closed':
            return None
        else:
            return getattr(self,
                           'get_%s_version_expiration_datetime' % status)(0)

InitializeClass(Version)

class CatalogedVersion(Version):
    """Base class for cataloged version objects"""

    def getPath(self):
        return '/'.join(self.getPhysicalPath())
    
    def index_object(self):
        """Index"""
        catalog = getattr(self, 'service_catalog', None)
        if catalog is not None:
            catalog.catalog_object(self, self.getPath())

    def unindex_object(self):
        """Unindex"""
        catalog = getattr(self, 'service_catalog', None)
        if catalog is not None:
            catalog.uncatalog_object(self.getPath())

    def reindex_object(self):
        """Reindex."""
        catalog = getattr(self, 'service_catalog', None)
        if catalog is None:
            return 
        path = self.getPath()
        catalog.uncatalog_object(path)
        catalog.catalog_object(self, path)
        
    
InitializeClass(CatalogedVersion)

