(function(A) {
	A.widget("ui.stars", {
		options : {
			inputType : "radio",
			split : 0,
			disabled : false,
			cancelTitle : "Cancel Rating",
			cancelValue : 0,
			cancelShow : true,
			disableValue : true,
			oneVoteOnly : false,
			showTitles : false,
			captionEl : null,
			callback : null,
			starWidth : 16,
			cancelClass : "ui-stars-cancel",
			starClass : "ui-stars-star",
			starOnClass : "ui-stars-star-on",
			starHoverClass : "ui-stars-star-hover",
			starDisabledClass : "ui-stars-star-disabled",
			cancelHoverClass : "ui-stars-cancel-hover",
			cancelDisabledClass : "ui-stars-cancel-disabled"
		},
		_create : function() {
			var C = this, F = this.options, B = 0;
			this.element.data("former.stars", this.element.html());
			F.isSelect = F.inputType == "select";
			this.$form = A(this.element).closest("form");
			this.$selec = F.isSelect ? A("select", this.element) : null;
			this.$rboxs = F.isSelect ? A("option", this.$selec) : A(":radio", this.element);
			this.$stars = this.$rboxs.map(function(I) {
				var J = {
					value : this.value,
					title : (F.isSelect ? this.text : this.title) || this.value,
					isDefault : (F.isSelect && this.defaultSelected) || this.defaultChecked
				};
				if(I == 0) {
					F.split = typeof F.split != "number" ? 0 : F.split;
					F.val2id = [];
					F.id2val = [];
					F.id2title = [];
					F.name = F.isSelect ? C.$selec.get(0).name : this.name;
					F.disabled = F.disabled || (F.isSelect ? A(C.$selec).attr("disabled") : A(this).attr("disabled"))
				}
				if(J.value == F.cancelValue) {
					F.cancelTitle = J.title;
					return null
				}
				F.val2id[J.value] = B;
				F.id2val[B] = J.value;
				F.id2title[B] = J.title;
				if(J.isDefault) {
					F.checked = B;
					F.value = F.defaultValue = J.value;
					F.title = J.title
				}
				var H = A("<div/>").addClass(F.starClass);
				var K = A("<a/>").attr("title", F.showTitles ? J.title : "").text(J.value);
				if(F.split) {
					var G = (B % F.split);
					var L = Math.floor(F.starWidth / F.split);
					H.width(L);
					K.css("margin-left", "-" + (G * L) + "px")
				}
				B++;
				return H.append(K).get(0)
			});
			F.items = B;
			F.isSelect ? this.$selec.remove() : this.$rboxs.remove();
			this.$cancel = A("<div/>").addClass(F.cancelClass).append(A("<a/>").attr("title", F.showTitles ? F.cancelTitle : "").text(F.cancelValue));
			F.cancelShow &= !F.disabled && !F.oneVoteOnly;
			F.cancelShow && this.element.append(this.$cancel);
			this.element.append(this.$stars);
			if(F.checked === undefined) {
				F.checked = -1;
				F.value = F.defaultValue = F.cancelValue;
				F.title = ""
			}
			this.$value = A("<input type='hidden' name='" + F.name + "' value='" + F.value + "' />");
			this.element.append(this.$value);
			this.$stars.bind("click.stars", function(H) {
				if(!F.forceSelect && F.disabled) {
					return false
				}
				var G = C.$stars.index(this);
				F.checked = G;
				F.value = F.id2val[G];
				F.title = F.id2title[G];
				C.$value.attr({
					disabled : F.disabled ? "disabled" : "",
					value : F.value
				});
				D(G, false);
				C._disableCancel();
				!F.forceSelect && C.callback(H, "star")
			}).bind("mouseover.stars", function() {
				if(F.disabled) {
					return false
				}
				var G = C.$stars.index(this);
				D(G, true)
			}).bind("mouseout.stars", function() {
				if(F.disabled) {
					return false
				}D(C.options.checked, false)
			});
			this.$cancel.bind("click.stars", function(G) {
				if(!F.forceSelect && (F.disabled || F.value == F.cancelValue)) {
					return false
				}
				F.checked = -1;
				F.value = F.cancelValue;
				F.title = "";
				C.$value.val(F.value);
				F.disableValue && C.$value.attr({
					disabled : "disabled"
				});
				E();
				C._disableCancel();
				!F.forceSelect && C.callback(G, "cancel")
			}).bind("mouseover.stars", function() {
				if(C._disableCancel()) {
					return false
				}
				C.$cancel.addClass(F.cancelHoverClass);
				E();
				C._showCap(F.cancelTitle)
			}).bind("mouseout.stars", function() {
				if(C._disableCancel()) {
					return false
				}
				C.$cancel.removeClass(F.cancelHoverClass);
				C.$stars.triggerHandler("mouseout.stars")
			});
			this.$form.bind("reset.stars", function() {!F.disabled && C.select(F.defaultValue)
			});
			A(window).unload(function() {
				C.$cancel.unbind(".stars");
				C.$stars.unbind(".stars");
				C.$form.unbind(".stars");
				C.$selec = C.$rboxs = C.$stars = C.$value = C.$cancel = C.$form = null
			});
			function D(G, I) {
				if(G != -1) {
					var J = I ? F.starHoverClass : F.starOnClass;
					var H = I ? F.starOnClass : F.starHoverClass;
					C.$stars.eq(G).prevAll("." + F.starClass).andSelf().removeClass(H).addClass(J);
					C.$stars.eq(G).nextAll("." + F.starClass).removeClass(F.starHoverClass + " " + F.starOnClass);
					C._showCap(F.id2title[G])
				} else {E()
				}
			}

			function E() {
				C.$stars.removeClass(F.starOnClass + " " + F.starHoverClass);
				C._showCap("")
			}
			this.select(F.value);
			F.disabled && this.disable()
		},
		_disableCancel : function() {
			var C = this.options, B = C.disabled || C.oneVoteOnly || (C.value == C.cancelValue);
			if(B) {
				this.$cancel.removeClass(C.cancelHoverClass).addClass(C.cancelDisabledClass)
			} else {
				this.$cancel.removeClass(C.cancelDisabledClass)
			}
			this.$cancel.css("opacity", B ? 0.5 : 1);
			return B
		},
		_disableAll : function() {
			var B = this.options;
			this._disableCancel();
			if(B.disabled) {
				this.$stars.filter("div").addClass(B.starDisabledClass)
			} else {
				this.$stars.filter("div").removeClass(B.starDisabledClass)
			}
		},
		_showCap : function(B) {
			var C = this.options;
			if(C.captionEl) {
				C.captionEl.text(B)
			}
		},
		value : function() {
			return this.options.value
		},
		select : function(D) {
			var C = this.options, B = (D == C.cancelValue) ? this.$cancel : this.$stars.eq(C.val2id[D]);
			C.forceSelect = true;
			B.triggerHandler("click.stars");
			C.forceSelect = false
		},
		selectID : function(D) {
			var C = this.options, B = (D == -1) ? this.$cancel : this.$stars.eq(D);
			C.forceSelect = true;
			B.triggerHandler("click.stars");
			C.forceSelect = false
		},
		enable : function() {
			this.options.disabled = false;
			this._disableAll()
		},
		disable : function() {
			this.options.disabled = true;
			this._disableAll()
		},
		destroy : function() {
			this.$form.unbind(".stars");
			this.$cancel.unbind(".stars").remove();
			this.$stars.unbind(".stars").remove();
			this.$value.remove();
			this.element.unbind(".stars").html(this.element.data("former.stars")).removeData("stars");
			return this
		},
		callback : function(C, B) {
			var D = this.options;
			D.callback && D.callback(this, B, D.value, C);
			D.oneVoteOnly && !D.disabled && this.disable()
		}
	});
	A.extend(A.ui.stars, {
		version : "3.0.1"
	})
})(jQuery);

