package jp.kirikiri.tjs2;

public class Dispatch implements Dispatch2 {

	// 最適化のためにprivateでコピーする
	static private final int
		E_MEMBERNOTFOUND = -1001,
		E_NOTIMPL = -1002,
		E_INVALIDPARAM = -1003,
		S_OK = 0;
		//E_FAIL = -1;

	static private final int
		OP_BAND	= 0x0001,
		OP_BOR	= 0x0002,
		OP_BXOR	= 0x0003,
		OP_SUB	= 0x0004,
		OP_ADD	= 0x0005,
		OP_MOD	= 0x0006,
		OP_DIV	= 0x0007,
		OP_IDIV	= 0x0008,
		OP_MUL	= 0x0009,
		OP_LOR	= 0x000a,
		OP_LAND	= 0x000b,
		OP_SAR	= 0x000c,
		OP_SAL	= 0x000d,
		OP_SR	= 0x000e,
		OP_INC	= 0x000f,
		OP_DEC	= 0x0010,
		OP_MASK	= 0x001f,
		OP_MIN	= OP_BAND,
		OP_MAX	= OP_DEC;

	protected void beforeDestruction() throws VariantException, TJSException {}
	private boolean mBeforeDestructionCalled;
	public Dispatch() {
		mBeforeDestructionCalled = false;
	}
	protected void finalize() {
		// object destruction
		if( !mBeforeDestructionCalled ) {
			mBeforeDestructionCalled = true;
			try {
				beforeDestruction();
			} catch (VariantException e) {
			} catch (TJSException e) {
			}
		}
		try {
			super.finalize();
		} catch (Throwable e) {
		}
	}
	// function invocation
	public int funcCall( int flag, final String memberName, IntWrapper hint, Variant result, Variant[] param, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// function invocation by index number
	public int funcCallByNum( int flag, int num, Variant result, Variant[] param, Dispatch2 objThis ) throws VariantException, TJSException {
		return funcCall( flag, String.valueOf( num ), null, result, param, objThis );
	}

	// property get
	public int propGet( int flag, final String memberName, IntWrapper hint, Variant result, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// property get by index number
	public int propGetByNum( int flag, int num, Variant result, Dispatch2 objThis ) throws VariantException, TJSException {
		return propGet( flag, String.valueOf(num), null, result, objThis );
	}

	// property set
	public int propSet( int flag, String memberName, IntWrapper hint, final Variant param, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// property set by index number
	public int propSetByNum( int flag, int num, final Variant param, Dispatch2 objThis ) throws VariantException, TJSException {
		return propSet( flag, String.valueOf(num), null, param, objThis );
	}

	// get member count
	public int getCount( IntWrapper result, final String memberName, IntWrapper hint, Dispatch2 objThis ) throws VariantException, TJSException {
		return E_NOTIMPL;
	}

	// get member count by index number ( result is Integer )
	public int getCountByNum( IntWrapper result, int num, Dispatch2 objThis ) throws VariantException, TJSException {
		return getCount( result, String.valueOf(num), null, objThis );
	}

	// property for internal use
	public int propSetByVS( int flag, String membername, final Variant param, Dispatch2 objthis ) throws VariantException, TJSException {
		return E_NOTIMPL;
	}

	// enumerate members
	public int enumMembers( int flag, VariantClosure callback, Dispatch2 objThis ) throws VariantException, TJSException {
		return E_NOTIMPL;
	}

	// delete member
	public int deleteMember( int flag, String memberName, IntWrapper hint, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// delete member by index number
	public int deleteMemberByNum( int flag, int num, Dispatch2 objThis ) throws VariantException, TJSException {
		return deleteMember( flag, String.valueOf(num), null, objThis );
	}

	// invalidation
	public int invalidate( int flag, String memberName, IntWrapper hint, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// invalidation by index number
	public int invalidateByNum( int flag, int num, Dispatch2 objThis ) throws VariantException, TJSException {
		return invalidate( flag, String.valueOf(num), null, objThis );
	}

	// get validation, returns true or false
	public int isValid( int flag, String memberName, IntWrapper hint, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// get validation by index number, returns true or false
	public int isValidByNum( int flag, int num, Dispatch2 objThis ) throws VariantException, TJSException {
		return isValid( flag, String.valueOf(num), null, objThis );
	}

	// create new object
	public int createNew( int flag, String memberName, IntWrapper hint, Holder<Dispatch2> result, Variant[] param, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// create new object by index number
	public int createNewByNum( int flag, int num, Holder<Dispatch2> result, Variant[] param, Dispatch2 objThis ) throws VariantException, TJSException {
		return createNew( flag, String.valueOf(num), null, result, param, objThis );
	}

	// reserved1 not use

	// class instance matching returns false or true
	public int isInstanceOf( int flag, String memberName, IntWrapper hint, String className, Dispatch2 objThis ) throws VariantException, TJSException {
		return memberName != null ? E_MEMBERNOTFOUND : E_NOTIMPL;
	}

	// class instance matching by index number
	public int isInstanceOfByNum( int flag, int num, String className, Dispatch2 objThis ) throws VariantException, TJSException {
		return isInstanceOf( flag, String.valueOf(num), null, className, objThis );
	}

	// operation with member
	public int operation( int flag, String memberName, IntWrapper hint, Variant result, final Variant param, Dispatch2 objThis ) throws VariantException, TJSException {
		int op = flag & OP_MASK;
		if( op != OP_INC && op != OP_DEC && param == null )
			return E_INVALIDPARAM;
		if( op < OP_MIN || op > OP_MAX )
			return E_INVALIDPARAM;

		Variant tmp = new Variant();
		int hr = propGet( 0, memberName, hint, tmp, objThis );
		if( hr < 0 ) return hr;	// #define TJS_FAILED(x) ((x)<0)

		doVariantOperation( op, tmp, param );

		hr = propSet( 0, memberName, hint, tmp, objThis );
		if( hr < 0 ) return hr;

		if( result != null ) result.copyRef(tmp);

		return S_OK;
	}

	// operation with member by index number
	public int operationByNum( int flag, int num, Variant result, final Variant param, Dispatch2 objThis ) throws VariantException, TJSException {
		return operation( flag, String.valueOf(num), null, result, param, objThis );
	}

	// support for native instance
	public int nativeInstanceSupport( int flag, int classid, Holder<NativeInstance> pointer ) {
		return E_NOTIMPL;
	}

	// support for class instance infomation
	public int classInstanceInfo( int flag, int num, Variant value ) throws VariantException {
		return E_NOTIMPL;
	}

	public static void doVariantOperation( int op, Variant target, final Variant param) throws VariantException {
		switch(op) {
		case OP_BAND:
			target.andEqual( param );
			return;
		case OP_BOR:
			target.orEqual( param );
			return;
		case OP_BXOR:
			target.bitXorEqual( param );
			return;
		case OP_SUB:
			target.subtractEqual( param );
			return;
		case OP_ADD:
			target.addEqual( param );
			return;
		case OP_MOD:
			target.residueEqual( param );
			return;
		case OP_DIV:
			target.divideEqual( param );
			return;
		case OP_IDIV:
			target.idivequal( param );
			return;
		case OP_MUL:
			target.multiplyEqual( param );
			return;
		case OP_LOR:
			target.logicalorequal( param );
			return;
		case OP_LAND:
			target.logicalandequal( param );
			return;
		case OP_SAR:
			target.rightShiftEqual( param );
			return;
		case OP_SAL:
			target.leftShiftEqual( param );
			return;
		case OP_SR:
			target.rbitshiftequal( param );
			return;
		case OP_INC:
			target.increment();
			return;
		case OP_DEC:
			target.decrement();
			return;
		}
	}
	// reserved2
	// reserved3
}
