//
// IMTextInputTraits.m
// Project
//
// Created by haibara on 9/22/16.
//
//

#import "IMTextInput.h"
#import "SystemUtils.h"
#import "IMFunctions.h"
#import <JRSwizzle/JRSwizzle.h>

NSString *const IMTextContentTypeName = @"name";
NSString *const IMTextContentTypeNamePrefix = @"honorifix-prefix";
NSString *const IMTextContentTypeGivenName = @"given-name";
NSString *const IMTextContentTypeMiddleName = @"additional-name";
NSString *const IMTextContentTypeFamilyName = @"family-name";
NSString *const IMTextContentTypeNameSuffix = @"honorifix-suffix";
NSString *const IMTextContentTypeNickname = @"nickname";
NSString *const IMTextContentTypeJobTitle = @"organization-title";
NSString *const IMTextContentTypeOrganizationName = @"organization";
NSString *const IMTextContentTypeLocation = @"location";
NSString *const IMTextContentTypeFullStreetAddress = @"street-address";
NSString *const IMTextContentTypeStreetAddressLine1 = @"address-line1";
NSString *const IMTextContentTypeStreetAddressLine2 = @"address-line2";
NSString *const IMTextContentTypeAddressCity = @"address-level2";
NSString *const IMTextContentTypeAddressState = @"address-level1";
NSString *const IMTextContentTypeAddressCityAndState = @"address-level1+2";
NSString *const IMTextContentTypeSublocality = @"address-level3";
NSString *const IMTextContentTypeCountryName = @"country-name";
NSString *const IMTextContentTypePostalCode = @"postal-code";
NSString *const IMTextContentTypeTelephoneNumber = @"tel";
NSString *const IMTextContentTypeEmailAddress = @"email";
NSString *const IMTextContentTypeURL = @"url";
NSString *const IMTextContentTypeCreditCardNumber = @"cc-number";
NSString *const IMTextContentTypeUsername = @"username";
NSString *const IMTextContentTypePassword = @"password";

@implementation IMTextInput

+ (NSDictionary *)transformTextContentType {
	NSMutableDictionary *dict = [NSMutableDictionary dictionary];
	if ([SystemUtils isOperatingSystemAtLeastVersion:NSOperatingSystemVersionMake(10, 0, 0)]) {
		[dict addEntriesFromDictionary:@{ IMTextContentTypeName : UITextContentTypeName, IMTextContentTypeNamePrefix : UITextContentTypeNamePrefix, IMTextContentTypeGivenName : UITextContentTypeGivenName, IMTextContentTypeMiddleName : UITextContentTypeMiddleName, IMTextContentTypeFamilyName : UITextContentTypeFamilyName, IMTextContentTypeNameSuffix : UITextContentTypeNameSuffix, IMTextContentTypeNickname : UITextContentTypeNickname, IMTextContentTypeJobTitle : UITextContentTypeJobTitle, IMTextContentTypeOrganizationName : UITextContentTypeOrganizationName, IMTextContentTypeLocation : UITextContentTypeLocation, IMTextContentTypeFullStreetAddress : UITextContentTypeFullStreetAddress, IMTextContentTypeStreetAddressLine1 : UITextContentTypeStreetAddressLine1, IMTextContentTypeStreetAddressLine2 : UITextContentTypeStreetAddressLine2, IMTextContentTypeAddressCity : UITextContentTypeAddressCity, IMTextContentTypeAddressState : UITextContentTypeAddressState, IMTextContentTypeAddressCityAndState : UITextContentTypeAddressCityAndState, IMTextContentTypeSublocality : UITextContentTypeSublocality, IMTextContentTypeCountryName : UITextContentTypeCountryName, IMTextContentTypePostalCode : UITextContentTypePostalCode, IMTextContentTypeTelephoneNumber : UITextContentTypeTelephoneNumber, IMTextContentTypeEmailAddress : UITextContentTypeEmailAddress, IMTextContentTypeURL : UITextContentTypeURL, IMTextContentTypeCreditCardNumber : UITextContentTypeCreditCardNumber }];
	}
	if (@available(iOS 11, *)) {
		[dict addEntriesFromDictionary:@{ IMTextContentTypeUsername : UITextContentTypeUsername, IMTextContentTypePassword : UITextContentTypePassword }];
	}
	return [NSDictionary dictionaryWithDictionary:dict];
}

@end

@implementation UITextField (IMCompatible)

- (void)setIm_textContentType:(NSString *)textContentType {
	if ([self respondsToSelector:@selector(setTextContentType:)]) {
		self.textContentType = [IMTextInput transformTextContentType][textContentType];
	}
}

- (NSString *)im_textContentType {
	if ([self respondsToSelector:@selector(textContentType)]) {
		return [[IMTextInput transformTextContentType] allKeysForObject:self.textContentType].firstObject;
	}
	return nil;
}

@end

@implementation UITextField (IMMethodSwizzling)

+ (void)load {
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		[self jr_swizzleMethod:@selector(intrinsicContentSize) withMethod:@selector(im_intrinsicContentSize) error:NULL];
		[self jr_swizzleMethod:@selector(textRectForBounds:) withMethod:@selector(im_textRectForBounds:) error:NULL];
		[self jr_swizzleMethod:@selector(editingRectForBounds:) withMethod:@selector(im_editingRectForBounds:) error:NULL];
	});
}

#pragma mark - Method Swizzling

- (CGSize)im_intrinsicContentSize {
	CGSize size = [self im_intrinsicContentSize];
	if (self.borderStyle == UITextBorderStyleRoundedRect) {
		size.height += ceil(self.font.lineHeight) - 30 + 4;
	}
	return size;
}

- (CGRect)im_textRectForBounds:(CGRect)bounds {
	CGRect rect = [self im_textRectForBounds:bounds];
	rect = [self fixRectForBounds:rect];
	return rect;
}

- (CGRect)im_editingRectForBounds:(CGRect)bounds {
	CGRect rect = [self im_editingRectForBounds:bounds];
	rect = [self fixRectForBounds:rect];
	return rect;
}

#pragma mark - Private

- (CGRect)fixRectForBounds:(CGRect)bounds {
	CGRect rect = bounds;
	if (self.borderStyle == UITextBorderStyleBezel) {
		rect.origin.y -= 1.5;
	}
	return rect;
}

@end
