//
//  NSArray+MCAdditions.h
//  MCFoundation
//
//  Created by aj on Tue Jan 01 2002.
//  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "MCFoundationDefines.h"

@interface NSArray (MCAdditions)


+ (NSArray*)arrayWithObject: (id)obj duplicates: (unsigned)dupes;


/*
	Sends an *unsafe* isEqualToString to each object in the array, return YES on the first find. Otherwise return NO;

*/
- (BOOL)containsString:(NSString *)str;


// returns YES if all objects are of the same class (uses the first object)
- (BOOL)objectsAreKindOfSameClass;
- (BOOL)objectsAreKindOfClassNames:(NSArray *)classNames; // all objects are kind of one of the class names
- (BOOL)objectsAreMembersOfClass:(Class)aClass;
- (BOOL)objectsAreKindOfClass:(Class)aClass;
- (BOOL)someObjectsAreKindOfClass:(Class)aClass;
- (BOOL)valuesForAttributeAreOfSameValue:(NSString *)anAttribute errorDescription:(NSString **)error;
- (id)mcfirstObjectKindOfClass:(Class)aClass;

// Selector must be one that returns an object that responds to boolValue, unless you want nil to be NO and everything else to be YES (i.e. you could use this to check if any of the objects have an object related, like if the array were of contacts, you could use this to see if all contacts had a default phone object set.
- (BOOL)cumulativeCompareUsingSelector: (SEL)aCompareSelector andBooleanOperator: (MCBooleanOperator)anOperator;

// check to see if the object responds before sending it the message (for each in the array)
- (void)tryToMakeObjectsPerformSelector:(SEL)aSelector;
- (void)tryToMakeObjectsPerformSelector:(SEL)aSelector withObject:(id)anObject;

- (void)makeObjectsPerformSelector: (SEL)aSelector withObject: (id)obj afterDelay: (NSTimeInterval)delay;

// invokes attr on each object in the array and joins the results with joinStr
- (NSString *)componentsUsingAttributeNamed:(NSString *)attr joinedByString:(NSString *)joinStr;
- (NSString *)componentsUsingAttributeKeyPathNamed:(NSString *)attr joinedByString:(NSString *)joinStr;

// This methods will generate the ASCII XML Representation
- (NSData *)asciiXMLRepresentation;
// This methods will write out the array and its contents as an ASCII XML Representation
// (Calls asciiXMLReperesentation for the actual XML)
- (BOOL)writeAsAsciiXMLToFile: (NSString *)path_to_write;

// returns an array of dictionaries. Each dictionary has 2 keys:
//		MCGroupByIndex
//      MCGroupByObjects
// The array contains the grouped by objects (a subset of this array)
// The MCGroupByIndex contains whatever anIndexKey returns. You can use that for sorting later
// or it is used by the sorting code if you specify sorting
// anIndexKey is optional
// The difference between this method and the others is that this method puts the returned value of aKeyPath in a dictionary as uses it as a key instead of converting it to a string then then grouping that way.
// WHATEVER OBJECT THAT IS RETURNED BY aKeyPath MUST IMPLEMENT copyWithZone:
- (NSArray *)groupByUniqueValueForKey:(NSString *)aKeyPath indexKey:(NSString *)anIndexKey sort:(MCGroupBySorting)sorting;


// Calls valueForKey: on all objects in the array and groups by the unique values returned.
// If the receiver is empty nil is returned
- (NSDictionary *)groupByUniqueValueForKey: (NSString *)key;
// Calls groupByUniqueValueForKey: and then adds a copy of the receiver for the key @"All"
- (NSDictionary *)groupByUniqueValueForKey: (NSString *)key includeAllKey: (BOOL)flag;

// calls valueForKey, separates the return value by separator and groups by that
- (NSDictionary *)groupByUniqueValueForKey: (NSString *)key valueSeparator:(NSString *)separator;
// calls valueForKey, and applies the format to the calendar date returned
- (NSDictionary *)groupByUniqueValueForKey: (NSString *)key dateFormat:(NSString *)format;

- (NSArray *)reverseArray;

- (NSArray *)arrayOfObjectsForKeypath:(NSString *)keypath;

// Creates a new array with the return value of calling selector on each object.  
// If selector return nil we add an [NSNull null]
- (NSArray*)arrayOfObjectsByCallingSelector: (SEL)selector;
- (NSArray*)arrayOfObjectsByCallingSelector: (SEL)selector withObject:(id)object;
	// same as previous, except passes in object to the selector

- (void)logDebugInformation;

- (NSNumber *)sumAsInteger;
- (NSNumber *)sumAsFloat;
- (NSNumber *)sumAsDouble;
- (NSNumber *)avgAsFloat;
- (NSNumber *)avgAsInteger;

- (BOOL)isEmpty;

// This is meant to duplicate the behavior seen in the Recent Documents menu in the cocoa Document architecture
// Whereby paths with the same filename show the actual path, but only enough such that the user can see the difference between them
// Thus preventing the whole path(which could be very long) from having to be displayed
- (NSArray *)shortestRelevantPaths;

- (id)firstObject;
// to work around conflicts in other categories
- (id)mcFirstObject;


// Enumerates through all the objects, if any are arrays it flattens it out(only goes one deep for now)
- (NSArray *)flattenArrayOfArrays;

// gets all the objects in our array at all the indexes in the set, and returns an array of them
- (NSArray *)objectsFromIndexSet:(NSIndexSet *)indexSet;

// i.e. 2 Contacts, or John Smith, or 5 Objects. Mainly used to title menu items, i.e. "New Email for John Smith"
- (NSString *)modelObjectMenuDescription;

// Replace any MCIntermediaryObjectProxy objects with the represented object
- (NSArray *)arrayByReplacingProxyObjects;

// Remove duplicates, but maintain the order of the objects(NSSet has no order!)
- (NSArray *)arrayByRemovingDuplicates;

// See NSMutableDictionary+MCAdditions for description
- (void)performSubstitutionWith:(NSDictionary *)aDict inStringValuesWithStartDelimiter:(NSString *)startDelim endDelimiter:(NSString *)endDelim;


- (NSArray*)indexesOfObjects:(NSArray*)objs;
- (NSIndexSet *)indexSetOfObjects:(NSArray *)objectArray;

- (NSString*)stringSet;

// Takes an array of dictionaries which represent sort descriptors (which can be archived in a plist or such) and converts them to NSSortDescriptors
- (NSArray *)sortDescriptorsForDictionaryRepresentations;
// Takes an array of NSSortDescriptors and converts them to dictionary representations which can then be archived in a plist for instance
- (NSArray *)dictionaryRepresentationsForSortDescriptors;
@end
