/src/BlinkenCPU.java
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
import javax.microedition.midlet.MIDlet;

public class BlinkenCPU extends MIDlet implements CommandListener, Runnable {
	private BlinkenCanvas canvas;
	private Display display;
	private BlinkenEngine engine;
	private Thread thread;

	private static final Command start = new Command("Start", Command.SCREEN, 1);
	private static final Command stop = new Command("Stop", Command.SCREEN, 1);
	private static final Command load = new Command("Load", Command.SCREEN, 2);
	private static final Command clear = new Command("Clear", Command.SCREEN, 3);
	private static final Command exit = new Command("Exit", Command.EXIT, 2);
	private static final Command darn = new Command("Darn", Command.EXIT, 1);


	public void startApp() {
		display = Display.getDisplay(this);
		engine = new BlinkenEngine();
		engine.loadState();
		canvas = new BlinkenCanvas(engine);

		canvas.addCommand(load);
		canvas.addCommand(clear);
		canvas.addCommand(exit);
		if (engine.loaded())
			canvas.addCommand(start);
		canvas.setCommandListener(this);
		canvas.draw();

		display.setCurrent(canvas);

		thread = new Thread(this);
		thread.start();
	}

	public void pauseApp() {
		display.flashBacklight(0);
	}

	public void destroyApp(boolean unconditional) {
		display.flashBacklight(0);
		engine.saveState();
	}

	public void run() {
		while (true) {
			if (engine.running()) {
				try {
					display.flashBacklight(0x7FFFFFFF);
					engine.step();
				} catch (BlinkenEngineException e) {
					engine.stop();
					shitSauce("Execution error", e.error);
				}
			}
			canvas.update();
			canvas.draw();
			try {
				Thread.sleep(100);
			} catch(InterruptedException e) {
			}
		}
	}

	public void commandAction(Command c, Displayable d) {
		if (c == start) {
			if (engine.loaded()) {
				engine.run();
				canvas.removeCommand(start);
				canvas.addCommand(stop);
			} else {
				display.setCurrent(new Alert("Code not loaded"));
			}
		} else if (c == stop) {
			engine.stop();
			canvas.removeCommand(stop);
			canvas.addCommand(start);
			display.flashBacklight(0);
		} else if (c == load) {
			BlinkenFileSelect bfs = new BlinkenFileSelect(this, engine, display);
			bfs.start();
		} else if (c == clear) {
			engine.clear();
		} else if (c == exit) {
			destroyApp(true);
			notifyDestroyed();
		} else if (c == darn) {
			display.setCurrent(canvas);
		}
	}

	public void loadFile(String file) {
		try {
			FileConnection fc = (FileConnection) Connector.open(file, Connector.READ);
			if (!fc.exists()) {
				display.setCurrent(new Alert("File does not exist"));
				return;
			}
			InputStream f = fc.openInputStream();
			try {
				engine.compile(f);
				canvas.addCommand(start);
			} catch (BlinkenEngineException e) {
				shitSauce("Failed to compile " + file, e.error);
			}
			f.close();
			fc.close();
			display.setCurrent(canvas);
		} catch (IOException e) {
			display.setCurrent(new Alert("File Open Failed\n" + e));
		}
	}

	public void shitSauce(String title, String error) {
		TextBox b = new TextBox(title, error, 1024, TextField.ANY | TextField.UNEDITABLE);
		b.addCommand(darn);
		b.setCommandListener(this);
		display.setCurrent(b);
	}
}