package speiger.src.coreengine.ui.gui.font;

import speiger.src.coreengine.assets.api.ID;
import speiger.src.coreengine.math.color.ColorUtils;
import speiger.src.coreengine.utils.helpers.TextUtil;

public record TextStyle(FontStyle font, int styleFlags, int color) {
	public static final TextStyle DEFAULT = new TextStyle(FontStyle.DEFAULT);
	public static final int NONE = 0;
	public static final int UNDERLINE = 1;
	public static final int STRIKETHROUGH = 2;
	public static final int HAS_COLOR = 4;
	
	public TextStyle(FontStyle font) {
		this(font, 0, 0xFFFFFFFF);
	}
	
	public TextStyle(FontStyle font, int color) {
		this(font, 0, color);
	}
	
	public TextStyle color(int color) {
		return new TextStyle(font, styleFlags | HAS_COLOR, color);
	}
	
	public TextStyle removeColor() {
		return new TextStyle(font, styleFlags & ~HAS_COLOR, color);
	}
	
	public TextStyle font(FontStyle font) {
		return new TextStyle(font, styleFlags, color);
	}
	
	public TextStyle font(ID location) {
		return new TextStyle(font.with(location), styleFlags, color);
	}
	
	public TextStyle size(float size) {
		return new TextStyle(font.with(size), styleFlags, color);
	}
	
	public TextStyle bold(boolean value) {
		return new TextStyle(font.withBold(value), styleFlags, color);
	}
	
	public TextStyle italic(boolean value) {
		return new TextStyle(font.withItalic(value), styleFlags, color);
	}
	
	public TextStyle underline(boolean value) {
		return new TextStyle(font, value ? styleFlags | UNDERLINE : styleFlags & ~UNDERLINE, color);
	}
	
	public TextStyle strikethrough(boolean value) {
		return new TextStyle(font, value ? styleFlags | STRIKETHROUGH : styleFlags & ~STRIKETHROUGH, color);
	}
	
	public TextStyle parseArguments(TextStyle original, String... args) {
		if(args == null || args.length <= 0) return this;
		ID font = font().font();
		boolean bold = font().bold();
		boolean italic = font().italic();
		boolean underline = underline();
		boolean strikethrough = strikethrough();
		int color = color();
		boolean hasColor = hasColor();
		float size = font().size();
		for(int i = 0,m=args.length;i<m;i++) {
			String entry = args[i].trim();
			if(entry.length() < 3 || entry.charAt(1) != '=') continue;
			String data = entry.substring(2);
			if(data.length() <= 0) continue;
			switch(Character.toLowerCase(entry.charAt(0))) {
				case 'f': 
					if(data.length() == 1 && data.charAt(0) == 'r') font = original.font().font();
					else {
						ID newFont = ID.tryOf(data);
						if(newFont != null) font = newFont;
					}
					break;
				case 'c':
					if(data.length() == 1 && data.charAt(0) == 'r') {
						color = original.color();
						hasColor = original.hasColor();
					}
					else if(data.length() == 1 && data.charAt(0) == 'd') {
						color = -1;
						hasColor = false;
					}
					else {
						color = ColorUtils.parse(data, color);
						hasColor = true;
					}
					break;
				case 's': {
					if(data.length() == 1 && data.charAt(0) == 'r') size = original.font().size();
					else size = TextUtil.parseFloat(data, size);
					break;
				}
				case 'b':
					bold = TextUtil.parseBoolean(data, bold, original.bold());
					break;
				case 'i':
					italic = TextUtil.parseBoolean(data, italic, original.italic());
					break;
				case 'u':
					underline = TextUtil.parseBoolean(data, underline, original.underline());
					break;
				case 'l':
					strikethrough = TextUtil.parseBoolean(data, strikethrough, original.strikethrough());
					break;
			}
		}
		if(color != color() || hasColor != hasColor() || bold != bold() || italic != italic() || underline != underline() || strikethrough != strikethrough() || font != font().font() || size != size) {
			return new TextStyle(font().with(font, (bold ? FontStyle.BOLD : FontStyle.REGULAR) | (italic ? FontStyle.ITALIC : FontStyle.REGULAR), size), (underline ? UNDERLINE : NONE) | (strikethrough ? STRIKETHROUGH : NONE) | (hasColor ? HAS_COLOR : NONE), color);
		}
		
		return this;
	}
	
	public boolean hasColor() {
		return (styleFlags & HAS_COLOR) != 0;
	}
	
	public boolean bold() {
		return font.bold();
	}
	
	public boolean italic() {
		return font.italic();
	}
	
	public boolean underline() {
		return (styleFlags & UNDERLINE) != 0;
	}
	
	public boolean strikethrough() {
		return (styleFlags & STRIKETHROUGH) != 0;		
	}
}
