public enum TuCallStatus
{
    MESSAGE_STOP_STATUS_NORMAL = 0,
    MESSAGE_STOP_STATUS_BREAK = 1,
    MESSAGE_STOP_STATUS_CONTINUE = 2,
    MESSAGE_STOP_STATUS_RETURN = 4,
    MESSAGE_STOP_STATUS_EOL = 8
}

public class TuCall : TuObject
{
    public override string getName() { return "Call"; }
    public TuObject sender;
    public TuObject msg;
    public TuObject target;
    public TuObject slotContext;
    public TuObject activated;
    public TuObject coroutine;
    public TuCallStatus stopStatus;

    public static new TuCall createProto(TuState state)
    {
        TuCall call = new TuCall();
        return call.proto(state) as TuCall;
    }

    public static new TuCall createObject(TuState state)
    {
        TuCall call = new TuCall();
        return call.clone(state) as TuCall;
    }

    public override TuObject proto(TuState state)
    {
        TuCall pro = new TuCall();
        pro.setState(state);
        pro.createSlots();
        pro.createProtos();
        state.registerProtoWithFunc(getName(), new TuStateProto(pro.getName(), pro, new TuStateProtoFunc(pro.proto)));
        pro.protos.Add(state.protoWithInitFunc("Object"));

        TuCFunction[] methodTable = new TuCFunction[] {
                new TuCFunction("sender", new TuMethodFunc(TuCall.slotSender)),
                new TuCFunction("target", new TuMethodFunc(TuCall.slotTarget)),
                new TuCFunction("message", new TuMethodFunc(TuCall.slotCallMessage)),
            };

        pro.addTaglessMethodTable(state, methodTable);
        return pro;
    }

    public static TuObject slotSender(TuObject target, TuObject locals, TuObject message)
    {
        TuCall self = target as TuCall;
        return self.sender;
    }

    public static TuObject slotTarget(TuObject target, TuObject locals, TuObject message)
    {
        TuCall self = target as TuCall;
        return self.target;
    }


    public static TuObject slotCallMessage(TuObject target, TuObject locals, TuObject message)
    {
        TuCall self = target as TuCall;
        return self.msg;
    }

    public static TuObject with(TuState state, TuObject sender, TuObject target,
        TuObject message, TuObject slotContext, TuObject activated, TuObject coro)
    {
        TuCall call = TuCall.createObject(state);
        call.sender = sender;
        call.target = target;
        call.msg = message;
        call.slotContext = slotContext;
        call.activated = activated;
        call.coroutine = coro;
        call.stopStatus = TuCallStatus.MESSAGE_STOP_STATUS_NORMAL;
        return call;
    }
}
