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

import speiger.src.collections.chars.maps.impl.hash.Char2ObjectOpenHashMap;
import speiger.src.collections.chars.maps.interfaces.Char2ObjectMap;

public enum WordType
{
	SEMICOLON(';', 3),
	COLON(':', 3),
	UNDERSCORE('_', 3),
	MINUS('-', 3),
	LEFT_BRACE('{', '}', 1),
	RIGHT_BRACE('}', '{', 2),
	LEFT_PARENTHESIS('(', ')', 1),
	RIGHT_PARENTHESIS(')', '(', 2),
	LESS_THEN('<', '>', 1),
	MORE_THEN('>', '<', 2),
	RIGHT_BRACKET('[', ']', 1),
	LEFT_BRACKET(']', '[', 2),
	SPACE(' ', 3),
	LINE_SEPERATOR('\n', 3);
	
	static final int START_WORD = 1;
	static final int END_WORD = 2;
	static final int DUAL_WORD = 3;
	static final Char2ObjectMap<WordType> MAPPER;
	
	char letter;
	Character opposite;
	int flag;
	
	private WordType(char letter, char opposite, int flag)
	{
		this.letter = letter;
		this.opposite = Character.valueOf(opposite);
		this.flag = flag;
	}
	
	private WordType(char letter, int flag)
	{
		this.letter = letter;
		this.flag = flag;
	}
	
	public char getLetter()
	{
		return letter;
	}
	
	public boolean isStartWord()
	{
		return flag == START_WORD;
	}
	
	public boolean isEndWord()
	{
		return flag == END_WORD;
	}
	
	public boolean isDualWord()
	{
		return flag == DUAL_WORD;
	}
	
	public boolean isSpace()
	{
		return this == SPACE;
	}
	
	public boolean isNewLine()
	{
		return this == LINE_SEPERATOR;
	}
	
	public boolean isOpposite(WordType letter)
	{
		return (opposite == null && letter == this) || (opposite != null && opposite.charValue() == letter.letter);
	}
	
	public Word findStartWord(Word word)
	{
		Word currentWord = word;
		while(currentWord.getPrev() != null)
		{
			currentWord = currentWord.getPrev();
			if(isOpposite(currentWord.getType()))
			{
				return currentWord;
			}
		}
		return null;
	}
	
	public Word findEndWord(Word word)
	{
		Word currentWord = word;
		while(currentWord.getNext() != null)
		{
			currentWord = currentWord.getNext();
			if(isOpposite(currentWord.getType()))
			{
				return currentWord;
			}
		}
		return null;
	}
	
	public static WordType getByLetter(char letter)
	{
		return MAPPER.get(letter);
	}
	
	static
	{
		MAPPER = new Char2ObjectOpenHashMap<WordType>();
		for(WordType type : WordType.values())
		{
			MAPPER.put(type.letter, type);
		}
	}
}
