function FunctionSelf(){return FunctionSelf.caller;}
function Delegate(obj,funcOrName)
{
var delegate=new Function("","return FunctionSelf().Invoke(FunctionSelf().arguments)"); delegate.Invoke=Delegate.Invoke;
delegate.Detach=Delegate.Detach; delegate.Arguments=Delegate.arguments;
delegate.Object=obj;
delegate.UniqueName="DelegateUniqueID"+Math.floor((new Date().getTime()+Math.random())*1000);
if(typeof(funcOrName)=="string")
{
delegate.FuncName=funcOrName;
delegate.Function=obj[delegate.FuncName];
}
else
{
delegate.FuncName=null;
delegate.Function=funcOrName;
}
return delegate;
}
function Delegate.Invoke(args)
{
if(this.Object==null)return;
var cid=Delegate.Coll.Insert(this,args);
var strArguments="";
var i=0;
for(i=0;i<args.length;i++)
{
strArguments+="Delegate.Coll['"+cid+"'].Arguments["+i+"]";
if(i<args.length-1)strArguments+=",";
}
i+=2;
if(i>2&&i<this.Arguments.length)strArguments+=",";
for(;i>1&&i<this.Arguments.length;i++)
{
strArguments+="Delegate.Coll['"+cid+"'].Delegate.Arguments["+i+"]";
if(i<this.Arguments.length-1)strArguments+=",";
} var funcName=this.FuncName||cid;
if(this.FuncName==null)this.Object[funcName]=this.Function;
var res;
var exception;
try
{
res=eval("Delegate.Coll['"+cid+"'].Delegate.Object['"+funcName+"']("+strArguments+")");
}catch(x){exception=x}
if(this.Object&&(this.FuncName==null))delete this.Object[funcName];
Delegate.Coll.Remove(cid);
if(exception)throw(exception);
return res;
}
function Delegate.Detach()
{
this.Object=null;
this.Function=null;
this.FuncName=null;
this.UniqueName=null;
}
function Delegate.EvalCaller(delegate,args,cid)
{
this.Delegate=delegate;
this.Arguments=args;
this.CallID=cid;
}
function Delegate.Coll(){}
function Delegate.Coll.Insert(delegate,args)
{
var cid=delegate.UniqueName+"call"+Math.floor((new Date().getTime()+Math.random())*1000);
var EvalCaller=new Delegate.EvalCaller(delegate,args,cid);
Delegate.Coll[cid]=EvalCaller;
return cid;
}
function Delegate.Coll.Remove(cid)
{
delete Delegate.Coll[cid];
}