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

import speiger.src.coreengine.utils.misc.CodepointSequence;

public class FontSplitter {
	private static final int FORMAT_CODE_POINT = '§';
	
	Font font;
	
	public FontSplitter(Font font) {
		this.font = font;
	}
	
	public float width(String text) {
		return width(TextStyle.DEFAULT, text, true);
	}
	
	public float width(TextStyle style, String text) {
		return width(style, text, true);
	}
	
	public float width(TextStyle style, String text, boolean applyStyleChanges) {
		TextStyle currentStyle = style;
		float total = 0F;
		for(int i = 0,m=text.length();i<m;i++) {
			int codepoint = text.codePointAt(i);
			CodepointSequence result;
			if(codepoint == FORMAT_CODE_POINT && applyStyleChanges && (result = Font.findValue(CodepointSequence.of(text, i))) != null) {
				currentStyle = currentStyle.parseArguments(style, result.toString().split(","));
				i += result.length()+3;
				continue;
			}
			total += font.width(currentStyle.font(), codepoint);
		}
		return total;
	}
	
	public String[] split(TextStyle style, String text, boolean applyTextStyles) {
		
		return null;
	}
	
	public static String removeStyleChanges(String input) {
		StringBuilder builder = new StringBuilder(input);
		for(int i = 0;i<builder.length();i++) {
			int codepoint = builder.codePointAt(i);
			CodepointSequence result;
			if(codepoint == FORMAT_CODE_POINT && (result = Font.findValue(CodepointSequence.of(builder, i))) != null) {
				builder.delete(i, (i--)+result.length()+3);
			}
		}
		return builder.toString();
	}
	
	public float[] countWidths(TextStyle style, String text) {
		float[] widths = new float[text.length()];
		TextStyle current = style;
		for(int i = 0,m=text.length();i<m;i++) {
			int codepoint = text.codePointAt(i);
			CodepointSequence result;
			if(codepoint == FORMAT_CODE_POINT && (result = Font.findValue(CodepointSequence.of(text, i))) != null) {
				style = current.parseArguments(style, result.toString());
				i += result.length()+3;
				continue;
			}
			float width = font.width(current.font(), codepoint);
			widths[i] = width;
		}
		return widths;
	}
	
	public String splitTailByWidth(TextStyle style, String text, float maxWidth, boolean applyStyleChanges) {
		if(applyStyleChanges) {
			float[] widths = countWidths(style, text);
			float totalWidth = 0;
			for(int i = text.length()-1;i>=0;i--) {
				totalWidth += widths[i];
				if(totalWidth >= maxWidth) return text.substring(i, text.length());
			}
		}
		else {
			float totalWidth = 0F;
			for(int i = text.length()-1;i>=0;i--) {
				int codepoint = text.codePointAt(i);
				totalWidth += font.width(style.font(), codepoint);
				if(totalWidth >= maxWidth) return text.substring(i, text.length());
			}
		}
		return text;
	}
	
	public String splitHeadByWidth(TextStyle style, String text, float maxWidth, boolean applyStyleChanges) {
		TextStyle current = style;
		float width = 0F;
		for(int i = 0,m=text.length();i<m;i++) {
			int codepoint = text.codePointAt(i);
			CodepointSequence result;
			if(codepoint == FORMAT_CODE_POINT && applyStyleChanges && (result = Font.findValue(CodepointSequence.of(text, i))) != null) {
				style = current.parseArguments(style, result.toString());
				i += result.length()+3;
				continue;
			}
			width += font.width(current.font(), codepoint);
			if(width >= maxWidth) return text.substring(0, i);
		}
		return text;
	}
}
