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

import java.util.List;

import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.coreengine.rendering.guiOld.renderer.IFontRenderer.CharInstance;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;

public class Line
{
	float totalWidth;
	float width;
	int totalLetters = 0;
	String result = null;
	List<Word> words = new ObjectArrayList<>();
	
	public Line(float totalWidth)
	{
		this.totalWidth = totalWidth;
	}
	
	public boolean attemptAddingWord(Word word)
	{
		if(word.getWidth() + width > totalWidth)
		{
			return false;
		}
		width += word.getWidth();
		words.add(word);
		totalLetters += word.size();
		return true;
	}
	
	public void addWord(Word word)
	{
		width += word.getWidth();
		words.add(word);
		totalLetters += word.size();
	}
	
	protected void finishLine()
	{
		StringBuilder builder = new StringBuilder();
		for(Word word : words)
		{
			builder.append(word.getLetters());
		}
		result = builder.toString();
	}
	
	public int getIndex(float width, boolean total)
	{
		if(width <= 0F) return (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
		if(width >= this.width) return ((total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0) + totalLetters;
		int letters = (total && !words.isEmpty()) ? words.get(0).getStartIndex() : 0;
		for(int i = 0,m=words.size();i<m;i++)
		{
			Word word = words.get(i);
			if(word.getWidth() > width)
			{
				return letters + word.getIndex(width);
			}
			width -= word.getWidth();
			letters += word.size();
		}
		return letters;
	}
	
	public String getText()
	{
		return result;
	}
	
	public boolean isEmpty()
	{
		return words.isEmpty();
	}
	
	public int size()
	{
		return totalLetters;
	}
	
	public int getStart()
	{
		return words.isEmpty() ? 0 : words.get(0).getStartIndex();
	}
	
	public int getEnd()
	{
		return words.isEmpty() ? 0 : words.get(words.size() - 1).getEndIndex();
	}
	
	public Word getWord(int letterIndex)
	{
		for(int i = 0;i<words.size();i++)
		{
			Word word = words.get(i);
			if(word.size() >= letterIndex)
			{
				return word;
			}
			letterIndex -= word.size();
		}
		return null;
	}
	
	public float getWidth()
	{
		return width;
	}
	
	public float getWidth(int index)
	{
		if(index <= 0) return 0F;
		else if(index >= totalLetters) return width;
		float width = 0F;
		for(int i = 0,m=words.size();i<m;i++)
		{
			Word word = words.get(i);
			if(word.size() > index)
			{
				return width + word.getWidth(index);
			}
			width += word.getWidth();
			index -= word.size();
		}
		return 0;
	}
	
	@SuppressWarnings("unchecked")
	public Iterable<CharInstance> letterIterator()
	{
		ObjectIterator<CharInstance>[] arrays = new ObjectIterator[words.size()];
		for(int i = 0,m=words.size();i<m;i++)
		{
			arrays[i] = words.get(i).objectInstanceIterator();
		}
		return IterableWrapper.wrap(ObjectIterators.concat(arrays));
	}
}
