"""$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/item.py $
$Id: item.py 23460 2004-02-12 22:08:13Z rmasse $
"""
import heapq

from mx import DateTime
from dulcinea.base import DulcineaPersistent, PersistentMapping
from dulcinea.sort import attr_sort
from dulcinea.typeutils import typecheck


class Item(DulcineaPersistent):
    """An Item object implements a mixin API for a unique stored item
    retrievable by creation time.

    Instance attributes:
      title: string
        The title of this item
      timestamp : DateTime
        So Items can be sorted by time.
      key : string
        Some sort of unique ID
    """
    def __init__(self, timestamp=None):
        assert self.__class__ is not Item, "abstract class"
        if timestamp is None:
            self.timestamp = DateTime.now()
        else:
            self.set_timestamp(timestamp)
        self.key = self.title = None

    def __cmp__(self, other):
        return cmp(self.timestamp, other.timestamp)

    def set_key(self, key):
        self.key = key

    def get_key(self):
        return self.key

    def set_timestamp(self, timestamp):
        typecheck(timestamp, DateTime.DateTimeType)
        self.timestamp = timestamp

    def get_timestamp(self):
        return self.timestamp

    def set_title(self, title):
        self.title = title

    def get_title(self):
        return self.title

    def get_subhead(self):
        return None

    def get_user(self):
        return None

    def format_time(self):
        return self.timestamp.strftime('%Y-%m-%d')

class ItemFolder(DulcineaPersistent):
    """Stores a collection of Items and defines an API for storage
    and creation-time-based retrieval.

    Instance attributes:
      items : PersistentMapping { string : Item }
    """

    def __init__(self):
        self.items = PersistentMapping()

    def clear (self):
        self.items.clear()

    def add_item (self, item):
        """(item : Item)
        """
        i = 0
        while 1:
            key =  '%s-%s' % (int(item.timestamp), i)
            if not self.items.has_key(key):
                break
            i += 1
        item.set_key(key)
        self.items[key] = item

    def delete_item (self, item):
        """(item : Item)
        """
        if item.get_key() is None:
            raise KeyError, "Item %r not in any database" % item
        if not self.items.has_key( item.key ):
            raise KeyError, "Item %r not in this database" % item
        del self.items[item.get_key()]

    def get_item (self, key):
        """(key : str) -> Item
        """
        return self.items[key]

    def get_items (self):
        """() -> [Item]
        """
        return self.items.values()

    def get_recent_items(self, N, require_approval=True):
        """(N : int, require_approval : bool = True) -> [Item]

        Return the N most recent items.  If 'require_approval' is true,
        only approved items are returned.
        """
        # XXX items should really be stored in sorted order since access is
        # probably much more frequent than updates
        if N is None:
            result = []
            for item in self.items.values():
                if require_approval and not item.approved:
                    continue
                result.append(item)
            result = attr_sort(result, 'timestamp')
            result.reverse()
        else:
            # Find the N most recent items.
            result = []
            for item in self.items.values():
                if require_approval and not item.approved:
                    continue
                if len(result) < N:
                    heapq.heappush(result, item)
                else:
                    if item > result[0]:
                        heapq.heapreplace(result, item)
            result.sort()
            result.reverse()
        return result
