//
//  NSString+MiscAdditions.h
//    Written by Carl Lindberg Copyright 1998 by Carl Lindberg.
//                     All rights reserved.
//      This notice may not be removed from this source code.
//
//	This header is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"License.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	

#import "MCFoundationDefines.h"

#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>
#import <Foundation/NSScanner.h>

extern NSString* MCMixedCaseAlphabetString;


@class NSArray, NSEnumerator;

/* Additional searching options for some methods */
enum
{
	MiscOverlappingSearch = 2048
};

@interface NSString (MiscAdditions)

+ (NSString*)stringWithFormat: (NSString*)format arguments: (va_list)argList;

+ (NSString *)stringWithFormat:(NSString *)format argumentsArray:(NSArray *)argsArray;

+ (NSString *)uniqueID;
+ (NSString *)horizontalEllipsisString;

+ (NSString *)mcSafeStringWithContentsOfFile:(NSString *)aPath error:(NSError **)anError;

- (NSString *)initWithFormat:(NSString *)format argumentsArray:(NSArray *)argsArray;

- (NSString *)initialCapitalString;

- (NSString*)stringByAppendingColon;

- (NSNumber*)numberValueFromLongLong;

/*" Trimming whitespace "*/
- (id)stringByTrimmingLeadWhitespace;
- (id)stringByTrimmingTailWhitespace;
- (id)stringByTrimmingWhitespace;
- (id)stringBySquashingWhitespace;

/*" "Letter" manipulation "*/
- (NSString *)letterAtIndex:(unsigned)anIndex;
- (NSString *)firstLetter;
- (unsigned)letterCount;

/*" Getting "words" "*/
- (NSArray *)wordArray;
- (unsigned)wordCount;
- (NSString *)wordNum:(unsigned)n;
- (NSEnumerator *)wordEnumerator;
- (NSString *)firstWord;

/*" Bulk replacing "*/
- stringByReplacingEveryOccurrenceOfString:(NSString *)aString
                                withString:(NSString *)replaceString;
- stringByReplacingEveryOccurrenceOfString:(NSString *)searchString
                                withString:(NSString *)replaceString
								options:(unsigned)mask;
- stringByReplacingEveryOccurrenceOfCharactersFromSet:(NSCharacterSet *)aSet
                                         withString:(NSString *)replaceString;
- stringByReplacingEverySeriesOfCharactersFromSet:(NSCharacterSet *)aSet
                                     withString:(NSString *)replaceString;

- (NSString *)stringByEscapingChar:(char)aCharacter withChar:(char)replace;
- (NSString *)stringByEscapingForDelimitedExport;
- (NSString *)stringByEscapingForCommaDelimitedExport;

- (unsigned)numOfString:(NSString *)aString;
- (unsigned)numOfString:(NSString *)aString options:(unsigned)mask;
- (unsigned)numOfString:(NSString *)aString range:(NSRange)range;
- (unsigned)numOfString:(NSString *)aString options:(unsigned)mask range:(NSRange)range;
- (unsigned)numOfCharactersFromSet:(NSCharacterSet *)aSet;
- (unsigned)numOfCharactersFromSet:(NSCharacterSet *)aSet range:(NSRange)range;

- (NSRange)rangeOfString:(NSString *)aString occurrenceNum:(int)n;
- (NSRange)rangeOfString:(NSString *)aString options:(unsigned)mask occurrenceNum:(int)n;
- (NSRange)rangeOfString:(NSString *)aString occurrenceNum:(int)n range:(NSRange)range;
- (NSRange)rangeOfString:(NSString *)aString options:(unsigned)mask occurrenceNum:(int)n range:(NSRange)range;

/*" Dividing strings into pieces "*/
- (NSArray *)componentsSeparatedByCharactersFromSet:(NSCharacterSet *)aSet;
- (NSArray *)componentsSeparatedBySeriesOfCharactersFromSet:(NSCharacterSet *)aSet;
- (NSArray *)componentsSeparatedByCharactersFromSetWithoutEmptyStrings:(NSCharacterSet *)aSet;
- (NSString *)substringToString:(NSString *)aString;
- (NSString *)substringFromEndOfString:(NSString *)aString;

/*" Adding the options mask (mainly for NSCaseInsensitiveSearch) "*/
- (BOOL)containsString:(NSString *)aString;
- (BOOL)containsString:(NSString *)aString options:(unsigned)mask;
- (BOOL)containsCaseInsensitiveString:(NSString *)aString;
- (BOOL)hasPrefix:(NSString *)aString options:(unsigned)mask;
- (BOOL)hasSuffix:(NSString *)aString options:(unsigned)mask;

/*---------------------------------------------------------------------------

	MC Additions

----------------------------------------------------------------------------*/

- (NSString*)stringByPrependingString: (NSString*)string;

- (NSString*)md5Hash;

- (NSString*)stringByStrippingNonNumberCharacters;
- (NSString *)stringByRemovingEveryOccurrenceOfCharactersFromSet:(NSCharacterSet *)aSet;
- (NSString *)stringByRemovingSubString:(NSString *)removeString;
- (NSString *)stringByRemovingSubStrings:(NSArray *)subs;
- (BOOL)containsSubString:(NSString *)searchString;

