//
//  NSString+Common.m
//  Coding_iOS
//
//  Created by 王 原闯 on 14-7-31.
//  Copyright (c) 2014年 Coding. All rights reserved.
//

#import "NSString+Common.h"
#import <CommonCrypto/CommonDigest.h>
#import "TTTAttributedLabel.h"
#import "RegexKitLite.h"
#import "sys/utsname.h"


@implementation NSString (Common)
+ (NSString *)userAgentStr{
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    NSString *userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], deviceString, [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)];
    return userAgent;
    //Coding_iOS/4.0.8.201611041630 (x86_64; iOS 10.1; Scale/2.00)
    //Coding_Enterprise_iOS/4.0.8.201611041630 (x86_64; iOS 10.1; Scale/2.00)
}

- (NSString *)URLEncoding
{
    NSString * result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( kCFAllocatorDefault,
                                                                                              (CFStringRef)self,
                                                                                              NULL,
                                                                                              CFSTR("!*'();:@&=+$,/?%#[]"),
                                                                                              kCFStringEncodingUTF8 ));
    return result;
}
- (NSString *)URLDecoding
{
    NSMutableString * string = [NSMutableString stringWithString:self];
    [string replaceOccurrencesOfString:@"+"
                            withString:@" "
                               options:NSLiteralSearch
                                 range:NSMakeRange(0, [string length])];
    return [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}


- (NSString *)md5Str
{
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ]; 
}

- (NSString*) sha1Str
{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    
    return output;
}

- (NSURL *)urlWithCodePath{
    NSString *urlStr;
    if (!self || self.length <= 0) {
        return nil;
    }else{
        if (![self hasPrefix:@"http"]) {
            urlStr = [NSString stringWithFormat:@"%@%@", [NSObject baseURLStr], [self hasPrefix:@"/"]? [self substringFromIndex:1]: self];
        }else{
            urlStr = self;
        }
        return [NSURL URLWithString:urlStr];
    }
}
- (NSURL *)urlImageWithCodePathResize:(CGFloat)width{
    return [self urlImageWithCodePathResize:width crop:NO];
}
- (NSURL *)urlImageWithCodePathResize:(CGFloat)width crop:(BOOL)needCrop{
    NSString *urlStr;
    BOOL canCrop = NO;
    if (!self || self.length <= 0) {
        return nil;
    }else{
        if (![self hasPrefix:@"http"]) {
            NSString *imageName = [self stringByMatching:@"/static/fruit_avatar/([a-zA-Z0-9\\-._]+)$" capture:1];
            if (!imageName) {
                imageName = [self stringByMatching:@"/static/project_icon/([a-zA-Z0-9\\-._]+)$" capture:1];
            }
            urlStr = [NSString stringWithFormat:@"%@%@", [NSObject baseURLStr], [self hasPrefix:@"/"]? [self substringFromIndex:1]: self];
        }else{
            urlStr = self;
            if ([urlStr rangeOfString:@"qbox.me"].location != NSNotFound) {
                if ([urlStr rangeOfString:@".gif"].location != NSNotFound) {
                    if ([urlStr rangeOfString:@"?"].location != NSNotFound) {
                        urlStr = [urlStr stringByAppendingString:[NSString stringWithFormat:@"/thumbnail/!%.0fx%.0fr/format/png", width, width]];
                    }else{
                        urlStr = [urlStr stringByAppendingString:[NSString stringWithFormat:@"?imageMogr2/auto-orient/thumbnail/!%.0fx%.0fr/format/png", width, width]];
                    }
                }else{
                    if ([urlStr rangeOfString:@"?"].location != NSNotFound) {
                        urlStr = [urlStr stringByAppendingString:[NSString stringWithFormat:@"/thumbnail/!%.0fx%.0fr", width, width]];
                    }else{
                        urlStr = [urlStr stringByAppendingString:[NSString stringWithFormat:@"?imageMogr2/auto-orient/thumbnail/!%.0fx%.0fr", width, width]];
                    }
                }
                canCrop = YES;
            }else if ([urlStr rangeOfString:@"www.gravatar.com"].location != NSNotFound){
                urlStr = [urlStr stringByReplacingOccurrencesOfString:@"s=[0-9]*" withString:[NSString stringWithFormat:@"s=%.0f", width] options:NSRegularExpressionSearch range:NSMakeRange(0, [urlStr length])];
            }else if ([urlStr hasSuffix:@"/imagePreview"]){
                urlStr = [urlStr stringByAppendingFormat:@"?width=%.0f", width];
            }
        }
        if (needCrop && canCrop) {
            urlStr = [urlStr stringByAppendingFormat:@"/gravity/Center/crop/%.0fx%.0f", width, width];
        }
        return [NSURL URLWithString:urlStr];
    }
}
- (NSURL *)urlImageWithCodePathResizeToView:(UIView *)view{
    return [self urlImageWithCodePathResize:[[UIScreen mainScreen] scale]*CGRectGetWidth(view.frame)];
}
- (NSString *)stringByRemoveHtmlTag{
    HtmlMedia *media = [HtmlMedia htmlMediaWithString:self showType:MediaShowTypeImageAndMonkey];
    return media.contentDisplay;
}
+ (NSString *)handelRef:(NSString *)ref path:(NSString *)path{
    if (ref.length <= 0 && path.length <= 0) {
        return nil;
    }
    
    NSMutableString *result = [NSMutableString new];
    if (ref.length > 0) {
        [result appendString:ref];
    }
    if (path.length > 0) {
        [result appendFormat:@"%@%@", ref.length > 0? @"/": @"", path];
    }
    return result;
//    return [result URLEncoding];
}
- (CGSize)getSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size{
    CGSize resultSize = CGSizeZero;
    if (self.length <= 0) {
        return resultSize;
    }
    NSMutableParagraphStyle *style = [NSMutableParagraphStyle new];
    style.lineBreakMode = NSLineBreakByWordWrapping;
    resultSize = [self boundingRectWithSize:CGSizeMake(floor(size.width), floor(size.height))//用相对小的 width 去计算 height / 小 heigth 算 width
                                    options:(NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin)
                                 attributes:@{NSFontAttributeName: font,
                                              NSParagraphStyleAttributeName: style}
                                    context:nil].size;
    resultSize = CGSizeMake(floor(resultSize.width + 1), floor(resultSize.height + 1));//上面用的小 width（height） 来计算了，这里要 +1
    return resultSize;
}

