jQuery.fn.throbber = function(o) {
	return new jQuery.throbber(this, o);
	};

jQuery.throbber = function(e, o) {
	var publ = this;
	publ.scope = function() { return priv.scope };
	publ.on = function() { return priv.on };
	publ.start = function() { priv.start() };
	publ.stop = function() { priv.stop() };
	publ.show = function() { priv.show() };
	publ.hide = function() { priv.hide() };
	
	var priv = {
		o: {
			speed: 100,
			frames: 12,
			src: 'images/throbber.png',
			width: 32,
			height: 32
			},
		
		scope: null,
		on: false,
		interval: null,
		frame: 0,
		inner: null,
		
		init: function(e, o) {
			if(o) jQuery.extend(priv.o, o);
			
			var s = priv.scope = jQuery(e);
			s.css('overflow', 'hidden');
			if(s.css('position') != 'relative') s.css('position', 'absolute');
			s.width(priv.o.width);
			s.height(priv.o.height);
			s.empty();
			
			var i = priv.inner = $('<div></div>');
			i.css({
				position: 'absolute',
				top: 0,
				left: 0
				});
			i.width(priv.o.width * priv.o.frames);
			i.height(priv.o.height);
			if($.browser.msie) {
				i.css('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+priv.o.src+"',sizingMethod='scale')");
				}
			else {
				i.css('background', 'url('+priv.o.src+') no-repeat top left');
				}
			i.appendTo(s);
			},
		
		start: function() {
			if(priv.on) return;
			priv.on = true;
			if(priv.interval !== null) clearInterval(priv.interval);
			priv.interval = setInterval(priv.onAnimate, priv.o.speed);
			},
		
		show: function() {
			priv.start();
			priv.scope.show();
			},
		
		stop: function() {
			if(!priv.on) return;
			priv.on = false;
			if(priv.interval !== null) clearInterval(priv.interval);
			priv.interval = null;
			},
		
		hide: function() {
			priv.scope.hide();
			priv.stop();
			},
		
		onAnimate: function() {
			priv.frame = (priv.frame + 1) % priv.o.frames;
			priv.inner.css('left', (priv.frame * -priv.o.width)+'px');
			}
		
		};
	
	priv.init(e, o);
	};
