﻿/**
* jQueryCS144.timers - Timer abstractions for jQuery
* Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
* Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
* Date: 2009/10/16
*
* @author Blair Mitchelmore
* @version 1.2
*
**/

jQueryCS144.fn.extend({
    everyTime: function (interval, label, fn, times) {
        return this.each(function () {  jQueryCS144.timer.add(this, interval, label, fn, times); });
    },
    oneTime: function (interval, label, fn) {
        return this.each(function () { jQueryCS144.timer.add(this, interval, label, fn, 1);  });
    },
    stopTime: function (label, fn) {
        return this.each(function () {  jQueryCS144.timer.remove(this, label, fn);  });
    }
});

jQueryCS144.extend({
    timer: {
        global: [],  guid: 1,  dataKey: "jQueryCS144.timer",
        regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
        powers: {
            // Yeah this is major overkill...
            'ms': 1,
            'cs': 10,
            'ds': 100,
            's': 1000,
            'das': 10000,
            'hs': 100000,
            'ks': 1000000
        },
        timeParse: function (value) {
            if (value == undefined || value == null)
			 return null;
            var result = this.regex.exec(jQueryCS144.trim(value.toString()));
            if (result[2]) {  var num = parseFloat(result[1]);  var mult = this.powers[result[2]] || 1;  return num * mult;
            } else { return value; }
        },
        add: function (element, interval, label, fn, times) {
            var counter = 0;

            if (jQueryCS144.isFunction(label)) {
                if (!times)  times = fn; fn = label; label = interval; }

            interval = jQueryCS144.timer.timeParse(interval);

            if (typeof interval != 'number' || isNaN(interval) || interval < 0)
                return;
            if (typeof times != 'number' || isNaN(times) || times < 0)
                times = 0;
            times = times || 0;
            var timers = jQueryCS144.data(element, this.dataKey) || jQueryCS144.data(element, this.dataKey, {});
            if (!timers[label])
                timers[label] = {};

            fn.timerID = fn.timerID || this.guid++;

            var handler = function () {  if ((++counter > times && times !== 0) || fn.call(element, counter) === false)  jQueryCS144.timer.remove(element, label, fn); };
            handler.timerID = fn.timerID; 
            if (!timers[label][fn.timerID]) timers[label][fn.timerID] = window.setInterval(handler, interval); this.global.push(element); 
        },
        remove: function (element, label, fn) {  var timers = jQueryCS144.data(element, this.dataKey), ret;
            if (timers) {
                if (!label) {  for (label in timers)  this.remove(element, label, fn);
                } else if (timers[label]) {
                    if (fn) {  if (fn.timerID) {  window.clearInterval(timers[label][fn.timerID]);  delete timers[label][fn.timerID]; }
                    } else {  for (var fn in timers[label]) { window.clearInterval(timers[label][fn]);  delete timers[label][fn];  }
                    }
                    for (ret in timers[label]) break;
                    if (!ret) { ret = null; delete timers[label];  } }
                for (ret in timers) break;
                if (!ret) jQueryCS144.removeData(element, this.dataKey); }
        }
    }
}); 
jQueryCS144(window).bind("unload", function () { jQueryCS144.each(jQueryCS144.timer.global, function (index, item) { jQueryCS144.timer.remove(item);  }); });
