/* Copyright (c) 2008 Gilberto Saraiva (saraivagilberto@gmail.com || http://gsaraiva.projects.pro.br)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Version: 2008.0.1.1 -
 * Under development and testing
 *
 * Requires: jQuery 1.2+
 *
 * Support/Site: http://gsaraiva.projects.pro.br/openprj/?page=jqueryanimator
 */

(function( $ ){
  // Anyone missed this basic?
  $.extend( $ , {
    now: function(){
      return +new Date;
    }
  });

  // Extend jQuery.timers to provide a better handler
	$.extend( $.timers , {
    // Active the timers on the jQuery way
    run: function(){
      if(jQuery.timerId == null){
        jQuery.timerId = setInterval(function(){
          var timers = jQuery.timers;

          for(var i = 0; i < timers.length; i++){
            if(!timers[i]())
              jQuery.timers.splice(i--, 1);
          }

          if(!timers.length){
            clearInterval(jQuery.timerId);
            jQuery.timerId = null;
          }
        }, 13);
      }
    },
    // No end call, no respect clean and end process
    cleanAll: function(){
      jQuery.timers = [];
      clearInterval(jQuery.timerId);
      jQuery.timerId = null;
    },
    // Add a timer callback on the jQuery timers list
    addTimer: function(timer, autostart){
      this.push(timer);
      if(autostart)
        this.run();
    }
  });

  $.fn.extend({
    // Create a animator to your callback, can't create more then one for the same query
    animator: function(speed, callback){
      this.animatorData = {
        interval: speed,
        last: jQuery.now() - speed,
        call: callback
      };

      var self = this;
      function Interact(gotoEnd){
        return self.animatorInteract(gotoEnd);
      }

      // add the animator time
      jQuery.timers.addTimer(Interact, true);
    },
    
    // the interactor for check interval and the endcall (gotoEnd)
    animatorInteract: function(gotoEnd){
      var data = this.animatorData;
      if(data.last + data.interval <= $.now()){
        this.animatorData.last = $.now();
        return data.call(this, gotoEnd);
      }else if(gotoEnd){
        data.call(this, gotoEnd);
        return false;
      }else{
        return true;
      }
    }
  });
})( jQuery );