/// /// /// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ///
//
//	SEQOY™ Development and Consulting
//	http://www.seqoy.com
//
///////////////
//
//	History:
//
//	19/12/08 --- Created by Matt Gallagher (http://cocoawithlove.com/)
//	20/09/09 --- Several changes by Paulo Oliveira
//
//	OTOrderedDictionary.h
//
/// /// /// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ///
//
//  Permission is given to use this source code file without charge in any
//  project, commercial or otherwise, entirely at your risk, with the condition
//  that any redistribution (in part or whole) of source code must retain
//  this copyright and permission notice. Attribution in compiled projects is
//  appreciated but not required.
//
/// /// /// ////// ////// ////// ////// ////// ////// //
#import <Foundation/Foundation.h>

@interface OTOrderedDictionary<__covariant KeyType : NSObject <NSCopying> *, __covariant ObjectType : NSObject *> : NSDictionary

//// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// ////
#pragma mark -

#pragma mark Init Methods.
- (id)initWithCapacity:(NSUInteger)capacity;

- (id)initWithDictionary:(NSDictionary *)object;

- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;

- (id)initWithObject:(NSMutableDictionary *)object withArray:(NSMutableArray *)array;

/// This method is similar to initWithDictionary, the difference is: This method will Scan the all Dictionary tree converting internal elements too.

- (id)initConvertFromDictionary:(id)object;

- (instancetype)initWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;

+ (instancetype)dictionaryWithKeysAndObjects:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;
#pragma mark -
#pragma mark Sorting Methods.

/// Reorder the Dictionary using one giving function.
- (void)sortUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;

- (void)sortUsingSelector:(SEL)comparator;

- (void)sortUsingComparator:(NSComparator NS_NOESCAPE)cmptr;

#pragma mark -
#pragma mark Insert Methods.
- (id)objectForKey:(id)key;
- (NSArray *)allKeys;
//- (NSArray *)allValues;

- (void)setObject:(id)object forKey:(id)key;

/**
 Sets a given object for a given key. If the receiver does not yet contain an object for the key, the key is inserted at the given index and the object is associated with the key. If a key-object pair already exists, the old object is replaced by the new object but the index is ignored.
 TODO: It would be more logical to honor the index even if a key already exists.
 */
- (void)setObject:(id)object forKey:(id)key atIndex:(NSUInteger)idx;

- (void)insertObject:(id)object forKey:(id)key atIndex:(NSUInteger)idx;

- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
#pragma mark -
#pragma mark Remove Methods.

- (void)removeLastObject;

- (void)removeObjectForKey:(id)key;

- (void)removeObjectAtIndex:(NSUInteger)idx;

- (BOOL)removeObjectFromIndex:(NSUInteger)from To:(NSUInteger)to; // This method could be slow on large dictionaries.

- (void)removeObjectsInRange:(NSRange)aRange; // This method could be slow on large dictionaries.

- (void)removeObjectsForKeys:(NSArray *)keyArray;
//// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// ////
#pragma mark -
//// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// ////
#pragma mark Retrieve Methods.

- (id)objectAtIndex:(NSUInteger)idx;

- (NSUInteger)indexOfKey:(id)key;

- (id)keyAtIndex:(NSUInteger)idx;

#pragma mark Manipulate Methods.

- (void)swipeIndex:(NSUInteger)from with:(NSUInteger)to;

- (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2; // This is the same of swipeIndex, this method is just for compatibility.

- (void)moveFromIndex:(NSUInteger)from To:(NSUInteger)to;

- (NSEnumerator *)reverseKeyEnumerator;

- (id)objectForKeyedSubscript:(id)key;

- (void)setObject:(id)object forKeyedSubscript:(id)key;
- (id)firstValue;
- (id)firstKey;

#ifdef DEBUG
- (NSDictionary *)dictionary;
#endif
@end
