/**
 * @class Ext.util.TaskRunner
 * Provides the ability to execute one or more arbitrary tasks in a multithreaded
 * manner.  Generally, you can use the singleton {@link Ext.TaskMgr} instead, but
 * if needed, you can create separate instances of TaskRunner.  Any number of
 * separate tasks can be started at any time and will run independently of each
 * other. Example usage:
 *

// Start a simple clock task that updates a div once per second
var updateClock = function(){
    Ext.fly('clock').update(new Date().format('g:i:s A'));
}
var task = {
    run: updateClock,
    interval: 1000 //1 second
}
var runner = new Ext.util.TaskRunner();
runner.start(task);

// equivalent using TaskMgr
Ext.TaskMgr.start({
    run: updateClock,
    interval: 1000
});

 *

 * Also see {@link Ext.util.DelayedTask}.
 *
 * @constructor
 * @param {Number} interval (optional) The minimum precision in milliseconds supported by this TaskRunner instance
 * (defaults to 10)
 */

Ext.util.TaskRunner = function(interval){
    interval
= interval || 10;
   
var tasks = [],
        removeQueue
= [],
        id
= 0,
        running
= false,

       
// private
        stopThread
= function(){
                running
= false;
                clearInterval
(id);
                id
= 0;
           
},

       
// private
        startThread
= function(){
               
if(!running){
                    running
= true;
                    id
= setInterval(runTasks, interval);
               
}
           
},

       
// private
        removeTask
= function(t){
                removeQueue
.push(t);
               
if(t.onStop){
                    t
.onStop.apply(t.scope || t);
               
}
           
},
           
       
// private
        runTasks
= function(){
               
var rqLen = removeQueue.length,
                        now
= new Date().getTime();                                            
           
               
if(rqLen > 0){
                   
for(var i = 0; i < rqLen; i++){
                        tasks
.remove(removeQueue[i]);
                   
}
                    removeQueue
= [];
                   
if(tasks.length < 1){
                        stopThread
();
                       
return;
                   
}
               
}              
               
for(var i = 0, t, itime, rt, len = tasks.length; i < len; ++i){
                    t
= tasks[i];
                    itime
= now - t.taskRunTime;
                   
if(t.interval <= itime){
                        rt
= t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
                        t
.taskRunTime = now;
                       
if(rt === false || t.taskRunCount === t.repeat){
                            removeTask
(t);
                           
return;
                       
}
                   
}
                   
if(t.duration && t.duration <= (now - t.taskStartTime)){
                        removeTask
(t);
                   
}
               
}
           
};

   
/**
     * Starts a new task.
     * @method start
     * @param {Object} task A config object that supports the following properties:

     * @return {Object} The task
     */

   
this.start = function(task){
        tasks
.push(task);
        task
.taskStartTime = new Date().getTime();
        task
.taskRunTime = 0;
        task
.taskRunCount = 0;
        startThread
();
       
return task;
   
};

   
/**
     * Stops an existing running task.
     * @method stop
     * @param {Object} task The task to stop
     * @return {Object} The task
     */

   
this.stop = function(task){
        removeTask
(task);
       
return task;
   
};

   
/**
     * Stops all tasks that are currently running.
     * @method stopAll
     */

   
this.stopAll = function(){
        stopThread
();
       
for(var i = 0, len = tasks.length; i < len; i++){
           
if(tasks[i].onStop){
                tasks
[i].onStop();
           
}
       
}
        tasks
= [];
        removeQueue
= [];
   
};
};

/**
 * @class Ext.TaskMgr
 * @extends Ext.util.TaskRunner
 * A static {@link Ext.util.TaskRunner} instance that can be used to start and stop arbitrary tasks.  See
 * {@link Ext.util.TaskRunner} for supported methods and task config properties.
 *

// Start a simple clock task that updates a div once per second
var task = {
    run: function(){
        Ext.fly('clock').update(new Date().format('g:i:s A'));
    },
    interval: 1000 //1 second
}
Ext.TaskMgr.start(task);

 * @singleton
 */

Ext.TaskMgr = new Ext.util.TaskRunner();