//
//  XTTableColumnWidthTracker.m
//  XTads
//
//  Created by Rune Berg on 07/09/2018.
//  Copyright © 2018 Rune Berg. All rights reserved.
//

#import "XTTableColumnWidthTracker.h"
#import "XTTableInfo.h"
#import "XTTableColumnInfo.h"
#import "XTTextTableBlock.h"
#import "XTLogger.h"
#import "XTAllocDeallocCounter.h"


@interface XTTableColumnWidthTracker ()

@property NSUInteger nextTableId;
@property NSMutableDictionary<NSNumber*, XTTableInfo*> *tableInfoByTableId;

@end

@implementation XTTableColumnWidthTracker

static XTLogger *logger;
static XTTableColumnWidthTracker *singletonInstance = nil;

#define VOID_HANDLE_MISSING_TABLE_INFO(tableInfo) \
    if (tableInfo == nil) { \
       /* This shouldn't happen, but just in case: */ \
       XT_DEF_SELNAME; \
       XT_ERROR_1(@"tableInfo == nil for tableId %@", tableId); \
	}
#define HANDLE_MISSING_TABLE_INFO(tableInfo) \
	if (tableInfo == nil) { \
		/* This shouldn't happen, but just in case: */ \
		XT_DEF_SELNAME; \
		XT_ERROR_1(@"tableInfo == nil for tableId %@", tableId); \
		return 10.0; /* gotta return something :-( */ \
	}

+ (void)initialize
{
	logger = [XTLogger loggerForClass:[XTTableColumnWidthTracker class]];
	if (singletonInstance == nil) {
		singletonInstance = [XTTableColumnWidthTracker new];
	}
}

+ (id)tracker
{
	return singletonInstance;
}

OVERRIDE_ALLOC_FOR_COUNTER
OVERRIDE_DEALLOC_FOR_COUNTER

- (instancetype)init
{
	self = [super init];
	if (self) {
		_nextTableId = 1;
		_tableInfoByTableId = [NSMutableDictionary<NSNumber*, XTTableInfo*> dictionary];
	}
	return self;
}

- (NSNumber *)registerNewTable
{
	NSNumber *tableId = [NSNumber numberWithUnsignedInteger:self.nextTableId];
	self.nextTableId += 1;
	
	self.tableInfoByTableId[tableId] = [XTTableInfo new];
	
	return tableId;
}

- (void)noteMaxContentRectWidthForTable:(NSNumber *)tableId
						 textTableBlock:(XTTextTableBlock *)textTableBlock
								  width:(CGFloat)width
{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	VOID_HANDLE_MISSING_TABLE_INFO(tableInfo);
	
	CGFloat widthUsed;
	if (textTableBlock.widthAsPoints != nil) {
		widthUsed = textTableBlock.widthAsPoints.unsignedIntegerValue;
	} else {
		widthUsed = width;
	}

	[tableInfo noteMaxContentRectWidth:widthUsed forColumn:textTableBlock.startingColumn];
}

- (void)noteMinContentRectWidthForTable:(NSNumber *)tableId
						 textTableBlock:(XTTextTableBlock *)textTableBlock
								  width:(CGFloat)width
{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	VOID_HANDLE_MISSING_TABLE_INFO(tableInfo);

	[tableInfo noteMinContentRectWidth:width forColumn:textTableBlock.startingColumn];
}

- (CGFloat)contentRectWidthForTable:(NSNumber *)tableId
					 textTableBlock:(XTTextTableBlock *)textTableBlock
						usableWidth:(CGFloat)usableWidth
{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	HANDLE_MISSING_TABLE_INFO(tableInfo);
	
	CGFloat contentRectWidth = [tableInfo contectRectWidthForTextTableBlock:textTableBlock usableWidth:usableWidth];
	return contentRectWidth;
}

- (void)noteTotalBoundsWidthForTable:(NSNumber *)tableId
					  textTableBlock:(XTTextTableBlock *)textTableBlock
							   width:(CGFloat)width
{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	VOID_HANDLE_MISSING_TABLE_INFO(tableInfo);
	
	[tableInfo noteTotalBoundsWidthForTextTableBlock:textTableBlock width:width];
}

- (void)noteBoundsRectWidthForTable:(NSNumber *)tableId
					 textTableBlock:(XTTextTableBlock *)textTableBlock
							  width:(CGFloat)width
{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	VOID_HANDLE_MISSING_TABLE_INFO(tableInfo);
	
	[tableInfo noteBoundsRectWidthForTextTableBlock:textTableBlock width:width];
}

- (CGFloat)contentRectXForTable:(NSNumber *)tableId
				 textTableBlock:(XTTextTableBlock *)textTableBlock
						originX:(CGFloat)originX
					usableWidth:(CGFloat)usableWidth

{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	HANDLE_MISSING_TABLE_INFO(tableInfo);
	
	CGFloat contentRectX = [tableInfo contentRectXForTextTableBlock:textTableBlock
															originX:originX
														usableWidth:usableWidth];
	return contentRectX;
}


- (CGFloat)totalTableWidth:(NSNumber *)tableId
{
	XTTableInfo *tableInfo = self.tableInfoByTableId[tableId];
	HANDLE_MISSING_TABLE_INFO(tableInfo);

	CGFloat res = [tableInfo totalTableWidth];
	return res;
}

- (void)clearAll
{
	for (XTTableInfo *tableInfo in self.tableInfoByTableId.allValues) {
		[tableInfo clear];
	}
	[self.tableInfoByTableId removeAllObjects];
}

@end
