//
//  ValidateUtil.m
//  JasonDevelop
//
//  Created by Jason Lee on 8/5/14.
//  Copyright (c) 2014 JasonDevelop All rights reserved.
//
#import "JDObject.h"

#import "ValidateUtil.h"

@implementation ValidateUtil

+ (NSString *)getUTF8String:(NSString *)hanggulString {
    NSArray *chosung = [[NSArray alloc] initWithObjects:@"ㄱ",@"ㄲ",@"ㄴ",@"ㄷ",@"ㄸ",@"ㄹ",@"ㅁ",@"ㅂ",@"ㅃ",@"ㅅ",@"ㅆ",@"ㅇ",@"ㅈ",@"ㅉ",@"ㅊ",@"ㅋ",@"ㅌ",@"ㅍ",@"ㅎ",nil];
    NSArray *jungsung = [[NSArray alloc] initWithObjects:@"ㅏ",@"ㅐ",@"ㅑ",@"ㅒ",@"ㅓ",@"ㅔ",@"ㅕ",@"ㅖ",@"ㅗ",@"ㅘ",@"ㅙ",@"ㅚ",@"ㅛ",@"ㅜ",@"ㅝ",@"ㅞ",@"ㅟ",@"ㅠ",@"ㅡ",@"ㅢ",@"ㅣ",nil];
    NSArray *jongsung = [[NSArray alloc] initWithObjects:@"",@"ㄱ",@"ㄲ",@"ㄳ",@"ㄴ",@"ㄵ",@"ㄶ",@"ㄷ",@"ㄹ",@"ㄺ",@"ㄻ",@"ㄼ",@"ㄽ",@"ㄾ",@"ㄿ",@"ㅀ",@"ㅁ",@"ㅂ",@"ㅄ",@"ㅅ",@"ㅆ",@"ㅇ",@"ㅈ",@"ㅊ",@"ㅋ",@" ㅌ",@"ㅍ",@"ㅎ",nil];
    NSString *textResult = @"";
    for (int i=0;i<[hanggulString length];i++) {
        NSInteger code = [hanggulString characterAtIndex:i];
        if (code >= 44032 && code <= 55203) {
            NSInteger uniCode = code - 44032;
            NSInteger chosungIndex = uniCode / 21 / 28;
            NSInteger jungsungIndex = uniCode % (21 * 28) / 28;
            NSInteger jongsungIndex = uniCode % 28;
            textResult = [NSString stringWithFormat:@"%@%@%@%@", textResult, [chosung objectAtIndex:chosungIndex], [jungsung objectAtIndex:jungsungIndex], [jongsung objectAtIndex:jongsungIndex]];
        }
    }
    return textResult;
}

+ (NSString *)appendPrefix:(NSString *)text {
    NSString *parted = [ValidateUtil getUTF8String:text];
    
    if ([parted isEmptyString]) {//한글이 아닐경우, 원래 텍스트를 리턴함.
        return text;
    }
    NSArray *jongsung = [[NSArray alloc] initWithObjects:@"",@"ㄱ",@"ㄲ",@"ㄳ",@"ㄴ",@"ㄵ",@"ㄶ",@"ㄷ",@"ㄹ",@"ㄺ",@"ㄻ",@"ㄼ",@"ㄽ",@"ㄾ",@"ㄿ",@"ㅀ",@"ㅁ",@"ㅂ",@"ㅄ",@"ㅅ",@"ㅆ",@"ㅇ",@"ㅈ",@"ㅊ",@"ㅋ",@" ㅌ",@"ㅍ",@"ㅎ",nil];
    
    NSString *lastword = [parted substringFromIndex:[parted length]-1];
    BOOL hasJongsung = NO;
    for (NSString *chr in jongsung) {
        if (!hasJongsung && [lastword isEqualToString:chr]) {
            hasJongsung = YES;
            break;
        }
    }
    
    return hasJongsung ? [NSString stringWithFormat:@"%@을", text] : [NSString stringWithFormat:@"%@를", text];
}

#pragma mark - 정규표현식
+ (BOOL)validateCellular:(NSString *)phone {
    
    NSString *regEx = @"[01]{2}[0-9]{8}|[01]{2}[0-9]{9}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
    
    return [pred evaluateWithObject:phone];
}


+ (BOOL)validateId:(NSString *)userId {

    //) 10 ~ 20Byte 이내 영문, 숫자, 영문과 숫자, 한글 조합
    NSString *regEx = @"[A-Za-z0-9가-힣_]{6,11}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
    
    return [pred evaluateWithObject:userId];
}