- (CGFloat)getHeightWithFont:(UIFont *)font constrainedToSize:(CGSize)size{
    return [self getSizeWithFont:font constrainedToSize:size].height;
}
- (CGFloat)getWidthWithFont:(UIFont *)font constrainedToSize:(CGSize)size{
    return [self getSizeWithFont:font constrainedToSize:size].width;
}

-(BOOL)containsEmoji{
    if (!self || self.length <= 0) {
        return NO;
    }
    __block BOOL returnValue = NO;
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
             }
             
         } else {
             // non surrogate
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
             }
         }
     }];
    
    return returnValue;
}
#pragma mark emotion_monkey
+ (NSDictionary *)emotion_specail_dict {
    static NSDictionary *_emotion_specail_dict;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _emotion_specail_dict = @{
                                 //猴子大表情
                                 @"coding_emoji_01": @" :哈哈: ",
                                 @"coding_emoji_02": @" :吐: ",
                                 @"coding_emoji_03": @" :压力山大: ",
                                 @"coding_emoji_04": @" :忧伤: ",
                                 @"coding_emoji_05": @" :坏人: ",
                                 @"coding_emoji_06": @" :酷: ",
                                 @"coding_emoji_07": @" :哼: ",
                                 @"coding_emoji_08": @" :你咬我啊: ",
                                 @"coding_emoji_09": @" :内急: ",
                                 @"coding_emoji_10": @" :32个赞: ",
                                 @"coding_emoji_11": @" :加油: ",
                                 @"coding_emoji_12": @" :闭嘴: ",
                                 @"coding_emoji_13": @" :wow: ",
                                 @"coding_emoji_14": @" :泪流成河: ",
                                 @"coding_emoji_15": @" :NO!: ",
                                 @"coding_emoji_16": @" :疑问: ",
                                 @"coding_emoji_17": @" :耶: ",
                                 @"coding_emoji_18": @" :生日快乐: ",
                                 @"coding_emoji_19": @" :求包养: ",
                                 @"coding_emoji_20": @" :吹泡泡: ",
                                 @"coding_emoji_21": @" :睡觉: ",
                                 @"coding_emoji_22": @" :惊讶: ",
                                 @"coding_emoji_23": @" :Hi: ",
                                 @"coding_emoji_24": @" :打发点咯: ",
                                 @"coding_emoji_25": @" :呵呵: ",
                                 @"coding_emoji_26": @" :喷血: ",
                                 @"coding_emoji_27": @" :Bug: ",
                                 @"coding_emoji_28": @" :听音乐: ",
                                 @"coding_emoji_29": @" :垒码: ",
                                 @"coding_emoji_30": @" :我打你哦: ",
                                 @"coding_emoji_31": @" :顶足球: ",
                                 @"coding_emoji_32": @" :放毒气: ",
                                 @"coding_emoji_33": @" :表白: ",
                                 @"coding_emoji_34": @" :抓瓢虫: ",
                                 @"coding_emoji_35": @" :下班: ",
                                 @"coding_emoji_36": @" :冒泡: ",
                                 @"coding_emoji_38": @" :2015: ",
                                 @"coding_emoji_39": @" :拜年: ",
                                 @"coding_emoji_40": @" :发红包: ",
                                 @"coding_emoji_41": @" :放鞭炮: ",
                                 @"coding_emoji_42": @" :求红包: ",
                                 @"coding_emoji_43": @" :新年快乐: ",
                                 //猴子大表情 Gif
                                 @"coding_emoji_gif_01": @" :奔月: ",
                                 @"coding_emoji_gif_02": @" :吃月饼: ",
                                 @"coding_emoji_gif_03": @" :捞月: ",
                                 @"coding_emoji_gif_04": @" :打招呼: ",
                                 @"coding_emoji_gif_05": @" :悠闲: ",
                                 @"coding_emoji_gif_06": @" :赏月: ",
                                 @"coding_emoji_gif_07": @" :中秋快乐: ",
                                 @"coding_emoji_gif_08": @" :爬爬: ",
                                 //特殊 emoji 字符
                                 @"0️⃣":	@"0",
                                 @"1️⃣":	@"1",
                                 @"2️⃣":	@"2",
                                 @"3️⃣":	@"3",
                                 @"4️⃣":	@"4",
                                 @"5️⃣":	@"5",
                                 @"6️⃣":	@"6",
                                 @"7️⃣":	@"7",
                                 @"8️⃣":	@"8",
                                 @"9️⃣":	@"9",
                                 @"↩️":	@"\n",
                                 };
    });
    return _emotion_specail_dict;
}
- (NSString *)emotionSpecailName{
    return [NSString emotion_specail_dict][self];
}

