package org.mlt.jkat;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

import org.mlt.jkat.evaluator.Evaluator;
import org.mlt.jkat.evaluator.StackException;
import org.mlt.jkat.parser.ParseException;
import org.mlt.jkat.parser.Vocabulary;
import org.mlt.jkat.parser.VocabularyLoader;

public class Main {

	/**
	 * Main program for JKat
	 * 
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		CommandLineParser parser = new CommandLineParser(args);
		if(parser.getFilename()==null) {
			interactiveMode(parser.getVocabularyPath());
		} else if(parser.isDebug() && parser.getFilename()!=null) {
			debuggerMode(parser.getFilename(), parser.getVocabularyPath());
		}

		try {
			VocabularyLoader loader = new VocabularyLoader();
			loader.setVocabularyPath(new File(parser.getVocabularyPath()));
			Vocabulary m = loader.load(new File(parser.getFilename()));
			Evaluator e = new Evaluator();
			e.evaluateVocabulary(m);
		} catch (ParseException e) {
			errorExit("Parse error: " + e.getMessage());
		} catch (StackException e) {
			errorExit("Evaluation error: " + e.getMessage());
		} catch (ClassCastException e) {
			errorExit("Type error: " + e.getMessage());
		} catch (RuntimeException e) {
			errorExit("ERROR: " + e.getMessage());
		}
	}

	private static void debuggerMode(String fileName, String vocabPath) throws IOException {
		greetings();
		
		Debugger debugger = new Debugger();
		debugger.setVocabularyPath(vocabPath);
		debugger.loadVocabulary(fileName);
		debugger.run(System.out, System.in, System.err);
	}

	private static void errorExit(String message) {
		System.err.println(message);
		System.exit(1);
	}

	private static void interactiveMode() throws IOException {
		interactiveMode(null);
	}
	
	private static void interactiveMode(String vocabPath) throws IOException {
		greetings();

		Interactive i = new Interactive();
		if(vocabPath!=null) i.setVocabularySearchPath(new File(vocabPath));
		i.run(System.out, System.in, System.err);
		System.exit(0);
	}

	private static void greetings() {
		final String greetingsMessage = "*** JKat interpreter v0.1 ***\n"
				+ "*** (C) Marko Lauronen 2009 ***\n"
				+ "This software is Islayware. You may use, modify and redistribute it as you wish,\n"
				+ "but please buy me a dram of nice Islay whisky if you meet me. HOWEVER, I take ABSOLUTELY NO RESPONSIBILITY\n"
				+ "of the damages using this software (or bying me a drink) may cause to you: There is no warranty.\n";
		System.out.println(greetingsMessage);
	}

}