+ (BOOL)validateNickname:(NSString *)nickname {
    
    if ([nickname length] > 7) {
        return NO;
    }

    //) 10 ~ 20Byte 이내 영문, 숫자, 영문과 숫자, 한글 조합
    NSString *regEx = @"[A-Za-z0-9가-힣_]{1,7}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];

    return [pred evaluateWithObject:nickname];
}

+ (BOOL)validateUserPasswd:(NSString *)rPasswd {
    if ([rPasswd length] > 20) {
        [ValidateUtil alert:@"최대 20까지 입력할 수 있습니다"];
        return NO;
    }
    
    //    8자이상, 영문자,숫자,특수문자 2가지 이상이 포함되어야함.
    NSString *regEx = @"(((?=.*[A-Za-z])(?=.*[0-9]))|((?=.*[A-Za-z])(?=.*[^A-Za-z0-9 \t]))|((?=.*[0-9])(?=.*[^A-Za-z0-9 \t])))[A-Za-z0-9|[^A-Za-z0-9 \t]]{8,20}";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
    
    return [pred evaluateWithObject:rPasswd];
}


+ (BOOL)validateEmail:(NSString*)email {
    
    if ([email length] > 40) {
        [ValidateUtil alert:@"최대 40까지 입력할 수 있습니다"];
        return NO;
    }
    
    //이메일 형식 검사
    NSString *regEx = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
    
    return [pred evaluateWithObject:email];
}

+ (BOOL)validateNumeric:(NSString *)numString {
    
    //숫자 형식 검사
    NSString *regEx = @"[0-9.]*$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
    
    return [pred evaluateWithObject:numString];
}


+ (BOOL)validateUserBirth:(NSString *)birth {
    
    NSString *date = [birth stringByReplacingOccurrencesOfString:@"-" withString:ksEmptyString];
    date = [date stringByReplacingOccurrencesOfString:@"." withString:ksEmptyString];
    
    //생년월일 검사
    NSString *regEx = @"[1,2]{1}[0-9]{7}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regEx];
    
    return [pred evaluateWithObject:date];
}

+ (BOOL)validateUserShortBirth:(NSString *)birth {//생년월일 6자리
    
    NSString *date = [birth stringByReplacingOccurrencesOfString:@"-" withString:ksEmptyString];
    date = [date stringByReplacingOccurrencesOfString:@"." withString:ksEmptyString];
    
    if (date.length != 6)
        return NO;
    
    NSString *month = [date substringWithRange:NSMakeRange(2, 2)];
    
    if (![ValidateUtil validateNumeric:date]) {//Month 체크
        return NO;
    }
    
    if (![ValidateUtil validateMonth:month]) {//Month 체크
        return NO;
    }
    
    if (![ValidateUtil validateDay:[date substringWithRange:NSMakeRange(4, 2)] month:month]) {//Month 체크
        return NO;
    }
    
    return YES;
}


+ (BOOL)validateCardYear:(NSString *)yearString {
    
    if (![ValidateUtil validateNumeric:yearString]) {//숫자형식이 아니면 리턴.
        return NO;
    }
    
    NSInteger sYear = [yearString intValue];
    
    //현재 연도를 구함.
    NSString *nowDate = [CommonUtil stringFromDate:[NSDate date]];
    NSString *yearStr = [NSString stringWithFormat:@"%zd", [CommonUtil dateComponentsFromString:nowDate].year];
    NSInteger rYear = [[yearStr substringFromIndex:2] intValue];
    
    //현재연도와 같거나 10년후보다 작음.
    return sYear >= rYear && sYear <= rYear + 10;
}


+ (BOOL)validateMonth:(NSString *)monthString {
    
    if (![ValidateUtil validateNumeric:monthString]) {//숫자형식이 아니면 리턴.
        return NO;
    }
    
    NSInteger sMonth = [monthString intValue];
    return sMonth >= 1 && sMonth <= 12;
}