- (NSString *)emotionMonkeyName{
    return [self emotionSpecailName];
}


+ (NSString *)sizeDisplayWithByte:(CGFloat)sizeOfByte{
    NSString *sizeDisplayStr;
    if (sizeOfByte < 1024) {
        sizeDisplayStr = [NSString stringWithFormat:@"%.2f bytes", sizeOfByte];
    }else{
        CGFloat sizeOfKB = sizeOfByte/1024;
        if (sizeOfKB < 1024) {
            sizeDisplayStr = [NSString stringWithFormat:@"%.2f KB", sizeOfKB];
        }else{
            CGFloat sizeOfM = sizeOfKB/1024;
            if (sizeOfM < 1024) {
                sizeDisplayStr = [NSString stringWithFormat:@"%.2f M", sizeOfM];
            }else{
                CGFloat sizeOfG = sizeOfKB/1024;
                sizeDisplayStr = [NSString stringWithFormat:@"%.2f G", sizeOfG];
            }
        }
    }
    return sizeDisplayStr;
}

- (NSString *)stringByRemoveSpecailCharacters{
    static NSCharacterSet *specailCharacterSet;
    if (!specailCharacterSet) {
        NSMutableString *specailCharacters = @"\u2028\u2029".mutableCopy;
        specailCharacterSet = [NSCharacterSet characterSetWithCharactersInString:specailCharacters];
    }
    return [[self componentsSeparatedByCharactersInSet:specailCharacterSet] componentsJoinedByString:@""];
}

