/**

* Debounce and throttle function's decorator plugin 1.0.5
*
* Copyright (c) 2009 Filatov Dmitry (alpha@zforms.ru)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/

(function ($) {

$.extend({
  debounce: function (fn, timeout, invokeAsap, ctx) {
    if (arguments.length == 3 && typeof invokeAsap != 'boolean') {
      ctx = invokeAsap;
      invokeAsap = false;
    }

    var timer;
    return function () {

      var args = arguments;
      ctx = ctx || this;

      invokeAsap && !timer && fn.apply(ctx, args);

      clearTimeout(timer);

      timer = setTimeout(function () {
        invokeAsap || fn.apply(ctx, args);
        timer = null;
      }, timeout);
    };
  },

  throttle: function (fn, timeout, ctx) {
    var timer, args, needInvoke;
    return function () {
      args = arguments;
      needInvoke = true;
      ctx = ctx || this;

      timer || (function () {
        if (needInvoke) {
          fn.apply(ctx, args);
          needInvoke = false;
          timer = setTimeout(arguments.callee, timeout);
        }
        else {
          timer = null;
        }
      })();
    };
  }
});

})(jQuery);