//
//  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 == nil || [self isEqualToString:@"<null>"] || [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];
}

+ (NSString *)stringWithUTF8Data:(NSData *)data {
    return [[NSString alloc]  initWithData:data encoding:NSUTF8StringEncoding];
}

- (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;

}


- (NSString *)base64Enc {
    NSData *plainData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSString *base64enc = [plainData base64EncodedStringWithOptions:0];
    
    return base64enc;
}

- (NSString *)trim {
    return [self stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
}

- (NSString *)trimSpaceAndEnter {
    return [self stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (BOOL)isEqualToIgnoreCase:(NSString *)str {
    BOOL result = false;
    if (![self isEmptyString] || ![str isEmptyString]) {
        if ([[self uppercaseString] isEqualToString:[str uppercaseString]]) {
            result = true;
        }
    }
    return result;
}

- (NSArray *) explode:(NSString*)delimiter {
    NSArray *ret = [self componentsSeparatedByString:delimiter];
    return ret;
}

- (NSString *) strReplace:(NSString *)search replace:(NSString *)replace {
    NSString *ret = [self stringByReplacingOccurrencesOfString:search withString:replace];
    
    return ret;
}

- (BOOL) strSearch:(NSString *)search {
    NSRange range;
    range = [self rangeOfString:search];
    if (range.location != NSNotFound)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

- (NSString *)stringWithFormatWithArr:(NSArray*)arguments {
//    NSRange range = NSMakeRange(0, [arguments count]);
//    NSMutableData* data = [NSMutableData dataWithLength:sizeof(id) * [arguments count]];
//    [arguments getObjects:(__unsafe_unretained id *)data.mutableBytes range:range];
//    NSString* result = [[NSString alloc] initWithFormat:self arguments:data.mutableBytes];
    
    NSString* result = [NSString stringWithFormat:self,
                        (arguments.count > 0) ? arguments[0]: nil,
                        (arguments.count > 1) ? arguments[1]: nil,
                        (arguments.count > 2) ? arguments[2]: nil,
                        (arguments.count > 3) ? arguments[3]: nil,
                        (arguments.count > 4) ? arguments[4]: nil,
                        (arguments.count > 5) ? arguments[5]: nil,
                        (arguments.count > 6) ? arguments[6]: nil,
                        (arguments.count > 7) ? arguments[7]: nil,
                        (arguments.count > 8) ? arguments[8]: nil,
                        (arguments.count > 9) ? arguments[9]: nil,
                        (arguments.count > 10) ? arguments[10]: nil,
                        (arguments.count > 11) ? arguments[11]: nil,
                        (arguments.count > 12) ? arguments[12]: nil,
                        (arguments.count > 13) ? arguments[13]: nil,
                        (arguments.count > 14) ? arguments[14]: nil,
                        (arguments.count > 15) ? arguments[15]: nil,
                        (arguments.count > 16) ? arguments[16]: nil,
                        (arguments.count > 17) ? arguments[17]: nil,
                        (arguments.count > 18) ? arguments[18]: nil,
                        (arguments.count > 19) ? arguments[19]: nil,
                        (arguments.count > 20) ? arguments[20]: nil];
    return result;
}

-(BOOL)isDigit
{
    NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    NSRange nond = [self rangeOfCharacterFromSet:nonDigits];
    if (NSNotFound == nond.location) {
        return YES;
    } else {
        return NO;
    }
}


@end
