/*
 * Copyright (C) 2002 - 2007 Lehrstuhl Grafische Systeme, BTU Cottbus
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package de.grogra.c4d.model;

import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.net.URLClassLoader;

import de.grogra.grammar.RecognitionExceptionList;
import de.grogra.grammar.Tokenizer;
import de.grogra.reflect.ClassAdapter;
import de.grogra.reflect.Method;
import de.grogra.reflect.Type;
import de.grogra.util.IOWrapException;
import de.grogra.vfs.MemoryFileSystem;
import de.grogra.xl.compiler.CClass;
import de.grogra.xl.compiler.Shell;
import de.grogra.xl.compiler.scope.ClassPath;
import de.grogra.xl.compiler.scope.CompilationUnitScope;
import de.grogra.xl.parser.XLTokenizer;

public final class C4DShell extends Shell
{
	C4DShell ()
	{
		super (new ClassPath (C4D.getLoaderForAll ()));
	}

	protected ClassLoader createClassLoader ()
	{
		return super.createClassLoader();
	}

	protected void printlnError (String msg)
	{
		C4D.println (msg);
	}

	protected Type compile (ClassLoader parentLoader, ClassPath path, CompilationUnitScope lastScope, CClass shell, String cmd,
							CompilationUnitScope[] newScopeOut) throws IOException
	{
		try
		{
			Tokenizer t = new XLTokenizer ();
			t.setSource (new StringReader (cmd), "Console");
			MemoryFileSystem[] fs = {null};
			CompilationUnitScope[] results = C4D.compile(Shell.createParser(t), path, (lastScope == null) ? C4D.getImports(path) : Shell.extractImports(lastScope), shell, fs);
			newScopeOut[0] = results[0];
			Type[] a = results[0].getDeclaredTypes ();
			if (a.length == 0)
			{
				return null;
			}
			URL u = fs[0].toURL (fs[0].getRoot ());
			ClassLoader cloader = new URLClassLoader (new URL[] {u}, parentLoader);
			return ClassAdapter.wrap (Class.forName (a[0].getBinaryName (), false, cloader), false);
		}
		catch (ClassNotFoundException e)
		{
			throw new IOWrapException (e);
		}
		catch (RecognitionExceptionList e)
		{
			throw new IOWrapException (e);
		}
	}

	protected void invokeCompiledMethod (Method method) throws Exception
	{
		try
		{
			method.invoke (null, null);
		}
		finally
		{
			if (C4D.RUNTIME.currentGraph () != null)
			{
				C4D.RUNTIME.currentGraph ().derive ();
			}
		}
	}
}