- (int) consecutiveOccurencesOfCharacter: (unichar) character fromIndex: (int) index;
- (int) consecutiveOccurencesInReverseOfCharacter: (unichar) character fromIndex: (int) index;

// Returns YES if there is a . and @ 
- (BOOL)looksLikeEmail;

- (NSString *)rtfSafe;
- (NSString *)htmlSafe;

// returns a string forcefully converted to unicode
- (NSString *)unicodeRepresentation;

// Runs through the string one character at a time stripping out anything that doesn't work with UTF8 encoding
- (NSString*)mcForceUTF8Conversion;

- (BOOL)isEqualToCaseInsensitiveString:(NSString *)aString;

// Breaks up a string by using capital letter as delimiter
//- (NSArray *)componentsSeparatedByCapitalLetters;

// replaces uppercase letters with a space and lower case
// so 'attributeName' becomes 'attribute name'
- (NSString *)humanReadableRepresentation;


// Methods for escaping and unescaping strings
- (NSString *)escapeStringUsingCharacterSet: (NSCharacterSet *)set;
- (NSString *)unescapeStringUsingCharacterSet: (NSCharacterSet *)set;
// Calls above methods with a set of double-quotes and backslash
- (NSString *)escapeStringUsingSimpleSet;
- (NSString *)unescapeStringUsingSimpleSet;
- (NSString *)escapeStringUsingOpenBaseSafeSet;
- (NSString *)escapeStringUsingTempOpenBaseSafeSet;
- (NSString *)escapeStringUsingSQLiteSafeSet;
- (NSString *)mcEscapedHtml;
- (NSString *)mcEscapedJson;
- (NSString *)mcEscapedURIForEncoding:(NSStringEncoding)anEncoding;
- (NSString *)mcEscapedURIForUTF8Encoding;
- (NSString *)mcEscapedURIForLatin1Encoding;

// returns a reversed string(i.e. 'hello' would return 'olleh')
- (NSString *)reverseString;

// Checks to see if the receiver starts with the passed in string from the beginning
- (BOOL)startsWithString: (NSString *)str;
// Checks to see if the receiver starts with the passed in string within the passed in range
- (BOOL)startsWithString: (NSString *)str range: (NSRange)range;

// Replaces all occurences of / with :
- (NSString *)hfsPathRepresentation;

// Replaces all occurences of /n with /r
- (NSString *)macLineEndingsRepresentation;
- (NSString *)pluralString;

- (NSDictionary *)dictionaryFromURLString;

- (NSString *)stringByTruncatingToLengthIfNecessary:(unsigned)maxLength;

- (NSString *)fileKindForPath;
- (NSString *)fileNameWithoutExtensionForPath;

+ (NSString*)stringSetWithValues:(NSArray*)values;
- (NSArray*)valuesForStringSet;
- (NSArray*)numberValuesForStringSet;
- (BOOL)stringSetContainsValue:(id)aValue;

- (NSString*)addValueToStringSet:(id)aValue;
- (NSString*)removeValueFromStringSet:(id)aValue;

- (NSString*)addNumberValuesToStringSet:(NSArray*)values;
- (NSString*)removeNumberValuesFromStringSet:(NSArray*)values;

// In the format: Deposition.doc in "Documents"
- (NSString *)friendlyFileAndPathDescription;
- (NSString *)shortFileDescription;

// Version String Methods
// Compares version string such as 1.0.2 or 3.4 or 4.2.3.45.5
- (BOOL)isNewerThanVersionString: (NSString*)versionString; // return NO if the same
- (BOOL)isNewerOrEqualThanVersionString: (NSString*)versionString; // returns YES if the same

- (BOOL)endsWithString:(NSString*)aString;

- (NSString*)filenameSafeString;

- (unsigned int)numberOfLines;
- (unsigned int)startLineForSubstring:(NSString*)aString;
- (NSString*)stringForLineContainingRange:(NSRange)aRange;

// Chooses the string with the best capitalization for comparison:
//    Best   - First letter of each word capitalized is the highest
//    Worst  - First letter of first word is lowercase
- (NSComparisonResult)capitalizedCaseInsensitiveStringCompare:(NSString *)str;

- (NSString *)stringForLineEndingType:(MCLineEndingType)lineEndingType;

- (NSString *)initialLowerCaseString;
- (NSString *)initialLowerCaseStringExceptingAcronyms; // prevents URL->uRL etc.
@end


@interface NSMutableString (MiscAdditions)

/*" Bulk replacing "*/
- (void)replaceEveryOccurrenceOfString:(NSString *)string withString:(NSString *)replaceString;
- (void)replaceEveryOccurrenceOfString:(NSString *)string
                            withString:(NSString *)replaceString
							   options:(unsigned)mask;
- (void)replaceEveryOccurrenceOfCharactersFromSet:(NSCharacterSet *)aSet
			withString:(NSString *)replaceString;
- (void)replaceEverySeriesOfCharactersFromSet:(NSCharacterSet *)aSet
			withString:(NSString *)replaceString;


@end

@interface NSString (MCPObjectAdditions)
// i.e. call this on "New Appointment" and get something like "New Appointment for John Smith"
- (NSString *)stringByAddingTitleForLinkedObjects:(NSArray *)linkedObjs;
@end
