package speiger.src.coreengine.utils.io.streams;

public class StringReader {
	String text;
	int index;
	
	public StringReader(String text) {
		this.text = text;
		if(text == null) { throw new IllegalStateException("String is null"); }
	}
	
	public int getIndex() { return index; }
	public void setIndex(int index) { this.index = index; }
	public boolean canRead() { return canRead(1); }
	public boolean canRead(int amount) { return index + amount <= text.length(); }
	public char peek() { return text.charAt(index); }
	public char peek(int offset) { return text.charAt(index + offset); }
	public char pull() { return text.charAt(index++); }
	public void skip() { index++; }
	public void skip(int amount) { index += amount; }
	public void skipEmpty() { for(;canRead() && Character.isWhitespace(peek());skip()); }
	
	public void requirePresent(char value) {
		if(!canRead() || peek() != value) throw new IllegalStateException("Char not present");
		skip();
	}
	
	public boolean isPresent(char value) {
		if(!canRead() || peek() != value) return false;
		skip();
		return true;
	}
	
	public static boolean isQuoteCharacter(char c) { return c == '"' || c == '\''; }
	public static boolean isValidTextCharacter(char c) { return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '_' || c == '-' || c == '.' || c == '+'; }
	
	public String readText() {
		int start = index;
		while(canRead() && isValidTextCharacter(peek())) {
			skip();
		}
		return text.substring(start, index);
	}
	
	public String readQuotedText() {
		if(!canRead()) return "";
		final char next = peek();
		if(isQuoteCharacter(next)) {
			skip();
			return readUntil(next);
		}
		throw new IllegalStateException("No Quote found");
	}
	
	public String readString() {
		if(!canRead()) return "";
		final char next = peek();
		if(isQuoteCharacter(next)) {
			skip();
			return readUntil(next);
		}
		return readText();
	}
	
	public String readUntil(char end) {
		StringBuilder builder = new StringBuilder();
		boolean skip = false;
		while(canRead()) {
			char c = pull();
			if(skip) {
				if(c == end || c == '\\') {
					builder.append(c);
					skip = false;
				}
				else {
					setIndex(getIndex() - 1);
					throw new IllegalStateException("Skipping non Skippable Letter");
				}
			}
			else if(c == '\\') skip = true;
			else if(c == end) return builder.toString();
			else builder.append(c);
		}
		throw new ArrayIndexOutOfBoundsException("Ran out of characters");
	}
}
