package jp.kirikiri.tjs2;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class NativeClassMethod extends Dispatch {
	private static final int S_TRUE = 1;
	private static final int
		E_NATIVECLASSCRASH = (-1008),
		E_INVALIDPARAM = (-1003),
		E_ACCESSDENYED = (-1007);

	protected Method mProcess;

	public NativeClassMethod( Method processfunc ) {
		mProcess = processfunc;
	}

	public int isInstanceOf( int flag, final String membername, IntWrapper hint, final String classname, Dispatch2 objthis ) throws VariantException, TJSException {
		if( membername == null ) {
			if( "Function".equals(classname) ) return S_TRUE;
		}
		int ret = super.isInstanceOf(flag, membername, hint, classname, objthis);
		return ret;
	}
	public int funcCall( int flag, final String membername, IntWrapper hint, Variant result, Variant[] param, Dispatch2 objthis ) throws VariantException, TJSException {
		if( membername != null ) return super.funcCall(flag, membername, hint, result, param, objthis);

		if( objthis == null ) return E_NATIVECLASSCRASH;

		if( result != null ) result.clear();

		int er = 0;
		Object[] args = new Object[3];
		args[0] = result;
		args[1] = param;
		args[2] = objthis;
		Object ret;
		try {
			ret = mProcess.invoke( objthis, args );
			er = ((Integer)ret).intValue();
		} catch (IllegalArgumentException e) {
			er = E_INVALIDPARAM;
		} catch (IllegalAccessException e) {
			er = E_ACCESSDENYED;
		} catch (InvocationTargetException e) {
			Throwable t = e.getCause();
			if( t instanceof VariantException ) {
				throw (VariantException)t;
			} else if( t instanceof TJSException ) {
				throw (TJSException)t;
			} else {
				throw new TJSException( t.toString() );
			}
		}
		return er;
	}
	// 以下の形のメソッドが標準系
	// int Method( Variant result, Variant[] param, Dispatch2 objthis );
	// 自動的に適合する形のものも作った方がいい気がする
}
