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

import speiger.src.collections.ints.collections.IntIterable;
import speiger.src.collections.ints.collections.IntIterator;
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.coreengine.rendering.guiOld.renderer.IFontRenderer.CharInstance;
import speiger.src.coreengine.rendering.guiOld.renderer.lexer.TextContext.WordContext;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;

public class Word implements IntIterable
{
	final float scale;
    ObjectList<CharInstance> letters = new ObjectArrayList<CharInstance>();
    int startIndex;
    Word prev;
    Word next;
    WordType special = null;
    float width;
    WordContext context;
    
    public Word(float scale)
	{
    	this.scale = scale;
	}
    
    public Word(Word parent)
	{
    	prev = parent;
    	if(parent == null)
    	{
    		scale = 1F;
    		return;
    	}
    	parent.next = this;
    	startIndex = parent.getEndIndex();
    	scale = parent.scale;
	}
    
	void setPrev(Word parent)
	{
    	prev = parent;
    	parent.next = this;
    	startIndex = parent.getEndIndex();
	}
    
    public void addLetter(CharInstance letter)
    {
    	if(letter == null)
    	{
    		return;
    	}
    	letters.add(letter);
    	width += letter.getXAdvance() * scale;
    }
    
    public Word getNext()
	{
		return next;
	}
    
    public Word getPrev()
	{
		return prev;
	}
    
    public int getStartIndex()
    {
    	return startIndex;
    }
    
    public int getEndIndex()
    {
    	return startIndex + letters.size();
    }
    
    public boolean isEmpty()
    {
    	return letters.isEmpty();
    }
    
    public int size()
    {
    	return letters.size();
    }
    
    public String getLetters()
    {
    	StringBuilder builder = new StringBuilder();
    	for(int i = 0,m=letters.size();i<m;i++)
    	{
    		builder.append(Character.toChars(letters.get(i).getCharacter()));
    	}
    	return builder.toString();
    }
    
    public float getWidth()
	{
		return width;
	}
    
    public float getWidth(int index)
    {
    	if(index <= 0) return 0F;
    	else if(index >= letters.size()) return width;
    	float result = 0F;
    	for(int i = 0;i<index;i++)
    	{
    		result += letters.get(i).getXAdvance() * scale;
    	}
    	return result;
    }
    
    public boolean isSpecial()
    {
    	return special != null;
    }
    
    public WordType getType()
	{
		return special;
	}
    
    public void setSpecail(WordType type)
	{
		special = type;
	}
    
    public void setContext(WordContext context)
    {
    	this.context = context;
    }
    
    public WordContext getContext()
	{
		return context;
	}
    
    public boolean isNewLine()
    {
    	return special != null && special.isNewLine();
    }
    
	@Override
	public IntIterator iterator()
	{
		return new IntIterator(){
			int index = 0;
			@Override
			public boolean hasNext()
			{
				return index < letters.size();
			}
			
			@Override
			public int nextInt()
			{
				return letters.get(index++).getCharacter();
			}
		};
	}
    
	Iterable<CharInstance> instanceIterator()
	{
		return IterableWrapper.wrap(letters.iterator());
	}
	
	ObjectIterator<CharInstance> objectInstanceIterator()
	{
		return letters.iterator();
	}

	public int getIndex(float width)
	{
		for(int i = 0,m=letters.size();i<m;i++)
		{
			float size = letters.get(i).getXAdvance() * scale;
			if(size < width)
			{
				width -= size;
				continue;
			}
			return size / 2 < width ? i+1 : i;
		}
		return 0;
	}

}