- (NSString *)trimWhitespace
{
    NSMutableString *str = [self mutableCopy];
    CFStringTrimWhitespace((__bridge CFMutableStringRef)str);
    return str;
}

- (BOOL)isEmpty
{
    return [[self trimWhitespace] isEqualToString:@""];
}

- (BOOL)isEmptyOrListening{
    return [self isEmpty] || [self hasListenChar];
}

//判断是否为整形
- (BOOL)isPureInt{
    NSScanner* scan = [NSScanner scannerWithString:self];
    int val;
    return[scan scanInt:&val] && [scan isAtEnd];
}

//判断是否为浮点形
- (BOOL)isPureFloat{
    NSScanner* scan = [NSScanner scannerWithString:self];
    float val;
    return[scan scanFloat:&val] && [scan isAtEnd];
}
//判断是否是手机号码或者邮箱
- (BOOL)isPhoneNo{
//    NSString *phoneRegex = @"1[3|5|7|8|][0-9]{9}";
    NSString *phoneRegex = @"[0-9]{1,15}";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex];
    return [phoneTest evaluateWithObject:self];
}
- (BOOL)isEmail{
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}
- (BOOL)isGK{
    NSString *gkRegex = @"[A-Z0-9a-z-_]{3,32}";
    NSPredicate *gkTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", gkRegex];
    return [gkTest evaluateWithObject:self];
}
- (BOOL)isFileName{
    NSString *phoneRegex = @"[a-zA-Z0-9\\u4e00-\\u9fa5\\./_-]+$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex];
    return [phoneTest evaluateWithObject:self];
}


- (NSRange)rangeByTrimmingLeftCharactersInSet:(NSCharacterSet *)characterSet{
    NSUInteger location = 0;
    NSUInteger length = [self length];
    unichar charBuffer[length];
    [self getCharacters:charBuffer];
    for (location = 0; location < length; location++) {
        if (![characterSet characterIsMember:charBuffer[location]]) {
            break;
        }
    }
    return NSMakeRange(location, length - location);
}
- (NSRange)rangeByTrimmingRightCharactersInSet:(NSCharacterSet *)characterSet{
    NSUInteger location = 0;
    NSUInteger length = [self length];
    unichar charBuffer[length];
    [self getCharacters:charBuffer];
    for (length = [self length]; length > 0; length--) {
        if (![characterSet characterIsMember:charBuffer[length - 1]]) {
            break;
        }
    }
    return NSMakeRange(location, length - location);
}

- (NSString *)stringByTrimmingLeftCharactersInSet:(NSCharacterSet *)characterSet {
    return [self substringWithRange:[self rangeByTrimmingLeftCharactersInSet:characterSet]];
}

- (NSString *)stringByTrimmingRightCharactersInSet:(NSCharacterSet *)characterSet {
    return [self substringWithRange:[self rangeByTrimmingRightCharactersInSet:characterSet]];
}

//转换拼音
- (NSString *)transformToPinyin {
    if (self.length <= 0) {
        return self;
    }
    NSString *tempString = [self mutableCopy];
    CFStringTransform((CFMutableStringRef)tempString, NULL, kCFStringTransformToLatin, false);
    tempString = (NSMutableString *)[tempString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];
    tempString = [tempString stringByReplacingOccurrencesOfString:@" " withString:@""];
    return [tempString uppercaseString];
}

//是否包含语音解析的图标
- (BOOL)hasListenChar{
    BOOL hasListenChar = NO;
    NSUInteger length = [self length];
    unichar charBuffer[length];
    [self getCharacters:charBuffer];
    for (length = [self length]; length > 0; length--) {
        if (charBuffer[length -1] == 65532) {//'\U0000fffc'
            hasListenChar = YES;
            break;
        }
    }
    return hasListenChar;
}

@end
