package jp.kirikiri.tjs2;

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

public class NativeClassProperty extends Dispatch {

	static private final int
		E_INVALIDPARAM		= -1003,
		E_ACCESSDENYED		= -1007,
		E_NATIVECLASSCRASH	= -1008,
		S_OK			= 0,
		S_TRUE			= 1,
		E_FAIL			= -1;

	protected Method mGet;
	protected Method mSet;

	public NativeClassProperty( Method get, Method set ) {
		mGet = get;
		mSet = set;
		// デバッグ機能は省く
		//if(TJSObjectHashMapEnabled()) TJSAddObjectHashRecord(this);
	}
	public int isInstanceOf( int flag, final String membername, IntWrapper hint, final String classname, Dispatch2 objthis ) throws VariantException, TJSException {
		if( membername == null ) {
			if( "Property".equals(classname) ) return S_TRUE;
		}
		return super.isInstanceOf(flag, membername, hint, classname, objthis);
	}
	public int propGet( int flag, final String membername, IntWrapper hint, Variant result, Dispatch2 objthis ) throws VariantException, TJSException {
		if( membername != null ) return super.propGet( flag, membername, hint, result, objthis );

		if( objthis == null ) return E_NATIVECLASSCRASH;
		if( result == null ) return E_FAIL;

		int er = 0;
		Object[] args = new Object[2];
		args[0] = result;
		args[1] = objthis;
		Object ret;
		try {
			ret = mGet.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;
	}
	public int propSet( int flag, final String membername, IntWrapper hint, final Variant param, Dispatch2 objthis ) throws VariantException, TJSException {
		if( membername != null ) return super.propSet(flag, membername, hint, param, objthis);
		if( objthis == null ) return E_NATIVECLASSCRASH;
		if( param == null ) return E_FAIL;

		int er = 0;
		Object[] args = new Object[2];
		args[0] = param;
		args[1] = objthis;
		Object ret;
		try {
			ret = mSet.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;
	}
}
