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

#import "XTStringUtils.h"


@implementation XTStringUtils

static NSCharacterSet *whitespaceCharSet;
static NSCharacterSet *whitespaceToDeleteToLastNewlineCharSet;
static NSArray *internetLinkPrefixes;

static const NSString *zeroWidthSpace = @"\u200B"; // non-printing, 0-width space

+ (void)initialize
{
	whitespaceCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
	
	NSMutableCharacterSet *tempWSTDTLNCharSet = [NSMutableCharacterSet whitespaceCharacterSet];
	[tempWSTDTLNCharSet addCharactersInString:zeroWidthSpace];
		// This char is actually printed at game start / screen clearing.
		//TODO !! more like this - test in real game
	whitespaceToDeleteToLastNewlineCharSet = tempWSTDTLNCharSet;

	internetLinkPrefixes = @[@"http:", @"https:", @"ftp:", @"news:", @"mailto:", @"telnet:"];
}

+ (BOOL)string:(NSString *)string endsWithChar:(unichar)ch
{
	//TODO unit test
	BOOL res = NO;
	NSUInteger stringLen = string.length;
	if (string != nil && stringLen >= 1) {
		unichar lastCh = [string characterAtIndex:(stringLen - 1)];
		res = (lastCh == ch);
	}
	return res;
}

+ (BOOL)string:(NSString *)string endsWith:(NSString *)end
{
	BOOL res = [XTStringUtils internalString:string endsWith:end];
	return res;
}

+ (BOOL)string:(NSString *)string endsWithCaseInsensitive:(NSString *)end
{
	if (string != nil && string.length >= 1) {
		string = [string lowercaseString];
	}
	if (end != nil && end.length >= 1) {
		end = [end lowercaseString];
	}
	BOOL res = [XTStringUtils internalString:string endsWith:end];
	return res;
}

+ (BOOL)internalString:(NSString *)string endsWith:(NSString *)end
{
	BOOL res = NO;
	if (string != nil && end != nil && string.length >= 1 && end.length >= 1) {
		NSRange rangeOfString = [string rangeOfString:end options:NSBackwardsSearch];
		if (rangeOfString.location != NSNotFound) {
			NSUInteger expectedLocation = (string.length - end.length);
			res = (rangeOfString.location == expectedLocation);
		}
	}
	return res;
}

+ (NSString *)filterRepeatedNewlines:(NSString *)string
{
	NSMutableString *res = nil;
	
	if (string != nil) {
		NSUInteger stringLength = string.length;
		res  = [NSMutableString stringWithCapacity:stringLength];
		unichar prevCh = 'z';
		for (NSUInteger i = 0; i < stringLength; i++) {
			unichar ch = [string characterAtIndex:i];
			if (ch != '\n' || prevCh != '\n') {
				NSString *newChStr = [NSString stringWithCharacters:&ch length:1];
				[res appendString:newChStr];
			}
			prevCh = ch;
		}
	}
	
	return res;
}

/*TODO rm
+ (NSRange)findRangeOfTabsAfterLastNewline:(NSString *)string
{
	NSUInteger resLoc = NSNotFound;
	NSUInteger resLen = 0;

	if (string != nil) {
		
		NSUInteger trailingTabCount = 0;
		NSInteger index = string.length - 1;
		
		while (index >= 0 && [string characterAtIndex:index] == '\t') {
			trailingTabCount += 1;
			index -= 1;
		}
		
		if (trailingTabCount >= 1) {
			if (index < 0 || [string characterAtIndex:index] == '\n') {
				resLoc = index + 1;
				resLen = trailingTabCount;
			}
		}
	}

	NSRange res = NSMakeRange(resLoc, resLen);
	return res;
}*/

//TODO unit test
+ (NSRange)findRangeOfWhitespaceAfterLastNewline:(NSString *)string
{
	NSUInteger resLoc = NSNotFound;
	NSUInteger resLen = 0;
	
	if (string != nil) {
		
		NSUInteger trailingTabCount = 0;
		NSInteger index = string.length - 1;
		
		while (index >= 0 && [whitespaceToDeleteToLastNewlineCharSet characterIsMember:[string characterAtIndex:index]]) {
			trailingTabCount += 1;
			index -= 1;
		}
		
		if (trailingTabCount >= 1) {
			if (index < 0 || [string characterAtIndex:index] == '\n') {
				resLoc = index + 1;
				resLen = trailingTabCount;
			}
		}
	}
	
	NSRange res = NSMakeRange(resLoc, resLen);
	return res;
}


//TODO unit test
+ (NSString *)trimLeadingAndTrailingWhitespace:(NSString *)string
{
	NSString *res = nil;
	if (string != nil) {
		res = [string stringByTrimmingCharactersInSet:whitespaceCharSet];
	}
	return res;
}

//TODO unit test
+ (NSString *)emptyIfNull:(NSString *)string {
	
	NSString *res = string;
	if (res == nil) {
		res = @"";
	}
	return res;
}

//TODO unit test
+ (BOOL)isInternetLink:(NSString *)string
{
	// See http://www.tads.org/t3doc/doc/htmltads/deviate.htm#Achanges
	
	BOOL res = NO;
	if (string != nil) {
		string = [XTStringUtils trimLeadingAndTrailingWhitespace:string];
		string = [string lowercaseString];
		for (NSString* prefix in internetLinkPrefixes) {
			if ([string hasPrefix:prefix]) {
				res = YES;
				break;
			}
		}
	}
	return res;
}


@end