+ (BOOL)validateDay:(NSString *)dayString month:(NSString *)monthString {
    
    if (![ValidateUtil validateNumeric:dayString]) {//숫자형식이 아니면 리턴.
        return NO;
    }
    
    NSInteger sMonth = [monthString intValue];
    NSInteger sDay = [dayString intValue];
    
    
    if (sMonth == 1 || sMonth == 3 || sMonth == 5 || sMonth == 7 || sMonth == 8 || sMonth == 10 || sMonth == 12) {//큰달이면,
        return sDay >= 1 && sDay <= 31;
        
    } else if (sMonth == 2) {//2월이면,
        return sDay >= 1 && sDay <= 29;
    }
    
    return sDay >= 1 && sDay <= 30;
}


+ (BOOL)validateCardNumber:(NSString *)numString {
    
    if (![ValidateUtil validateNumeric:numString]) {//숫자형식이 아니면 리턴.
        return NO;
    }
    
    return numString.length == 4;
}


+ (BOOL)ValidateDate:(NSString *)dateString {
    return [CommonUtil dateFromDateString:dateString] != nil;
}

+ (void)alert:(NSString *)message {
    [[JDFacade facade] alert:message];
    //    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    //    [alert show];
}


+ (BOOL)validateTextfiled:(UITextField *)textfield type:(ValidateType)type title:(NSString *)title {
    BOOL isValid = NO;
    switch (type) {
        case ValidateTypeNull:
            isValid = !(!textfield.text || [textfield.text isEqualToString:ksEmptyString]);
            if (!isValid) {
                NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%@ 입력하세요", @"%@ 입력하세요"), [ValidateUtil appendPrefix:title]];
                [ValidateUtil alert:message];
            } else {
                //check emoji
                isValid = ![CommonUtil stringContainsEmoji:textfield.text];
                if (!isValid) {
                    NSString *message = NSLocalizedString(@"이모지를 사용할 수 없습니다", @"이모지를 사용할 수 없습니다");
                    [ValidateUtil alert:message];
                }
            }
            
            break;
        case ValidateTypeNumber:
            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil validateNumeric:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%@ 형식이 올바르지 않습니다\n다시 입력해주세요", @"%@ 형식이 올바르지 않습니다\n다시 입력해주세요"), title];
                    [ValidateUtil alert:message];
                }
            }
            break;
        case ValidateTypeMobile:
            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil validateCellular:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%@ 형식이 올바르지 않습니다\n다시 입력해주세요", @"%@ 형식이 올바르지 않습니다\n다시 입력해주세요"), title];
                    [ValidateUtil alert:message];
                }
            }
            break;
        case ValidateTypeEmail:
            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil validateEmail:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%@ 형식이 올바르지 않습니다\n다시 입력해주세요", @"%@ 형식이 올바르지 않습니다\n다시 입력해주세요"), title];
                    [ValidateUtil alert:message];
                }
            }
            
            break;
        case ValidateTypePassword:
            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil validateUserPasswd:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"비밀번호 설정 가이드를 다시 확인하세요.", @"비밀번호 설정 가이드를 다시 확인하세요.")];
                    [ValidateUtil alert:message];
                }
            }
            
            break;
        case ValidateTypeNickname:

            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil validateNickname:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"사용자 이름 설정 가이드를 다시 확인하세요.", @"사용자 이름 설정 가이드를 다시 확인하세요."), title];
                    [ValidateUtil alert:message];
                }
            }
            break;
        case ValidateTypeDate:
            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil ValidateDate:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%@ 형식이 올바르지 않습니다\n다시 선택하세요", @"%@ 형식이 올바르지 않습니다\n다시 선택하세요"), title];
                    [ValidateUtil alert:message];
                }
            }
            break;
        case ValidateTypeID:
            if ([ValidateUtil validateTextfiled:textfield type:ValidateTypeNull title:title]) {
                if (!(isValid = [ValidateUtil validateId:textfield.text])) {
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"아이디 설정 가이드를 다시 확인하세요.", @"아이디 설정 가이드를 다시 확인하세요."), title];
                    [ValidateUtil alert:message];
                }
            }
            break;
    }
    
    return isValid;
}


+ (BOOL)validateTextView:(UITextView *)textview type:(ValidateType)type title:(NSString *)title {
    BOOL isValid = NO;
    switch (type) {
        case ValidateTypeNull:
            isValid = !(!textview.text || [textview.text isEqualToString:ksEmptyString]);
            if (!isValid) {
                NSString *message = [NSString stringWithFormat:NSLocalizedString(@"%@ 입력하세요", @"%@ 입력하세요"), [ValidateUtil appendPrefix:title]];
                [ValidateUtil alert:message];
            }
            
            break;
        default:
            break;
    }
    
    return isValid;
}

@end
