/// /// /// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ////// ///
//
//	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
//
//	MGOrderedDictionary.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.
//
/// /// /// ////// ////// ////// ////// ////// ////// //

NS_ASSUME_NONNULL_BEGIN

@interface MGOrderedDictionary<KeyType, ObjectType> : NSMutableDictionary<KeyType, ObjectType>

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

#pragma mark Init Methods.

- (instancetype)initWithCapacity:(NSUInteger)capacity;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

- (instancetype)initWithDictionary:(NSMutableDictionary *)dictionary withArray:(NSMutableArray *)array;

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

- (instancetype)initConvertFromDictionary:(__kindof NSDictionary*)dictionary;

#pragma mark -
#pragma mark Sorting Methods.

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

- (void)sortUsingSelector:(SEL)comparator;

- (void)sortUsingDescriptors:(NSArray *)sortDescriptors;

- (void)sortUsingComparator:(NSComparator)cmptr;

#pragma mark -
#pragma mark Insert Methods.
- (nullable id)objectForKeyedSubscript:(id)key;

- (void)setObject:(nullable ObjectType)object forKey:(KeyType)key;

- (void)setObject:(nullable ObjectType)object forKeyedSubscript:(id)key;

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

- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;

#pragma mark -
#pragma mark Remove Methods.

- (void)removeLastObject;

- (void)removeAllObjects;

- (void)removeObjectForKey:(KeyType)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.

- (nullable id)objectAtIndex:(NSUInteger)idx;

- (nullable id)objectAtIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8, 6_0);

- (NSUInteger)indexOfKey:(KeyType)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;

- (NSArray *)allDistinctValues;

/// Returns a reference to the internal order array.
///
/// The array may change when the ordered dictionary is modified.
/// Use this array only in performance-sensitive code and `allKeys` otherwise.
@property (nonatomic, readonly) NSArray *allKeysInternal;

@property (nonatomic, readonly) NSArray *allValuesUnordered;
@end

NS_ASSUME_NONNULL_END
