package org.spoofax.interpreter.library.jsglr;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.spoofax.interpreter.adapter.aterm.WrappedATerm;
import org.spoofax.interpreter.adapter.aterm.WrappedATermFactory;
import org.spoofax.interpreter.core.IContext;
import org.spoofax.interpreter.core.InterpreterException;
import org.spoofax.interpreter.core.Tools;
import org.spoofax.interpreter.stratego.Strategy;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.interpreter.terms.TermConverter;
import org.spoofax.jsglr.ParseTable;
import org.spoofax.jsglr.SGLR;
import org.spoofax.jsglr.SGLRException;

import aterm.ATermFactory;

public class JSGLR_parse_string_pt extends JSGLRPrimitive {

	private WrappedATermFactory factory;

	protected JSGLR_parse_string_pt(WrappedATermFactory termFactory) {
		super("JSGLR_parse_string_pt", 1, 4);
		this.factory = termFactory;
	}

	@Override
	public boolean call(IContext env, Strategy[] svars, IStrategoTerm[] tvars)
			throws InterpreterException {
		
		if(!Tools.isTermString(tvars[0]))
			return false;
		if(!Tools.isTermInt(tvars[1]))
			return false;
		
		JSGLRLibrary lib = getLibrary(env);
		ParseTable pt = lib.getParseTable(Tools.asJavaInt(tvars[1]));
		
		SGLR parser = makeSGLR(factory.getFactory(), pt);
		// parser.setFilter(true);
		// parser.setHeuristicFilters(false);
		
		InputStream is = new ByteArrayInputStream(Tools.asJavaString(tvars[0]).getBytes());
		try {
			IStrategoTerm result = factory.wrapTerm(parser.parse(is));
			if (!(tvars[0] instanceof WrappedATerm))
				result = TermConverter.convert(env.getFactory(), result);
			
			env.setCurrent(result);
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SGLRException e) {
			e.printStackTrace();
		}
		return false;
	}

	protected SGLR makeSGLR(ATermFactory factory, ParseTable table) {
		return new SGLR(factory, table);
	}
}

@@ -457,16 +457,68 @@
 rategy;%0A
+import org.spoofax.interpreter.terms.IStrategoAppl;%0A
 import o
@@ -820,16 +820,22 @@
 private 
+final 
 WrappedA
@@ -854,16 +854,84 @@
 factory;
+%0A%09%0A%09private SGLRException lastException;%0A%09%0A%09private String lastPath;
 %0A%0A%09prote
@@ -1064,16 +1064,208 @@
 tory;%0A%09%7D
+%0A%09%0A%09public String getLastPath() %7B%0A%09%09return lastPath;%0A%09%7D%0A%09%0A%09public SGLRException getLastException() %7B%0A%09%09return lastException;%0A%09%7D%0A%09%0A%09public void clearLastException() %7B%0A%09%09lastException = null;%0A%09%7D
 %0A%0A%09@Over
@@ -1381,20 +1381,48 @@
 on %7B%0A%09%09%0A
+%09%09clearLastException();%0A%09%09%0A
 %09%09if
+ 
 (!Tools.
@@ -1466,16 +1466,17 @@
 se;%0A%09%09if
+ 
 (!Tools.
@@ -1513,16 +1513,480 @@
  false;%0A
+%09%09if(!Tools.isTermString(tvars%5B3%5D))%0A%09%09%09return false;%0A%0A%09%09String startSymbol;%0A%09%09if (Tools.isTermString(tvars%5B2%5D)) %7B%0A%09%09%09startSymbol = Tools.asJavaString(tvars%5B2%5D);%0A%09%09%7D else if (tvars%5B2%5D.getSubtermCount() == 0 && tvars%5B2%5D.getTermType() == IStrategoTerm.APPL && ((IStrategoAppl) tvars%5B2%5D).getConstructor().getName().equals(%22None%22)) %7B%0A%09%09%09startSymbol = null;%0A%09%09%7D else %7B%0A%09%09%09return false;%0A%09%09%7D%0A%0A%09%09lastPath = Tools.asJavaString(tvars%5B3%5D);%0A%09%09Strategy onParseError = svars%5B0%5D;%0A
 %09%09%0A%09%09JSG
@@ -2361,16 +2361,29 @@
 parse(is
+, startSymbol
 ));%0A%09%09%09i
@@ -2616,34 +2616,282 @@
 e) %7B%0A%09%09%09
-e.printStackTrace(
+lastException = e;%0A%09%09%09IStrategoTerm errorTerm = factory.wrapTerm(e.toTerm(lastPath));%0A%09%09%09env.setCurrent(TermConverter.convert(env.getFactory(), errorTerm));%0A%09%09%09%0A%09%09%09// TODO: Stratego doesn't seem to print the erroneous line in Java%0A%09%09%09return onParseError.evaluate(env
 );%0A%09%09%7D%0A%09

Build fixes.