package io.github.rlee287.jrainbuck.uppering;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

import io.github.rlee287.jrainbuck.constants.Constants;

public class UVBCreator implements UVCreator {
	public byte[] rawInput;
	private String inputFile;
	private ArrayList<Byte> UVB=new ArrayList<Byte>();
	public UVBCreator(String inputFile) {
		this.inputFile=inputFile;
	}
	private void readRaw() throws IOException {
		Path inputFilePath=Paths.get(inputFile);
		rawInput=Files.readAllBytes(inputFilePath);
	}
	private void emitUV() {
		/*
		 * 0 |0 |0 |0 |0 |0 |0 |0
		 * []|+-|<>|.,|00|00|00|sign
		 */
		for ( byte inst:rawInput ) {
			Character in=new Character((char) inst);
			Byte mapped=Constants.UVB_MAP.get(in);
			if (mapped!=null) {
				UVB.add(mapped);
			}
		}
	}
	/* (non-Javadoc)
	 * @see io.github.rlee287.jrainbuck.uppering.UVCreator#getUV()
	 */
	@Override
	public byte[] getUV() {
		if ( UVB.size()==0 ) {
			/* Re-emit UVB only if necessary
			 * UV can be quite dangerous if re-emitted
			 * (CPU usage, sunburn :-) [extra )]? 
			 */
			try {
				this.readRaw();
			} catch (IOException e) {
				// Should never happen
				System.err.println("An error has occured during uppering.");
				e.printStackTrace();
			}
			this.emitUV();
		}
		byte[] returnUVB =new byte[UVB.size()];
		for (int index=0;index<UVB.size();index++) {
			returnUVB[index]=UVB.get(index);
		}
		return returnUVB;
	}
}

@@ -690,16 +690,38 @@
 n%0A%09%09 */%0A
+%09%09int bracketLevel=0;%0A
 %09%09for ( 
@@ -846,9 +846,9 @@
 pped
-!
+=
 =nul
@@ -860,29 +860,662 @@
 %09%09%09%09
-UVB.add(mapped
+//Invalid bytes are comments; ignore them%0A%09%09%09%7D else %7B%0A%09%09%09%09if (mapped==-127 %7C%7C mapped==-128) %7B%0A%09%09%09%09%09if (mapped==-128) %7B // '%5D'%0A%09%09%09%09%09%09bracketLevel--;%0A%09%09%09%09%09%7D%0A%09%09%09%09%09if (bracketLevel%3C63) %7B%0A%09%09%09%09%09%09UVB.add((byte) (mapped+2*bracketLevel)
 );%0A
+%09%09
 %09%09%09%7D
+ else if (bracketLevel%3C255) %7B%0A%09%09%09%09%09%09UVB.add((byte) (mapped+2*63));%0A%09%09%09%09%09%09UVB.add((byte) bracketLevel);%0A%09%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09throw new RuntimeException%0A%09%09%09%09%09%09(%22Maximum level of bracket nesting exceeded%22);%0A%09%09%09%09%09%7D%0A%09%09%09%09%09if (mapped==-127) %7B // '%5B'%0A%09%09%09%09%09%09bracketLevel++;%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%09else %7B%0A%09%09%09%09%09UVB.add(mapped);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%09if (bracketLevel!=0) %7B%0A%09%09%09throw new RuntimeException(%22SyntaxError: brackets do not match%22);
 %0A%09%09%7D
@@ -2150,11 +2150,67 @@
 nUVB;%0A%09%7D
+%0A%0A%09@Override%0A%09public char getUVType() %7B%0A%09%09return 'B';%0A%09%7D
 %0A%7D%0A

Add bracketing logic and type to UVBCreator