//
//  XTTabStopUtils.m
//  XTads
//
//  Created by Rune Berg on 31/10/2019.
//  Copyright © 2019 Rune Berg. All rights reserved.
//

#import "XTTabStopUtils.h"
#import "XTStringUtils.h"
#import "XTTabStopModelEntry.h"
#import "XTLogger.h"
#import "XTTextTableBlock.h"
#import "XTTextTab.h"


@implementation XTTabStopUtils

static XTLogger* logger;

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

+ (NSArray<XTRecalcTabStopCommand *> *)limitTabStopsSensitiveToResizing:(NSTextStorage *)textStorage range:(NSRange)range
{
	//XT_DEF_SELNAME;
	//XT_WARN_2(@"range=%lu,%lu", range.location, range.length);
	
	NSMutableArray<XTRecalcTabStopCommand *> *res = [NSMutableArray arrayWithCapacity:10];
	NSString *textStorageString = textStorage.string;
	NSUInteger idx = range.location;
	NSUInteger idxLimit = range.location + range.length;

	while (idx < idxLimit) {
		//XT_WARN_1(@"para idx=%lu", idx);
		NSRange paraRange = [XTStringUtils rangeOfNextParagraphIn:textStorageString fromLoc:idx];
		NSAttributedString *paraAttrStr = [textStorage attributedSubstringFromRange:paraRange]; // keep for debugging
		
		NSRange effRange;
		NSMutableParagraphStyle *oldParaStyle = [textStorage attribute:NSParagraphStyleAttributeName atIndex:idx effectiveRange:&effRange];
		
		NSArray *paraTabStops = oldParaStyle.tabStops;
		NSUInteger tabIdx = 0;
		for (NSUInteger idxInPara = 0; idxInPara < paraRange.length; idxInPara++) { //TODO !!! adapt: skip if paraTabStops is empty?
			NSUInteger idxInTextStorage = paraRange.location + idxInPara;
			unichar ch = [textStorageString characterAtIndex:idxInTextStorage];
			if (ch == '\t') {
				NSTextTab *tabStop = paraTabStops[tabIdx];
				if ([tabStop isKindOfClass:[XTTextTab class]]) {
					XTTextTab *castTabStop = (XTTextTab *)tabStop;
					if ([self tabStopIsSensitiveToResizing:castTabStop]) {
						BOOL paraIsInTextCell = (oldParaStyle != nil && oldParaStyle.textBlocks.count >= 1);
						if (paraIsInTextCell) {
							NSRange tabRange = NSMakeRange(idxInTextStorage, 1);
							[textStorage replaceCharactersInRange:tabRange withString:@" "];
						}
						XTRecalcTabStopCommand *resElement = [XTRecalcTabStopCommand forIdxInTextStorage:idxInTextStorage
																					 tabIndexInParagraph:tabIdx
																			   reinsertTabForPlaceholder:paraIsInTextCell];
						[res addObject:resElement];
					}
				}
				tabIdx += 1;
			}
		}
		idx += paraRange.length;
	}
	
	return res;
}

+ (void)restoreTabStopSensitiveToResizing:(NSTextStorage *)textStorage atPos:(NSUInteger)pos
{
	unichar ch = [textStorage.string characterAtIndex:pos];
	if (ch == ' ') {
		NSRange tabRange = NSMakeRange(pos, 1);
		[textStorage replaceCharactersInRange:tabRange withString:@"\t"];
	} else {
		XT_DEF_SELNAME;
		XT_ERROR_1(@"unexpected char %C", ch);
	}
}

+ (BOOL)tabStopIsSensitiveToResizing:(XTTextTab *)tabStop
{
	BOOL res = NO;
	if ([XTTabStopUtils tabStopIsAtRhsOfView:tabStop] ||
		[XTTabStopUtils tabStopIsAtHalfwayToRhsOfView:tabStop] ||
		[XTTabStopUtils tabStopIsToId:tabStop] ||
		[XTTabStopUtils tabStopIsForHorizRuler:tabStop]) {
		res = YES;
	}
	if (! res) {
		int brkpt = 1;
	}
	return res;
}

+ (BOOL)tabStopIsAtRhsOfView:(XTTextTab *)textTab
{
	return [XTTabStopUtils tabStop:textTab isOfType:XT_TAB_TYPE_RHS_OF_VIEW];
}

+ (BOOL)tabStopIsAtHalfwayToRhsOfView:(XTTextTab *)textTab
{
	return [XTTabStopUtils tabStop:textTab isOfType:XT_TAB_TYPE_HALFWAY_TO_RHS_OF_VIEW];
}

+ (BOOL)tabStopIsToId:(XTTextTab *)textTab
{
	return [XTTabStopUtils tabStop:textTab isOfType:XT_TAB_TYPE_TO_ID];
}

+ (BOOL)tabStopIsAtMultiple:(XTTextTab *)textTab
{
	return [XTTabStopUtils tabStop:textTab isOfType:XT_TAB_TYPE_MULTIPLE];
}

+ (BOOL)tabStopIsAtFixedPos:(XTTextTab *)textTab
{
	return [XTTabStopUtils tabStop:textTab isOfType:XT_TAB_TYPE_FIXED_POS];
}

+ (BOOL)tabStopIsForHorizRuler:(XTTextTab *)textTab
{
	return [XTTabStopUtils tabStop:textTab isOfType:XT_TAB_TYPE_HORIZ_RULER];
}

+ (BOOL)tabStop:(XTTextTab *)textTab isOfType:(NSString *)type
{
	NSString *actualType = [textTab getCustomOptionForKey:XT_TAB_TYPE_KEY];
	BOOL res = [actualType isEqualToString:type];
	return res;
}

+ (XTTextTab *)createLimitedTabStopFrom:(XTTextTab *)oldTextTab position:(CGFloat)position
{
	NSMutableDictionary<NSString *,id> *options = [NSMutableDictionary dictionaryWithDictionary:oldTextTab.options];
	NSMutableDictionary<NSString *,id> *customOptions = [NSMutableDictionary dictionaryWithDictionary:[oldTextTab getCustomOptions]];
	XTTextTab *textTab = [XTTextTab withTextAlignment:NSTextAlignmentLeft location:position options:options customOptions:customOptions];
	return textTab;
}

@end
