//
//  XTConverter.m
//  TadsTerp
//
//  Created by Rune Berg on 03/04/14.
//  Copyright (c) 2014 Rune Berg. All rights reserved.
//

#import "XTConverter.h"
#import "XTAllocDeallocCounter.h"
#import "XTLogger.h"
#import "XTCharacterSets.h"


@implementation XTConverter

//TODO unit test

static XTLogger* logger;

+ (void)initialize
{
	if (self == [XTConverter class]) {
		logger = [XTLogger loggerForClass:[XTConverter class]];
	}
}

+ (instancetype)converter
{
	XTConverter *converter = [[XTConverter alloc] init];
	return converter;
}

OVERRIDE_ALLOC_FOR_COUNTER
OVERRIDE_DEALLOC_FOR_COUNTER

- (BOOL)toUInteger:(NSString *)s uinteger:(NSUInteger *)uinteger
{
	NSScanner *scanner = [NSScanner scannerWithString:s];
	unsigned long long ull = 0;
	BOOL res = NO;
	if ([scanner scanUnsignedLongLong:&ull]) {
		if (ull <= NSUIntegerMax) {
			if ([scanner isAtEnd]) {
				*uinteger = ull;
				res = YES;
			}
		}
	}
	return res;
}

- (BOOL)hexToUInteger:(NSString *)s uinteger:(NSUInteger *)uinteger
{
	NSUInteger sLen = s.length;
	BOOL res = (sLen >= 1);
	
	if (res) {
		NSCharacterSet *hexDigitCharSet = [XTCharacterSets hexDigitCharSet];
		
		for (NSUInteger i = 0; i < sLen; i++) {
			unichar ch = [s characterAtIndex:i];
			if (! [hexDigitCharSet characterIsMember:ch]) {
				res = NO;
				break;
			}
		}
	}
	
	if (res) {
		NSScanner *scanner = [NSScanner scannerWithString:s];
		unsigned int uintVal = 0;
		res = [scanner scanHexInt:&uintVal];
		if (res) {
			*uinteger = uintVal;
		} else {
			XT_DEF_SELNAME;
			XT_WARN_1(@"\"%@\" could not be converted from hex to dec", s);
		}
	}
	
	return res;
}

- (BOOL)toInteger:(NSString *)s integer:(NSInteger *)integer
{
	NSScanner *scanner = [NSScanner scannerWithString:s];
	long long ll = 0;
	BOOL res = NO;
	if ([scanner scanLongLong:&ll]) {
		if (ll <= NSIntegerMax) {
			if ([scanner isAtEnd]) {
				*integer = ll;
				res = YES;
			}
		}
	}
	return res;
}

//TODO !!! adapt: refactor vs above method
- (BOOL)toIntegerWithOptionalSuffix:(NSString *)s integer:(NSInteger *)integer
{
	NSScanner *scanner = [NSScanner scannerWithString:s];
	long long ll = 0;
	BOOL res = NO;
	if ([scanner scanLongLong:&ll]) {
		if (ll <= NSIntegerMax) {
			//if ([scanner isAtEnd]) {
				*integer = ll;
				res = YES;
			//}
		}
	}
	return res;
}

@end
