/*
**  (C) Copyright 1989, 1990
**  Micro Data Base Systems Inc.
**  Lafayette, Indiana
*/
/* Construct a new instance of a kind of Collection. */
method CollectionClass::new(self, aSize)
{
        return indexedNew(self, aSize);
}

/* Add the initialization message on to the basic indexedNew message. */
method CollectionClass::indexedNew(self, aSize)
{
        return init(basicIndexedNew(self, aSize));
}

/* Basic initialization message for collection classes. */
method Collection::init(self)
{
        return self;
}

/* Answer the size of the collection in elements. */
method Collection::sizeOf(self)
{
	return basicSizeOf(self);
}

/* Add all the members of one collection to another. */
method Collection::addAll(self, aCollection)
{
        do(aCollection, ::(anElement){
                 add(self, anElement);
        });
        return aCollection;
}

/* Remove all the members of one collection from another. */
method Collection::removeAll(self, aCollection)
{
        reverseDo(aCollection, ::(anElement){
                remove(self, anElement);
        });
        return aCollection;
}

/* Determine if the collection is empty or not. */
method Collection::isEmpty(self)
{
        do(self, ::( aMember ){
                return false;
        });
        return true;
}

/* Determine if the collection contains the argument as a member. */
method Collection::includes(self, anObject)
{
        do(self, ::(aMember){
                if (anObject == aMember) {
                        return true;
                }
        });
        return false;
}

/* Count the occurences of an object in the collection. */
method Collection::occurrencesOf(self, anObject)
{
        local  tally ;

        tally = 0;
        do(self, ::(aMember){
                if (anObject == aMember) {
                        tally = tally + 1;
                }
        });
        return tally;
}

/* Collect the members of one collection into another. */
method Collection::collect(self, aBlock)
{
        local  newCollection ;

        newCollection = new(speciesOf(self), sizeOf(self));
        do(self, ::(aMember){
		add(newCollection, valueOf(aBlock, aMember));
        });
        return newCollection;
}

/* Select a subset of a collection to add to another. */
method Collection::select(self, aBlock)
{
        local  newCollection ;

        newCollection = new(speciesOf(self), sizeOf(self));
        do(self, ::(aMember){
		if (valueOf(aBlock, aMember)) {
                        add(newCollection, aMember);
                }
        });
        return newCollection;
}

/* Reject unwanted members from a collection. */
method Collection::reject(self, aBlock)
{
        return select(self, ::(aMember){
		!valueOf(aBlock, aMember);
        });
}

/* Answer the index of the member in the collection. */
method Collection::find(self, anItem)
{
        local  index ;

        index = 0;
        do(self, ::( aMember ){
                if (aMember == anItem) {
                        return index;
                }
                index = index + 1;
        });
        return nil;
}

/* Convert the collection into a Set of the elements. */
method Collection::asSet(self)
{
        local  aSet ;

	aSet = new(Set, sizeOf(self) + 1);
        addAll(aSet, self);
        return aSet;
}

/* Convert the collection into an OrderedCollection of the elements. */
method Collection::asOrderedCollection(self)
{
        local  aCollection ;

        aCollection = new(OrderedCollection, sizeOf(self));
        addAll(aCollection, self);
        return aCollection;
}

/* Convert the collection into a SortedCollection of the elements. */
method Collection::asSortedCollection(self)
{
        local  aCollection ;

	aCollection = new(SortedCollection, sizeOf(self));
        addAll(aCollection, self);
        return aCollection;
}

/* Convert the collection into a Array of the elements. */
method Collection::asArray(self)
{
        local  array, i ;

	array = new(Array, sizeOf(self));
        i     = 0;
        do(self, ::(member){
                array[i] = member;
                i        = i + 1;
        });
        return array;
}

/* Convert the collection into a compact string form. */
method Collection::asString(self)
{
        local  aString, tooMany, i ;

        aString = classNameOf(classOf(self)) + "(";
        tooMany = maxPrint(self);
        if(isNil(tooMany))
                return EmptyString;

        i       = 0;
        do(self, ::(aMember){
                if ((i = i + 1) > tooMany) {
                        return aString + " ...etc...)";
                }
                aString = aString + " " + asString(aMember);
        });
        return aString + ")";
}

/* Return the number of members to include in 'asString' */
method Collection::maxPrint(self)
{
        return 16;
}
        
/* Create a Stream over a Collection. */
method Collection::streamOver(self)
{
        return init(new(Stream), self, 0);
}


/* add two collections together to produce a third. */
method Collection::+(self, aCollection)
{
    local newCollection;

    newCollection = new(speciesOf(self),sizeOf(self)+sizeOf(aCollection));
    addAll(newCollection,self);
    addAll(newCollection,aCollection);
    return newCollection;
}
 


/* subtract the second collection from the first to produce a third. */
method Collection::-(self, aCollection)
{
    local newCollection;

    newCollection = new(speciesOf(self),sizeOf(self));
    addAll(newCollection,self);
    removeAll(newCollection,aCollection);
    return newCollection;
}


/* Return the class of the receiver. */
method Collection::speciesOf(self)
{
        return classOf(self);
}
