############################################################################
#
# File Name: 		Extent.py
#
# Documentation:	http://docs.ftsuite.com/4ODS/StorageManager/ExtentManager.py/html
#

#Manages Extents
#WWW: http://4suite.org/4ODS         e-mail: support@4suite.org
#
#Copyright (c) 2000-2001 Fourthought Inc, USA.   All Rights Reserved.
#See  http://4suite.org/COPYRIGHT  for license and copyright information


#NOTE Do not inherit from CollectionBase becuase this is a readonly collection (can be rewritten much simplier)

from Ft.Ods.StorageManager.Adapters import Constants
from Ft.Ods import Exception

class Extent:
    def __init__(self,name,manager,subType,data=None):
        self._name = name
        if data is None:
            self._new = 1
            self.data = []
        else:
            self.data = list(data)
            self._new = 0

        self.manager = manager
        self._addedObjects = []
        self._deletedObjectIds = []
        self._subType = subType
    
        self._delete = 0

    def cardinality(self):
        return len(self.data)

    def is_empty(self):
        return self.cardinality() == 0

    def is_ordered(self):
        return 0

    def allows_duplicates(self):
        return 0

    def contains_element(self, e):
        return e in self.data

    def create_iterator(self, stable):
        return Iterator.Iterator(self, stable)

    def create_bidirectional_iterator(self, stable):
        return BidirectionalIterator.BidirectionalIterator(self, stable)

    def select_element(self,OQL_predicate):
        raise Exception.FtodsNotSupportedError(feature="select_element")

    def select(self,OQL_predicate):
        raise Exception.FtodsNotSupportedError(feature="select")

    def query(self,OQL_predicate):
        raise Exception.FtodsNotSupportedError(feature="select_element")

    def exists_element(self,OQL_predicate):
        raise Exception.FtodsNotSupportedError(feature="select_element")


    #The pythonic interface
    def __len__(self): return self.cardinality()
    def __getitem__(self, i):
        if i >= self.cardinality():
            raise IndexError(i)
        if i < 0:
            i = self.cardinality() + i
        oid = self.data[i]
        if self._subType == Constants.Types.ROBJECT:
            obj = self.manager._4ods_getRepositoryObject(oid)
        else:
            obj = self.manager._4ods_getObject(oid)
        return obj


    def __getslice__(self, i, j):
        i = max(i, 0); j = min(j, self.cardinality())
        res = []
        for ctr in range(i,j):
            res.append(self[ctr])
        return res

    def _4ods_delete(self):
        self._delete = 1

    def _4ods_addObject(self,object):
        self._addedObjects.append(object)
        self.data.append(object._4ods_getId())

    def _4ods_removeObject(self,object):
        oid = object._4ods_getId()
        self._deletedObjectIds.append(oid)
        while object in self._addedObjects:
            self._addedObjects.remove(object)

        while oid in self.data:
            self.data.remove(oid)
            

    def _4ods_updateChanges(self,adapter,db):
        if self._delete:
            adapter.dropExtent(db,self._name)
        else:
            if self._new:
                adapter.addExtent(db,self._name,self._subType)

            for obj in self._addedObjects:
                adapter.addExtentEntry(db,[self._name],obj._4ods_getId())

            for objId in self._deletedObjectIds:
                adapter.dropExtentEntry(db,[self._name],objId)

