########################################################################
#
# File Name: 	       Collection.py
#
# Documentation:	http://docs.ftsuite.com/4ODS/Collection.py.html
#
"""
Implements the Collection meta-data interface.
WWW: http://4suite.org/4ODS         e-mail: support@4suite.org

Copyright (c) 1999 Fourthought, Inc., USA.   All Rights Reserved.
See  http://4suite.org/COPYRIGHT  for license and copyright information
"""

from Ft.Ods.MetaData import Type
import string

from Ft.Ods.MetaData import MetaKind
from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods.MetaData import CollectionKind
from Ft.Ods.PersistentObject import TupleDefinitions
td = TupleDefinitions

from Ft.Ods.Exception import FtodsUnknownError, FtodsUnsupportedError

class Collection(Type.Type):

    def __init__(self,db,
                 data,
                 collection_kind=None):
        Type.Type.__init__(self,db,data,meta_kind=MetaKind.mk_collection)

        if data is None:
            if collection_kind is None:
                raise FtodsUnknownError(msg="No Collection Kind")
            self.__dict__['collection_kind'] = collection_kind

    def form_subtype(self,target,inverse = 1):
        self._4ods_formRelationship('subtype',Type.Type,'collections','add',target,inverse)

    def drop_subtype(self, target, inverse=1):
        self._4ods_dropRelationship('subtype','collections','remove',target,inverse)

    def form_max_size(self,target,inverse = 1):
        from Ft.Ods.MetaData import Operand
        self._4ods_formRelationship('max_size',Operand.Operand,'size_of','form',target,inverse)

    def drop_max_size(self, target, inverse=1):
        self._4ods_dropRelationship('max_size','size_of','drop',target,inverse)

    def is_ordered(self):
        return self.collection_kind == CollectionKind.ck_list

    def bound(self):
        if self.max_size:
            return self.max_size.value()
        return -1

    def _4ods_getOdl(self,indent):
        ckind = self.collection_kind
        if ckind == CollectionKind.ck_string:
            return indent + 'string<%s>' % self.max_size.value()

        if ckind == CollectionKind.ck_list:
            base = "list"
        elif ckind == CollectionKind.ck_set:
            base = "set"
        elif ckind == CollectionKind.ck_bag:
            base = "bag"
        else:
            raise FtodsUnsupportedError(feature = "Collections of Kind %s" % str(ckind))
        
        return indent + '%s <%s>' % (base,self.subtype.absolute_name())

    def _4ods_getOdmgType(self):
        if self.collection_kind == CollectionKind.ck_list:
            return Constants.Types.LIST_COLLECTION
        if self.collection_kind == CollectionKind.ck_set:
            return Constants.Types.SET_COLLECTION
        if self.collection_kind == CollectionKind.ck_bag:
            return Constants.Types.BAG_COLLECTION
        if self.collection_kind == CollectionKind.ck_string:
            return Constants.Types.FIXEDSTRING


    def _4ods_getGeneratedMetaClasses(self,found,checked):
        if self in checked: return
        checked.append(self)
        if self.collection_kind == CollectionKind.ck_string:
            found.append(self)
        if self.subtype:
            self.subtype._4ods_getGeneratedMetaClasses(found,checked)


    def _4ods_findTypePath(self,object):
        #Never the path to a type
        return []

    _tupleNames =  (('collection_kind',),('max_size',),('subtype',))


    _tupleDefinitions = {'collection_kind': {td.TYPE:Constants.Types.ENUMERATION,
                                             td.READONLY:1,
                                             td.LITERAL_REPO_ID:CollectionKind.CollectionKind._typeId,
                                             },
                         'max_size': {td.TYPE:Constants.Types.ROBJECT,
                                      td.RELATIONSHIP:1,
                                      td.READONLY:1,
                                      },
                         'subtype': {td.TYPE:Constants.Types.ROBJECT,
                                     td.RELATIONSHIP:1,
                                     td.READONLY:1,
                                     },
                         
                         }
    localExtents = ()

