/*
 * jQuery UI Throbber 0.1
 *
 * Copyright (c) 2009 Jeremy Lea <reg@openpave.org>
 * Dual licensed under the MIT and GPL licenses.
 *
 * http://docs.jquery.com/Licensing
 *
 * Based loosely on the Raphael spinner demo.
 */
(function($){

// Set up IE for VML if we have not done so already...
if ($.browser.msie) {
	// IE6 background flicker fix
	try	{
		document.execCommand("BackgroundImageCache", false, true);
	} catch (e) {}

	if (!document.namespaces["v"]) {
		$("head").prepend("<xml:namespace ns='urn:schemas-microsoft-com:vml' prefix='v' />");
		$("head").prepend("<?import namespace='v' implementation='#default#VML' ?>");
	}
}

$.widget("ui.throbber", {
	_init: function() {

		var o = this.options, e = this.element, a, i, w, tmp;

		if ($.browser.msie) {
			this.element[0].insertAdjacentHTML("afterBegin",
				"<v:group></v:group>");
			this._wrapper = this.element[0].firstChild;
			this._wrapper.addBehavior("#default#VML");
			this._wrapper.coordorigin = "-100 -100";
			this._wrapper.coordsize = "200 200";
			this._wrapper.style.display = "inline-block";
			this._wrapper.style.position = "absolute";
			w = Math.min(e.innerWidth(),e.innerHeight());
			this._wrapper.style.left = (e.innerWidth()-w)/2;
			this._wrapper.style.top = (e.innerHeight()-w)/2;
			this._wrapper.style.width = w;
			this._wrapper.style.height = w;
			this._wrapper.insertAdjacentHTML("afterBegin",
				"<v:roundrect arcsize='"+o.bgcorner/200+"'></v:roundrect>");
			tmp = this._wrapper.childNodes[0];
			tmp.addBehavior("#default#VML");
			tmp.fillcolor = o.bgcolor;
			tmp.stroked = "false";
			tmp.style.top = "-100";
			tmp.style.left = "-100";
			tmp.style.width = "200";
			tmp.style.height = "200";
			tmp.insertAdjacentHTML("afterBegin","<v:fill></v:fill>");
			tmp.firstChild.addBehavior("#default#VML");
			tmp.firstChild.opacity = o.bgopacity;
			this._wrapper.insertAdjacentHTML("beforeEnd",
				"<v:group></v:group>");
			tmp = this._wrapper.childNodes[1];
			tmp.addBehavior("#default#VML");
			tmp.style.top = "-100";
			tmp.style.left = "-100";
			tmp.style.width = "200";
			tmp.style.height = "200";
			tmp.style.rotation = "0";
			for (i = 0; i < o.segments; ++i) {
				a = -i*360/o.segments;
				this._wrapper.childNodes[1].insertAdjacentHTML("beforeEnd",
					"<v:shape></v:shape>");
				tmp = this._wrapper.childNodes[1].childNodes[i];
				tmp.addBehavior("#default#VML");
				tmp.stroked = "false";
				tmp.fillcolor = o.fgcolor;
				tmp.style.top = "-100";
				tmp.style.left = "-100";
				tmp.style.width = "200";
				tmp.style.height = "200";
				tmp.style.rotation = a;
				tmp.path = o.path(i,o.segments)
					.replace(/[mlcz]/g, function(s) {
						switch (s) {
						case "m": return "t";
						case "l": return "r";
						case "c": return "v";
						case "z": return "x";
						}
					}) + " e";
				tmp.insertAdjacentHTML("afterBegin","<v:fill></v:fill>");
				tmp.firstChild.addBehavior("#default#VML");
				tmp.firstChild.opacity = o.opacity(i,o.segments);
			}
		} else {
			var NS = "http://www.w3.org/2000/svg";
			this._wrapper = this.element[0].insertBefore(
				document.createElementNS(NS,"svg"),this.element[0].firstChild);
			tmp = this._wrapper;
			tmp.setAttribute("viewBox","-100 -100 200 200");
			tmp.style.position = "absolute";
			tmp.style.width = "100%";
			tmp.style.height = "100%";
			tmp = this._wrapper.appendChild(
				document.createElementNS(NS,"rect"));
			tmp.setAttribute("x","-100px");
			tmp.setAttribute("y","-100px");
			tmp.setAttribute("width","200px");
			tmp.setAttribute("height","200px");
			tmp.setAttribute("rx",o.bgcorner);
			tmp.setAttribute("fill",o.bgcolor);
			tmp.setAttribute("fill-opacity",o.bgopacity);
			tmp = this._wrapper.appendChild(document.createElementNS(NS,"g"));
			tmp.setAttribute("fill",o.fgcolor);
			for (i = 0; i < o.segments; ++i) {
				a = -i*360/o.segments;
				tmp = this._wrapper.childNodes[1]
					.appendChild(document.createElementNS(NS,"path"));
				tmp.setAttribute("d",o.path(i,o.segments));
				tmp.setAttribute("fill-opacity",o.opacity(i,o.segments));
				tmp.setAttribute("transform","rotate("+a+")");
			}
		}
	},
	destroy: function() {
		this._wrapper.remove();

		$.widget.prototype.destroy.apply(this, arguments);
	},
	reset: function() {
		this._pos = -1;
		this._update();
	},

	_timer: false,
	_setData: function(key, value) {
		var self = this, o = this.options;

		this.options[key] = value;
		if (key == "disabled") {
			if (!value) {
				if (this._timer) {
					this._timer = clearInterval(this._timer);
				}
				this._timer = setInterval(function() {
					self._update();
				}, 1000/this.options.segments/this.options.speed);
				if (o.show) {
					o.show.call(this.element);
				}
			} else {
				if (!o.hide) {
					o.hide = function(callback) { callback(); };
				}
				o.hide.call(this.element, function() {
					if (self._timer) {
						self._timer = clearInterval(self._timer);
					}
				});
			}
		}
	},
	_pos: 0,
	_update: function() {
		var o = this.options;
		this._pos = (this._pos+1)%o.segments;
		var a = this._pos*360/o.segments;
		if ($.browser.msie) {
			this._wrapper.childNodes[1].disabled = true;
			this._wrapper.childNodes[1].rotation = a;
			this._wrapper.childNodes[0].rotation = 0; // rendering bug in 6&7
			this._wrapper.childNodes[1].disabled = false;
		} else {
			this._wrapper.childNodes[1]
				.setAttribute("transform","rotate("+a+")");
		}
	}
});
$.ui.throbber.defaults = {
	bgcolor: "#F00",
	bgopacity: 0.1,
	bgcorner: 10,
	fgcolor: "#000",
	segments: 12,
	path: function(i, segments) {
		return "M 40,8 c -4,0 -8,-4 -8,-8 c 0,-4 4,-8 8,-8 " +
			"l "+(30-i)+",0 c 4,0 8,4 8,8 c 0,4 -4,8 -8,8 " +
			"l -"+(30-i)+",0 z";
	},
	opacity: function(i, segments) {
		return Math.cos(Math.PI/2*(i%segments)/segments);
	},
	speed: 1
};

})(jQuery);

