jQuery.extend({

	fjFunctionQueue: function(funcToQue) {

		if (funcToQue == null) {

			if (jQuery.fjFunctionQueue.queue != null && jQuery.fjFunctionQueue.queue.queue.length > 0) {

				if (jQuery.fjFunctionQueue.queue.running) {

					jQuery.fjTimer({

						interval: jQuery.fjFunctionQueue.queue.properties.interval,

						tick: function(counter, timer) {

							var func = jQuery.fjFunctionQueue.queue.queue.shift();

							try {

								jQuery.fjFunctionQueue.queue.properties.onTick(jQuery.fjFunctionQueue.queue.index, func);

								jQuery.fjFunctionQueue.queue.index++;

							} catch (e) {

								jQuery.fjFunctionQueue();

								throw e;

							}

							if (jQuery.fjFunctionQueue.queue.queue.length > 0) {

								jQuery.fjFunctionQueue();

							} else {

								jQuery.fjFunctionQueue.queue.running = false;

								jQuery.fjFunctionQueue.queue.index = 0;

								jQuery.fjFunctionQueue.queue.properties.onComplete();

							}

						}

					});

				} else {

					jQuery.fjFunctionQueue.queue.running = true;

					jQuery.fjFunctionQueue();

				}

			}

		} else {

			if (jQuery.fjFunctionQueue.queue == null) {

				jQuery.fjFunctionQueue.queue = {index: 0, running: false, queue:[], properties: {interval: 1, onComplete: function(){}, onStart: function(){}, autoStart: true, onTick: function(counter, func) {func();}}};

			}

			var isEmptyArray = jQuery.fjFunctionQueue.queue.queue.length == 0;

			if (jQuery.isFunction(funcToQue)) {

				jQuery.fjFunctionQueue.queue.queue.push(funcToQue);

			} else if (jQuery.isArray(funcToQue)) {

				for(var i = 0; i < funcToQue.length; i++) {

					jQuery.fjFunctionQueue.queue.queue.push(funcToQue[i]);

				}

			} else {

				jQuery.fjFunctionQueue.queue.properties = jQuery.extend(jQuery.fjFunctionQueue.queue.properties, funcToQue);

			}

			if (isEmptyArray && jQuery.fjFunctionQueue.queue.queue.length > 0 && !jQuery.fjFunctionQueue.queue.running && jQuery.fjFunctionQueue.queue.properties.autoStart) {

				jQuery.fjFunctionQueue.queue.running = true;

				jQuery.fjFunctionQueue.queue.properties.onStart();

				jQuery.fjFunctionQueue.queue.running = false;

				jQuery.fjFunctionQueue();

			}

		}

	},

	fjTimer : function(properties) {

	    properties = jQuery.extend({interval: 10, tick: function(){}, repeat: false, random :false, onComplete: function(){}, step: 1}, properties);

	    var counter = 0;

	    var timer = new function() {

	    	this.timerId = null;

	    	this.stop = function() {

	    		clearInterval(this.timerId);

	    	}

	    }

	    timer.timerId = setInterval(function() {

	    	try {

	    		properties.tick(counter, timer);

	    		counter+=properties.step;

	    	} catch (e) {

	    		alert(e);

	    	}

	    	if (properties.repeat !== true && ((properties.repeat * properties.step) <= counter || properties.repeat === false)) {

	    		timer.stop();

	    		properties.onComplete();

	    	}

	    }, properties.interval);

	},

	fjTimerEach: function(properties) {

		var ___array = properties.array;

		var ___callback = properties.tick;

		properties.repeat = ___array.length;

		if (properties.step != null) {

			properties.repeat = Math.ceil(___array.length / parseInt(properties.step, 10));

		}

		properties.tick = function(counter, timer) {

			___callback(counter, ___array[counter]);

		}

		jQuery.fjTimer(properties);

	}

});

