#import "stringCategories.h"
#import "utils.h"


@implementation NSString (NSStringTextFinding)
-(NSString *) stringUnescaped
{
    NSMutableString *s2 = [NSMutableString string];
    
    [s2 setString: self];

    [s2 replaceOccurrencesOfString: @"\\n" withString: @"\n"
                           options: NSLiteralSearch range: NSMakeRange(0, [s2 length])];
    [s2 replaceOccurrencesOfString: @"\\t" withString: @"\t"
                           options: NSLiteralSearch range: NSMakeRange(0, [s2 length])];
    [s2 replaceOccurrencesOfString: @"\\r" withString: @"\r"
                           options: NSLiteralSearch range: NSMakeRange(0, [s2 length])];
    return s2;
}

- (NSRange)findString:(NSString *)string selectedRange:(NSRange)selectedRange options:(unsigned)options wrap:(BOOL)wrap regex: (BOOL) regexFlag multiline: (BOOL) mlFlag 
{
    return [self findString: string selectedRange: selectedRange options: options wrap: wrap regex: regexFlag multiline: mlFlag substring: 0];
    
}

- (NSRange)findString:(NSString *)string selectedRange:(NSRange)selectedRange options:(unsigned)options wrap:(BOOL)wrap regex: (BOOL) regexFlag multiline: (BOOL) mlFlag substring: (int) sbstr

{
    BOOL forwards = (options & NSBackwardsSearch) == 0;
    unsigned length = [self length];
    NSRange searchRange, range;
    int mycnt;
    
    if (forwards) {
	searchRange.location = NSMaxRange(selectedRange);
	searchRange.length = length - searchRange.location;
        if(regexFlag == YES)
        {
            AGRegex *regex;
            int regexOptions;
            AGRegexMatch *match;
            regexOptions = 0;
            if (options & NSCaseInsensitiveSearch) 
                regexOptions |= AGRegexCaseInsensitive;
            if(mlFlag == YES) regexOptions |= AGRegexMultiline;
            regex = [[AGRegex alloc] initWithPattern: string options: regexOptions];
            match = [regex findInString: self range: searchRange];
            if((mycnt = [match count]) > 0) 
            {
                if(sbstr <= mycnt - 1)
                    range = [match rangeAtIndex: sbstr];
                else
                {
                    range.location = NSNotFound;
                    range.length = 0;
                }
            }
            else if(wrap)
            {
                searchRange.location = 0;
                searchRange.length = selectedRange.location;
                match = [regex findInString: self range: searchRange];
                if((mycnt = [match count]) > 0)
                {
                    if(sbstr <= mycnt - 1)
                        range = [match rangeAtIndex: sbstr];
                    else
                    {
                        range.length = 0;
                        range.location = NSNotFound;
                    }
                    
                }
                else
                {
                    range.length = 0;
                    range.location = NSNotFound;
                }
            }
            else
            {
                range.length = 0;
                range.location = NSNotFound;
            }
            
            [regex release];
            
            
        }
        else
        {
            range = [self rangeOfString:string options:options range:searchRange];
            if ((range.length == 0) && wrap) {	/* If not found look at the first part of the string */
                searchRange.location = 0;
                searchRange.length = selectedRange.location;
                range = [self rangeOfString:string options:options range:searchRange];
            }
        }
    } 
    else 
    {
	searchRange.location = 0;
	searchRange.length = selectedRange.location;
        range = [self rangeOfString:string options:options range:searchRange];
        if ((range.length == 0) && wrap) 
        {
            searchRange.location = NSMaxRange(selectedRange);
            searchRange.length = length - searchRange.location;
            range = [self rangeOfString:string options:options range:searchRange];
        }
    }
return range;
}        
-(BOOL) startsWith: (NSString *) who
{
    NSRange r;
    r = [self rangeOfString: who];
    if(r.location == NSNotFound) return NO;
    else if (r.location == 0) return YES;
    return NO;
    
}

@end

