//
//  XTHtmlUtils.m
//  XTads
//
//  Created by Rune Berg on 15/03/2019.
//  Copyright © 2019 Rune Berg. All rights reserved.
//

#import "XTHtmlUtils.h"
#import "XTHtmlTag_private.h"
#import "XTHtmlTagDiv.h"
#import "XTHtmlTagCenter.h"
#import "XTHtmlTagTd.h"
#import "XTHtmlTagTh.h"
#import "XTHtmlTagListContainer.h"
#import "XTHtmlTagLi.h"
#import "XTHtmlTagDd.h"
#import "XTHtmlTagDt.h"


@implementation XTHtmlUtils

+ (BOOL)tagIsEnclosedByDivOrCenter:(XTHtmlTag *)tag
{
	BOOL res = NO;
	
	for (XTHtmlTagContainer *container = tag.container;
		 container != nil && res == NO;
		 container = container.container) {
		
		if ([container isKindOfClass:[XTHtmlTagDiv class]] ||
			[container isKindOfClass:[XTHtmlTagCenter class]] ||
			[container isKindOfClass:[XTHtmlTagTd class]] ||
			[container isKindOfClass:[XTHtmlTagTh class]]) {
			res = YES;
		}
	}
	
	return res;
}

+ (BOOL)tagIsEnclosedByListOrListItem:(XTHtmlTag *)tag
{
	BOOL res = NO;
	
	for (XTHtmlTagContainer *container = tag.container;
		 container != nil && res == NO;
		 container = container.container) {
		
		if ([container isKindOfClass:[XTHtmlTagListContainer class]] ||
			[container isKindOfClass:[XTHtmlTagLi class]] ||
			[container isKindOfClass:[XTHtmlTagDd class]] ||
			[container isKindOfClass:[XTHtmlTagDt class]] ) {
			res = YES;
		} else if (container.cachedIsEnclosedByListOrListItem != nil) {
			res = container.cachedIsEnclosedByListOrListItem.boolValue;
		}
	}
	
	return res;
}

+ (BOOL)tag:(XTHtmlTag *)tag hasParentOfClass:(Class)aClass
{
	BOOL res = [tag.container isKindOfClass:aClass];
	return res;
}

//TODO !!! refactor: impl using findAncestorTagContainerOfClass:
+ (XTHtmlTagListContainer *)listContainerFor:(XTHtmlTag *)tag
{
	XTHtmlTagListContainer *res = nil;
	
	for (XTHtmlTagContainer *container = tag.container;
		 container != nil && res == NO;
		 container = container.container) {
		
		if ([container isKindOfClass:[XTHtmlTagListContainer class]]) {
			res = (XTHtmlTagListContainer *) container;
		}
	}
	
	return res;
}

+ (XTHtmlTagContainer *)findAncestorTagContainerOfClass:(Class)aClass
									   forDescendantTag:(XTHtmlTag *)descendantTag
									  includeDescendant:(BOOL)includeDescendant
{
	XTHtmlTagContainer *res = nil;
	
	for (XTHtmlTagContainer *container = includeDescendant ? (XTHtmlTagContainer *)descendantTag : descendantTag.container;
		 container != nil && res == nil;
		 container = container.container) {
		
		if ([container isKindOfClass:aClass]) {
			res = container;
		}
	}
	
	return res;
}

//TODO !!! refactor:
//	and define constants for default / min / max
//	and *use* those constants
+ (void)extractBaseHtmlFontSizeFromTag:(XTHtmlTag *)tag toFormattingSpec:(XTFormattingSpecification *)formattingSpec
{
	NSInteger sign;
	NSUInteger htmlSize;
	if ([tag attribute:@"size" asOptionalSign:&sign andUint:&htmlSize]) {
		if (sign == 0) {
			// only fixed size supported
			if (htmlSize < 1 || htmlSize > 7) {
				htmlSize = 3;
			}
			formattingSpec.baseHtmlSize = htmlSize;
		}
	}
}

+ (void)extractHtmlFontSizeFromTag:(XTHtmlTag *)tag toFormattingSpec:(XTFormattingSpecification *)formattingSpec
{
	NSInteger sign;
	NSUInteger htmlSize;
	if ([tag attribute:@"size" asOptionalSign:&sign andUint:&htmlSize]) {
		if (htmlSize < 1 || htmlSize > 7) {
			htmlSize = 3;
		}
		if (sign != 0) {
			// relative size
			if (sign < 0) {
				formattingSpec.htmlSize -= htmlSize;
			} else {
				formattingSpec.htmlSize += htmlSize;
			}
			if (formattingSpec.htmlSize < 1) {
				formattingSpec.htmlSize = 1;
			} else if (formattingSpec.htmlSize > 7) {
				formattingSpec.htmlSize = 7;
			}
		} else {
			// fixed size
			formattingSpec.htmlSize = htmlSize;
		}
	}
}

+ (void)extractHtmlFontFaceFromTag:(XTHtmlTag *)tag toFormattingSpec:(XTFormattingSpecification *)formattingSpec
{
	NSArray *htmlFontFaceList = [tag attributeAsCommaSeparatedStrings:@"face"];
	if (htmlFontFaceList != nil && htmlFontFaceList.count >= 1) {
		formattingSpec.htmlFontFaceList = htmlFontFaceList;
	}
}

+ (void)extractHtmlFontColorFromTag:(XTHtmlTag *)tag toFormattingSpec:(XTFormattingSpecification *)formattingSpec
{
	NSString *colorAttr = [tag attributeAsString:@"color"];
	if (colorAttr != nil) {
		formattingSpec.fontColor = [XTHtmlColor forAttributeValue:colorAttr];
	}
}

@end
