var Invoker = Class("Invoker", function(thisClass, Super){
    thisClass.prototype.init = function(obj, fn){
        this.obj = obj;
        this.fn = fn;
    }
    
    thisClass.prototype.invoke = function(){
        this.fn.call(this.obj);
    }
})


var Simulator = Class("Simulator", function(thisClass, Super){
    thisClass.prototype.init = function(){
        this.events = new Array();
        this.running = false;
        
    }
    
    thisClass.prototype.run = function(){
        if(this.running == false){
            this.running = true;
            while(this.events.length > 0){
                var invk = this.events.shift();
                if(invk.delay == 0){
                    invk.invoke();
                }else{
                    invk.delay--;
                    this.events.push(invk);
                }
            }
            this.running = false;
        }
    }
     
    
    thisClass.prototype.invokeLater = function(obj, fn, delay){
        for(var i=0;i<this.events.length;i++){
            var invk = this.events[i];
            //check if obj already in list for the same delay
            if(invk.obj == obj && invk.delay == delay){
                return;
            }
        }
        var invk = new Invoker(obj, fn)
        invk.delay=delay;
        this.events.push(invk);
    }
})


var Scheduler = Class("Scheduler", function(thisClass, Super){
    var waiting=new Array();
    thisClass.prototype.register=function(obj, fn, time){
        //generate a new oject for calling obj.fn
        var invoker = new Invoker(obj, fn);
        //generate a new id
        invoker.id = 0;
        for(var i=0;i<waiting.length;i++){
            if (waiting[i].id > invoker.id){
                invoker.id = waiting[i].id;
            }
        }
        invoker.id++;
        //save it in a list
        waiting.push(invoker);
        window.setTimeout("scheduler.exec(" + invoker.id + ")", time);
    }
    
    thisClass.prototype.exec=function(id){
        //find the object to execute
        
        for(var i=0;i<waiting.length;i++){
            if (waiting[i].id == id){
                var invoker = waiting[i];
                //remove it from the list
                waiting.splice(i,1);
                i = waiting.length;
                //execute it
                invoker.invoke();
            }
        }
    }
})

scheduler = new Scheduler();
    