@implementation AGRegex (NSEscapeReplace)
- (NSString *)replaceWithString:(NSString *)rep inString:(NSString *)str limit:(int)lim range: (NSRange) r
{
    [self replaceWithString: rep inString: [str substringWithRange: r] limit: lim];
}
- (NSString *)replaceWithStringWithEscape:(NSString *)rep inString:(NSString *)str limit: (int) lim range: (NSRange) r raw: (int) rawflag
{
    int n, i;
    char ch, chn;
    NSRange rrr;
    NSMutableString *newString;
    if(rawflag) {return [self replaceWithString: rep inString: str limit: lim range: r] ;}
    newString   = [[NSMutableString alloc] init];
    //go through the replace string
    n = [rep length];
    rrr.location = 0;
    rrr.length = 0;
    for(i = 0; i < n; i++)
    {
        ch = [rep characterAtIndex: i];
        if(ch == '\\' && i < n - 1)
        {
            if(rrr.length)
            {
                [newString appendString: [rep substringWithRange: rrr]];
            }
            chn = [rep characterAtIndex: ++i];
            rrr.length = 0;
            rrr.location = 1+i;
            switch(chn)
            {
                case 't':
                    [newString ADDCHAR('\t')];
                    break;
                case 'n':
                    [newString ADDCHAR('\n')];
                    break;
                case 'r':
                    [newString ADDCHAR('\r')];
                    break;
                default:
                    [newString ADDCHAR('\\')];
                    [newString ADDCHAR(chn)];
                    break;
            }
        }
        else
        {
            rrr.length +=1;
            //[newString ADDCHAR( ch)];
        }
        
    }
    if(rrr.length && rrr.location < n)
    {
        [newString appendString: [rep substringWithRange: rrr]];
    }
    [newString autorelease];
    return [self replaceWithString: newString inString: str limit: lim range: r] ;
    
    
}
- (NSString *)replaceWithStringWithEscape:(NSString *)rep inString:(NSString *)str  raw: (int) rawflag
{
    int n, i;
    char ch, chn;
    NSRange rrr;
    NSMutableString *newString;
    //go through the replace string
    if(rawflag) { return [self replaceWithString: rep inString: str] ;}
    
    newString = [[NSMutableString alloc] init];

    n = [rep length];
    rrr.location = rrr.length = 0;
    for(i = 0; i < n; i++)
    {
        ch = [rep characterAtIndex: i];
        if(ch == '\\' && i < n - 1)
        {
            if(rrr.length)
            {
                [newString appendString: [rep substringWithRange: rrr]];
            }
            chn = [rep characterAtIndex: ++i];
            rrr.length = 0;
            rrr.location = i+1;
            switch(chn)
            {
                case 't':
                    [newString ADDCHAR('\t')];
                    break;
                case 'n':
                    [newString ADDCHAR('\n')];
                    break;
                case 'r':
                    [newString ADDCHAR('\r')];
                    break;
                default:
                    [newString ADDCHAR('\\')];
                    [newString ADDCHAR(chn)];
                    break;
            }
        }
        else
        {
            rrr.length +=1;
            //[newString ADDCHAR( ch)];
        }
    }
    if(rrr.length && rrr.location < n)
    {
        [newString appendString: [rep substringWithRange: rrr]];
    }
    [newString autorelease];
    return [self replaceWithString: newString inString: str] ;
    
    
}


/*
 - (NSArray *)findAllInString:(NSString *)str range:(NSRange)range {
     int length = range.length;
     int location = range.location;
     AGRegexMatch *match;
     NSMutableArray *result = [NSMutableArray array];
     NSRange matchRange;
     while (match = [self findInString:str range:range]) {
         [result addObject:match];
         matchRange = [match range];
         range.location = matchRange.location + matchRange.length;
         if (!matchRange.length)
             range.location++;
         range.length = location + length - range.location;
         if (range.location > length)
             break;
     }
     return result;
 }
 */
@end

@implementation NSMutableAttributedString(MGWAdditions)
-(void) setColor: (NSColor *) myC
{
    NSMutableDictionary *dd = [NSMutableDictionary dictionary];
    [dd setObject: myC forKey: NSForegroundColorAttributeName];
    [self setAttributes: dd range: NSMakeRange(0, [self length])];
}
-(void) appendString: (NSString *) who
{
    [self appendAttributedString: [[[NSAttributedString alloc] initWithString: who] autorelease]];
}
-(void) setString: (NSString *) who
{
    [self setAttributedString: [[[NSAttributedString alloc] initWithString: who] autorelease]];
}
@end

