//
//  NSString-Addtions.m
//  JasonDevelop
//
//  Created by Jason Lee on 2/17/14.
//  Copyright (c) jasondevelop. All rights reserved.
//
#import "GTMNSString+HTML.h"

#import "NSString-Addtions.h"

@implementation NSString (Additions)

- (BOOL)isEmptyString {
    if([self isEqualToString:@"<null>"] || [self isEqualToString:@"null"] || self == (id)[NSNull null] || [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]) {
        return YES;
    }

    return NO;
}

- (BOOL)isNullString {
    if([self isEqualToString:@"<null>"] || [self isEqualToString:@"null"] || self == (id)[NSNull null])
        return YES;
    else
        return NO;
}


+ (NSString *)stringWithUnsignedChar:(const unsigned char *)chr {
    return [NSString stringWithUTF8String:(char *)chr];
}

- (NSInteger)countForOccurrencesOfString:(NSString *)occurString {

    NSInteger count = 0, length = [self length];
    NSRange range = NSMakeRange(0, length);
    while(range.location != NSNotFound) {
        range = [self rangeOfString:occurString options:0 range:range];
        if(range.location != NSNotFound) {
            range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
            count++;
        }
    }

    return count;
}

#pragma mark - HTML

// Decode all HTML entities using GTM
- (NSString *)stringByDecodingHTMLEntities {
    return [self gtm_stringByUnescapingFromHTML];
}

// Encode all HTML entities using GTM
- (NSString *)stringByEncodingHTMLEntities {
    return [self gtm_stringByEscapingForAsciiHTML];
}

// Strip HTML tags
- (NSString *)stringByStrippingTags {

    // Find first & and short-cut if we can
    NSUInteger ampIndex = [self rangeOfString:@"<" options:NSLiteralSearch].location;
    if (ampIndex == NSNotFound) {
        return [NSString stringWithString:self]; // return copy of string as no tags found
    }

    // Scan and find all tags
    NSScanner *scanner = [NSScanner scannerWithString:self];
    [scanner setCharactersToBeSkipped:nil];
    NSMutableSet *tags = [[NSMutableSet alloc] init];
    NSString *tag;
    do {

        // Scan up to <
        tag = nil;
        [scanner scanUpToString:@"<" intoString:NULL];
        [scanner scanUpToString:@">" intoString:&tag];

        // Add to set
        if (tag) {
            NSString *t = [[NSString alloc] initWithFormat:@"%@>", tag];
            [tags addObject:t];
        }

    } while (![scanner isAtEnd]);

    // Strings
    NSMutableString *result = [[NSMutableString alloc] initWithString:self];
    NSString *finalString;

    // Replace tags
    NSString *replacement;
    for (NSString *t in tags) {

        // Replace tag with space unless it's an inline element
        replacement = @" ";
        if ([t isEqualToString:@"<a>"] ||
            [t isEqualToString:@"</a>"] ||
            [t isEqualToString:@"<span>"] ||
            [t isEqualToString:@"</span>"] ||
            [t isEqualToString:@"<strong>"] ||
            [t isEqualToString:@"</strong>"] ||
            [t isEqualToString:@"<em>"] ||
            [t isEqualToString:@"</em>"]) {
            replacement = @"";
        }

        // Replace
        [result replaceOccurrencesOfString:t
                                withString:replacement
                                   options:NSLiteralSearch
                                     range:NSMakeRange(0, result.length)];
    }

    // Remove multi-spaces and line breaks
    finalString = [result stringByRemovingNewLinesAndWhitespace];

    // Cleanup & return
    return finalString;

}

// Replace newlines with <br /> tags
- (NSString *)stringWithNewLinesAsBRs {

    // Strange New lines:
    //	Next Line, U+0085
    //	Form Feed, U+000C
    //	Line Separator, U+2028
    //	Paragraph Separator, U+2029

    // Scanner
    NSScanner *scanner = [[NSScanner alloc] initWithString:self];
    [scanner setCharactersToBeSkipped:nil];
    NSMutableString *result = [[NSMutableString alloc] init];
    NSString *temp;
    NSCharacterSet *newLineCharacters = [NSCharacterSet characterSetWithCharactersInString:
                                         [NSString stringWithFormat:@"\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
    // Scan
    do {

        // Get non new line characters
        temp = nil;
        [scanner scanUpToCharactersFromSet:newLineCharacters intoString:&temp];
        if (temp) [result appendString:temp];
        temp = nil;

        // Add <br /> s
        if ([scanner scanString:@"\r\n" intoString:nil]) {

            // Combine \r\n into just 1 <br />
            [result appendString:@"<br />"];

        } else if ([scanner scanCharactersFromSet:newLineCharacters intoString:&temp]) {

            // Scan other new line characters and add <br /> s
            if (temp) {
                for (int i = 0; i < temp.length; i++) {
                    [result appendString:@"<br />"];
                }
            }

        }

    } while (![scanner isAtEnd]);

    // Cleanup & return
    NSString *retString = [NSString stringWithString:result];
    return retString;

}

// Remove newlines and white space from strong
- (NSString *)stringByRemovingNewLinesAndWhitespace {

    // Strange New lines:
    //	Next Line, U+0085
    //	Form Feed, U+000C
    //	Line Separator, U+2028
    //	Paragraph Separator, U+2029

    // Scanner
    NSScanner *scanner = [[NSScanner alloc] initWithString:self];
    [scanner setCharactersToBeSkipped:nil];
    NSMutableString *result = [[NSMutableString alloc] init];
    NSString *temp;
    NSCharacterSet *newLineAndWhitespaceCharacters = [NSCharacterSet characterSetWithCharactersInString:
                                                      [NSString stringWithFormat:@" \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
    // Scan
    while (![scanner isAtEnd]) {

        // Get non new line or whitespace characters
        temp = nil;
        [scanner scanUpToCharactersFromSet:newLineAndWhitespaceCharacters intoString:&temp];
        if (temp) [result appendString:temp];

        // Replace with a space
        if ([scanner scanCharactersFromSet:newLineAndWhitespaceCharacters intoString:NULL]) {
            if (result.length > 0 && ![scanner isAtEnd]) // Dont append space to beginning or end of result
                [result appendString:@" "];
        }

    }

    // Return
    NSString *retString = [NSString stringWithString:result];
    return retString;

}

@end
