package dk.dtu.brainfuckcomp;

import java.io.IOException;

public class Brainfuck {
	
	private int[] arr;
	private int lenght;
	private int pointer;
	
	public Brainfuck(int n) {
		pointer = 0;
		lenght = n;
		arr = new int[n];
	}
	
	public void parse(String str) throws UnknownSymbolExeption {
		int loopMode = 0;
		String loopString = "";
		for (char a: str.toCharArray()) {
			if (loopMode>0 && (loopMode != 1 || a != ']')) {
				loopString += a;
			}
			
			if (a == '[') {
				loopMode++;
				continue;
			}
			
			if (a == ']') {
				loopMode--;
			}
			
			if (loopString.length() > 0 && loopMode == 0) {
				parseLoop(loopString);
				loopString = "";
				continue;
			}
			
			if (loopMode == 0) {
				parseChar(a);
			}
		}
	}
	
	private void parseLoop(String str) throws UnknownSymbolExeption {
		int loopMode = 0;
		String loopString = "";
		while (arr[pointer] != 0) {
			for (char a: str.toCharArray()) {
				if (loopMode>0 && (loopMode != 1 || a != ']')) {
					loopString += a;
				}
				
				if (a == '[') {
					loopMode++;
					continue;
				}
				
				if (a == ']') {
					loopMode--;
				}
				
				if (loopString.length() > 0 && loopMode == 0) {
					parseLoop(loopString);
					loopString = "";
					continue;
				}
				
				if (loopMode == 0) {
					parseChar(a);
				}
			}	
		}
	}
	
	private void parseChar(char a) throws UnknownSymbolExeption {
		switch (a) {
		case '>': 	incPointer();
					break;
		case '<':	decPointer(); 	
					break;
		case '+': 	incValue();
					break;
		case '-': 	decValue();
					break;
		case '.': 	printCurr();
					break;
		case ',': 	inputChar();
					break;
		default: 	throw new UnknownSymbolExeption();
		}
	}

	private void incValue() {
		arr[pointer] += 1;
	}
	
	private void decValue() {
		arr[pointer] -= 1;
	}
	
	private void incPointer() {
   		pointer += 1;
   		if (pointer >= lenght) {
   			throw new NullPointerException();
   		}
	} 
	
	private void decPointer() {
   		pointer -= 1;
   		if (pointer < 0) {
   			throw new NullPointerException();
   		}
	} 
	
	private void printCurr() {
		System.out.print((char) arr[pointer]);
	}

	private void inputChar() {
        System.out.println("Enter a Character:");
        try {
            arr[pointer] = System.in.read();
        }
        catch (IOException e){
            System.out.println("Error reading from user");
        }
	}
	
	public String toString() {
		String str = "\n[";
		
		for (int n: arr) {
			str += " " + n + " ";
		}
		
		str += "]\n  ";
		
		for (int i = 0; i < pointer; i++) {
			str += "  ";
			for (int j = 0; j < String.valueOf(arr[i]).length(); j++) {
				str += " ";
			}
		}
		return str += "^";
	}
 
}

@@ -280,32 +280,332 @@
 ymbolExeption %7B%0A
+%09%09parseHelper(str, false);%0A%09%7D%0A%09%0A%09private void parseHelper(String str, boolean loop) throws UnknownSymbolExeption %7B%0A%09%09if (loop) %7B%0A%09%09%09while (arr%5Bpointer%5D != 0) %7B%0A%09%09%09%09parseString(str);%0A%09%09%09%7D%09%09%09%0A%09%09%7D else %7B%0A%09%09%09parseString(str);%0A%09%09%7D%0A%09%7D%0A%09%0A%09private void parseString(String str) throws UnknownSymbolExeption %7B%0A
 %09%09int loopMode =
@@ -600,32 +600,32 @@
 t loopMode = 0;%0A
-
 %09%09String loopStr
@@ -906,36 +906,38 @@
 = 0) %7B%0A%09%09%09%09parse
-Loop
+Helper
 (loopString);%0A%09%09
@@ -927,24 +927,30 @@
 r(loopString
+, true
 );%0A%09%09%09%09loopS
@@ -1026,16 +1026,16 @@
 har(a);%0A
+
 %09%09%09%7D%0A%09%09%7D
@@ -1044,578 +1044,8 @@
 %7D%0A%09%0A
-%09private void parseLoop(String str) throws UnknownSymbolExeption %7B%0A%09%09int loopMode = 0;%0A%09%09String loopString = %22%22;%0A%09%09while (arr%5Bpointer%5D != 0) %7B%0A%09%09%09for (char a: str.toCharArray()) %7B%0A%09%09%09%09if (loopMode%3E0 && (loopMode != 1 %7C%7C a != '%5D')) %7B%0A%09%09%09%09%09loopString += a;%0A%09%09%09%09%7D%0A%09%09%09%09%0A%09%09%09%09if (a == '%5B') %7B%0A%09%09%09%09%09loopMode++;%0A%09%09%09%09%09continue;%0A%09%09%09%09%7D%0A%09%09%09%09%0A%09%09%09%09if (a == '%5D') %7B%0A%09%09%09%09%09loopMode--;%0A%09%09%09%09%7D%0A%09%09%09%09%0A%09%09%09%09if (loopString.length() %3E 0 && loopMode == 0) %7B%0A%09%09%09%09%09parseLoop(loopString);%0A%09%09%09%09%09loopString = %22%22;%0A%09%09%09%09%09continue;%0A%09%09%09%09%7D%0A%09%09%09%09%0A%09%09%09%09if (loopMode == 0) %7B%0A%09%09%09%09%09parseChar(a);%0A%09%09%09%09%7D%0A%09%09%09%7D%09%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09pri

Refactor avoid duplicate code