/*!
  @header ECCache
  @abstract Module of Encore
 
  @availability OS X, GNUstep
  @copyright 2004, 2005, 2006 Oliver Langer

  Author: Oliver Langer

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA

 <pre>
  -------------------------------------------------------------------------
  Modification history

  24.02.05 ola     initial version
  07.11.05 ola     changed API
  22.08.06 ola     license changed
  -------------------------------------------------------------------------
  </pre>
*/

#if !defined(__ECCache_H)
#define __ECCache_H

#include <Foundation/Foundation.h>
#include <Encore/ECExceptions.h>
#include <Encore/ECCacheItem.h>

/*!
 * @class ECCache
 * @abstract Class used for a simple caching.
 * @discussion At present the underlying mechanism is <b>very</b> simple: If
 *   the object has a reference counter value of greater/equal 1 then the
 *   object relies in the dictionary. If the counter equals 0 then the
 *   object will be removed. <p/>Please note that the "reference counter" 
 *   mentioned here refers to cache-internal counter and not to that of
 *   an object in general.
 */
@interface ECCache : ECObject <NSCoding> {
  @private 
    NSMutableDictionary *keyToCacheItem;
    NSLock *lock;
}


- init;
- (void) dealloc;


- (id) initWithCoder: (NSCoder *) decoder;
- (void) encodeWithCoder: (NSCoder *) encoder;


/*!
 * @method addObject
 * @abstract adds an object to the cache.
 * @discuss the object will be added and the reference count be set to 1.
 *   If an object with that key already exists then the exception
 *   {@link ECIllegalArgumentException} will be thrown.
 * @throws ECIllegalArgumentException if the key is already in use
 * @return self
 */
- addObject: (id) anObject forKey: (id <NSCopying>) aKey;


/*!
 * @method allKeys
 * @result iterator over all keys
 */
- (id <ECIterator>) allKeys;


/*!
 * @method objectExistsForKey
 * @abstract checks wether an object exists for the given key
 * @param aKey key of the object
 * @result YES if existent, NO otherwise
 */
- (BOOL) objectExistsForKey: (id) aKey;


/*!
 * @method objectForKey
 * @abstract get the cached object identified by the given key
 * @param doIncrement The internal reference count will be incremented by 1 if
 *   this parameter equals YES
 * @result related object or nil if not existent
 */
- objectForKey: (id) aKey incrementRefCounter: (BOOL) doIncrement;


/*!
 * @method referenceCountOfObjectForKey
 * @param aKey key of object to look for.
 * @result return the current reference count for the specified object. Return 0
 *   if the object does not exist
 */
- (unsigned int) referenceCounterOfObjectForKey: (id) aKey;


/*!
 * @method decrementRefCounterFor
 * @abstract Decrements the internal reference counter by one of the object
 *   identified by the given key.
 * @discuss Does nothing if the key refers to a non-existing object
 */
- (void) decrementRefCounterForKey: (id) aKey;


/*!
 * @method removeObjectForKey
 * @abstract removes the specified entry from the cache
 * @discussion Does nothing if the element could not be found.
 * @param aKey key of the entry to be removed
 */
- (void) removeObjectForKey: (id) aKey;
@end
#endif
