ratingExtension = {
	// makes element the rating controller
	// ratingCeil - maximum rating value
	// [ratingStep] - rating values step, 1 is default
	// [clickHandler] - onclick event function
	ratingController: function(ratingCeil,ratingStep,clickHandler) {
		// enable ranking
		this.ratingEnabled(true);
		// set parameters
		if (typeof ratingStep != 'undefined') {
			ratingStep = 1;
		}
		this.data('_ratingCeil',ratingCeil);
		this.data('_ratingStep',ratingStep);

		// display total ranking on mouse over and out
		this.bind('mouseover mouseout',function() {
			$(this).ratingShow();
		});
		// mouse over interaction if rating is enabled
		this.bind('mousemove',function(e) {
			if (!$(this).ratingEnabled()) {
				return;
			}
			var relMouseX = e.pageX - $(this).offset().left;

			var ratingExact = relMouseX / $(this).width() * $(this).data('_ratingCeil');
			var ratingStep = $(this).data('_ratingStep');
			var ratingOutput = Math.ceil(ratingExact / ratingStep) * ratingStep;

			$(this).data('_userRatingCurrent',ratingOutput);
			$(this).ratingShow(true,ratingOutput);
		});
		// onclick user rating if enabled
		this.click(function() {
			if ($(this).ratingEnabled() && typeof $(this).data('_userRatingCurrent') != 'undefined') {
				// save user rating
				$(this).ratingValue(true,$(this).data('_userRatingCurrent'));
			}
		});
		// onclick handler
		if (typeof clickHandler != 'undefined') {
			this.click(clickHandler);
		}
	},
	// set rating enabled/disabled or get current state
	// [enabled] - whether ranking should be disabled (false) enabled (true)
	ratingEnabled: function(enabled) {
		if (typeof enabled == 'undefined') {
			return $(this).data('_userRatingEnabled');
		} else {
			$(this).data('_userRatingEnabled',enabled);
			if (enabled) {
				$(this).css('cursor','pointer');
			} else {
				$(this).css('cursor','default');
			}
		}
	},
	// get or set a rating value
	// [userRating] - whether work with user rating (otherwise works with total rating); false if default
	// [ratingValue] - ranking value to be set
	ratingValue: function(userRating,ratingValue) {
		if (typeof userRating == 'undefined') {
			userRating = false;
		}
		if (typeof ratingValue != 'undefined') {
			if (userRating) {
				$(this).data('_userRatingValue', ratingValue);
			} else {
				$(this).data('_ratingValue', ratingValue);
			}
		} else {
			if (userRating) {
				return $(this).data('_userRatingValue');
			} else {
				return $(this).data('_ratingValue');
			}
		}
	},
	// display a rating value
	// [userRating] - whether display user ranking (true), or total ranking (false); false is default
	// [ratingValue] - value to be displayed, if not set it´s loaded from memory
	ratingShow: function(userRating,ratingValue) {
		var ratingStep = 1;
		if (typeof userRating == 'undefined') {
			userRating = false;
		}
		// if rating value is not defined, load from memory
		if (typeof ratingValue == 'undefined') {
			do {
				if (userRating && typeof $(this).data('_userRatingValue') != 'undefined') {
					ratingValue = $(this).data('_userRatingValue');
					break;
				} else if (typeof $(this).data('_ratingValue') != 'undefined') {
					ratingValue = $(this).data('_ratingValue');
					break;
				}
				ratingValue = 0;
			} while (0);
		}
		if (typeof $(this).data('_ratingStep') != 'undefined') {
			ratingStep = $(this).data('_ratingStep');
		}
		// display the value
		var bgPartNum = Math.ceil(ratingValue / ratingStep) + 1;
		var bgPosX = 0;
		var bgPosY = -(bgPartNum-1) * $(this).height();
		if (userRating) {
			bgPosX = -$(this).width();
		}
		$(this).css('background-position',bgPosX + 'px ' + bgPosY + 'px');
	}
}
$.fn.extend(ratingExtension);