//
//  XTBannerGridTextModel.m
//  XTads
//
//  Created by Rune Berg on 16/04/16.
//  Copyright © 2016 Rune Berg. All rights reserved.
//

#import "XTBannerGridTextModel.h"
#import "XTLogger.h"
#import "XTAllocDeallocCounter.h"
#import "XTStringUtils.h"


@interface XTBannerGridTextModel ()

@property XTOutputFormatter *outputFormatter;

@property NSMutableArray<NSMutableAttributedString *>*rows;


@end


@implementation XTBannerGridTextModel

#define ROW_INITIAL_CAPACITY 100

OVERRIDE_ALLOC_FOR_COUNTER
OVERRIDE_DEALLOC_FOR_COUNTER

@synthesize hasChanged = _hasChanged;

- (id)init
{
	self = [super init];
	if (self != nil) {
		_rowIndex = 0;
		_columnIndex = 0;
		_maxRowIndex = 0;
		_maxColumnIndex = 0;
		_rows = [NSMutableArray arrayWithCapacity:20];
		_hasChanged = NO;
	}
	return self;
}

+ (instancetype)withTextFormatter:(XTOutputFormatter *)outputFormatter
{
	XTBannerGridTextModel *res = [XTBannerGridTextModel new];
	res.outputFormatter = outputFormatter;
	return res;
}

- (void)clear
{
	self.rowIndex = 0;
	self.columnIndex = 0;
	self.maxRowIndex = 0;
	self.maxColumnIndex = 0;
	self.rows = [NSMutableArray arrayWithCapacity:20];
	_hasChanged = YES;
}

- (void)addAttributedString:(NSAttributedString*)attrString
{
	NSArray<NSAttributedString *> *paragraphs = [XTStringUtils splitIntoParagraphs:attrString];
	
	for (NSAttributedString *para in paragraphs) {
		NSAttributedString *paraUsed;
		BOOL moveToNextLine;
		if ([XTStringUtils string:para.string endsWithChar:'\n']) {
			paraUsed = [XTStringUtils withoutTrailingNewline:para];
			moveToNextLine = YES;
		} else {
			paraUsed = para;
			moveToNextLine = NO;
		}
		
		[self addParagraphToGridModel:paraUsed];
		
		self.columnIndex += paraUsed.string.length;
		if (self.columnIndex > self.maxColumnIndex) {
			self.maxColumnIndex = self.columnIndex;
		}

		if (moveToNextLine) {
			self.rowIndex += 1;
			if (self.rowIndex > self.maxRowIndex) {
				self.maxRowIndex = self.rowIndex;
			}
			self.columnIndex = 0;
		}
	}
}

- (NSAttributedString *)getFullAttributedString
{
	NSMutableAttributedString *res = [NSMutableAttributedString new];
	NSAttributedString *newlineAttrString = [self.outputFormatter formatStringForGridBanner:@"\n"];
	
	BOOL needNewline = NO;
	for (NSAttributedString *row in self.rows) {
		if (needNewline) {
			[res appendAttributedString:newlineAttrString];
		}
		needNewline = YES;
		[res appendAttributedString:row];
	}
	//TODO !!! adapt? need something for last para if it had \n?
	
	_hasChanged = NO;
	
	return res;
}

//----- internal -----

- (void)addParagraphToGridModel:(NSAttributedString *)paraAttrString
{
	[self ensureRowWithIndex:self.rowIndex];
	[self ensureRowWithIndex:self.rowIndex hasColumnWithIndex:self.columnIndex];

	NSMutableAttributedString *rowMutAttrString = self.rows[self.rowIndex];
	[self overwriteMutAttrString:rowMutAttrString
					   fromIndex:self.columnIndex
				  withAttrString:paraAttrString];
	
	_hasChanged = YES;
}

//TODO !!! adapt? mv to stringutils
- (void)overwriteMutAttrString:(NSMutableAttributedString *)mutAttrString
					 fromIndex:(NSUInteger)idx
				withAttrString:(NSAttributedString *)attrString
{
	NSAttributedString *prefix = nil;
	NSUInteger lenPrefix = idx;
	if (lenPrefix >= 1) {
		NSRange rangePrefix = NSMakeRange(0, lenPrefix);
		prefix = [mutAttrString attributedSubstringFromRange:rangePrefix];
	}
	
	NSAttributedString *suffix = nil;
	NSInteger tempLenSuffix = mutAttrString.length - lenPrefix - attrString.length;
	if (tempLenSuffix >= 1) {
		NSUInteger lenSuffix = (tempLenSuffix >= 1 ? tempLenSuffix : 0);
		NSRange rangeSuffix = NSMakeRange(lenPrefix + attrString.length, lenSuffix);
		suffix = [mutAttrString attributedSubstringFromRange:rangeSuffix];
	}

	NSMutableAttributedString * newMutAttrString;
	if (prefix != nil) {
		newMutAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:prefix];
		[newMutAttrString appendAttributedString:attrString];
	} else {
		newMutAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:attrString];
	}
	if (suffix != nil) {
		[newMutAttrString appendAttributedString:suffix];
	}
	
	[mutAttrString setAttributedString:newMutAttrString];
}

- (void)ensureRowWithIndex:(NSUInteger)rowIndex
{
	NSInteger rowsToAdd = (rowIndex + 1 - self.rows.count);
	
	if (rowsToAdd >= 1) {
		for (NSInteger i = rowsToAdd; i >= 1; i--) {
			NSMutableAttributedString *mutAttrStringEmptyLine = [self createMutAttrStringForEmptySpace:@""];
			[self.rows addObject:mutAttrStringEmptyLine];
		}
	}
}

- (void)ensureRowWithIndex:(NSUInteger)rowIndex hasColumnWithIndex:(NSUInteger)columnIndex
{
	NSMutableAttributedString *row = self.rows[rowIndex];
	NSInteger colsToAdd = (columnIndex /*+ 1*/ - row.length);
	
	if (colsToAdd >= 1) {
		NSString *stringToAdd = [@"" stringByPaddingToLength:colsToAdd withString:@" " startingAtIndex:0];
		NSAttributedString *attrStringToAdd = [self createMutAttrStringForEmptySpace:stringToAdd];
		[row appendAttributedString:attrStringToAdd];
	}
}

- (NSMutableAttributedString *)createMutAttrStringForEmptySpace:(NSString *)string
{
	NSAttributedString *attrString = [self.outputFormatter formatStringForGridBanner:string];
	NSMutableAttributedString *res = [[NSMutableAttributedString alloc] initWithAttributedString:attrString];
	NSRange range = NSMakeRange(0, res.length);
	[res removeAttribute:XT_OUTPUT_FORMATTER_ATTR_RECOLORABLE_TEXT_BACKGROUND range:range];
	[res removeAttribute:NSBackgroundColorAttributeName range:range];
	return res;
}

@end
