package speiger.src.coreengine.rendering.guiOld.renderer.lexer;

import java.util.List;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.guiOld.components.TextComponent;

public class TextMetadata
{
	TextComponent owner;
	List<Line> lines = new ObjectArrayList<>();
	float startX;
	float startY;
	float maxHeight;
	float maxWidth = 0F;
	float scale;
	
	public TextMetadata(TextComponent owner)
	{
		this.owner = owner;
	}

	public void clear()
	{
		scale = owner.getTextScale();
		lines.clear();
		maxWidth = 0F;
		maxHeight = 0F;
		startX = 0F;
		startY = 0F;
	}
	
	public void addLine(Line line)
	{
		lines.add(line);
		maxWidth = Math.max(maxWidth, line.getWidth());
		maxHeight = lines.size() * owner.getFont().height() * scale;
	}
	
	public void setStart(float x, float y)
	{
		startX = x;
		startY = y;
	}
	
	public float getStartX()
	{
		return startX;
	}
	
	public float getStartY()
	{
		return startY;
	}
	
	public float getMaxHeight()
	{
		return maxHeight;
	}
	
	public float getMaxWidth()
	{
		return maxWidth;
	}
	
	public float getWidth(int letterIndex)
	{
		return lines.isEmpty() ? 0F : lines.get(0).getWidth(letterIndex);
	}
	
	public float getWidth(int posX, int posY)
	{
		return lines.size() > posY ? lines.get(posY).getWidth(posX) : 0F;
	}
	
	public float getLineWidth(int line)
	{
		return lines.size() > line ? lines.get(line).getWidth() : 0F;
	}
	
	public Word getWord(int letterIndex)
	{
		return lines.isEmpty() ? null : lines.get(0).getWord(letterIndex);
	}
	
	public Line getLine(int line)
	{
		return lines.size() > line ? lines.get(line) : null;
	}
	
	public int moveUp(Vec2i pos)
	{
		if(pos.y() + 1 < lines.size())
		{
			float width = lines.get(pos.y()).getWidth(pos.x());
			return lines.get(pos.y() + 1).getIndex(width, true);
		}
		return lines.isEmpty() ? 0 : lines.get(lines.size() - 1).getEnd();
	}
	
	public int moveDown(Vec2i pos)
	{
		if(pos.y() > 0 && pos.y() - 1 < lines.size())
		{
			float width = lines.get(pos.y()).getWidth(pos.x());
			return lines.get(pos.y() - 1).getIndex(width, true);
		}
		return lines.isEmpty() ? 0 : lines.get(0).getStart();
	}
	
	public int getIndex(float width)
	{
		return lines.size() > 0 ? lines.get(0).getIndex(width, false) : 0;
	}
	
	public int getIndex(float width, float height)
	{
		return lines.isEmpty() ? 0 : lines.get(MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)))).getIndex(width, true);
	}
	
	public void getIndex(float width, float height, Vec2i result)
	{
		if(lines.isEmpty())
		{
			result.negate();
			return;
		}
		int index = MathUtils.clamp(0, lines.size() - 1, (int)(height / (owner.getFont().height() * scale)));
		result.set(lines.get(index).getIndex(width, false), index);
	}
	
	public void convert(int index, Vec2i result)
	{
		result.set(Vec2i.ZERO);
		for(int i = 0,m=lines.size();i<m;i++)
		{
			Line line = lines.get(i);
			if(line.size() >= index)
			{
				result.add(index, i);
				return;
			}
			index -= line.size();
		}
	}
	
	public int convert(Vec2i input)
	{
		int index = input.x();
		for(int i = 0,m=input.y();i<m;i++)
		{
			index += lines.get(i).size();
		}
		return index;
	}
}
