/**
 * Sprite Rating
 * @author Gary Manfredi
 */
jQuery.fn.srating = function(options){
	
	// default options
	options = jQuery.extend({
	     numSteps: 5,
	     numStars: 5,
	     callback: function(){},
		 tooltip: null,
		 tips:null, // could be an array of strings represent low to high
		 width:16,
		 height:16,
		 rating:0,
		 avgRating:0
	  }, options);
	
	
    return this.each(function(){
        // use "stars" for readability
        var stars = $(this);
		
		// store width & height in stars element for dynamic resizing externally (using $(el).data("size", newVals))
		stars.data("size", { width: options.width, height: options.height });
		
        // set default rating
        var rating = options.rating * (options.numSteps / options.numStars); //normalize to step number
        stars.data("rating", options.rating);
        var avgRating = options.avgRating * (options.numSteps / options.numStars); //normalize to step number
        
		var offset; // used in functions
		
        stars.update = function(){
			// normalize given width according to number of steps (do it every time as as this can be dynamic)
			var w = stars.data("size").width * (options.numStars / options.numSteps);
			
            // if no rating AND an average rating given, show average rating (third set of stars).  Else just show rating
            if (avgRating && rating == 0) {
                stars.css("backgroundPosition", -(w * options.numSteps * 2) + "px -" + (avgRating * stars.data("size").height) + "px");
            }
            else {
                stars.css("backgroundPosition", "0px -" + (rating * stars.data("size").height) + "px");
            }
        };
        
        stars.click(function(e){
			// normalize given width according to number of steps (do it every time as as this can be dynamic)
			var w = stars.data("size").width * (options.numStars / options.numSteps);
			
			// set rating and do callback
            rating = Math.floor((e.pageX - $(this).offset().left) / w) + 1;
            var normalRating = rating / options.numSteps * options.numStars;
       		stars.data("rating", normalRating);
			options.callback(stars, normalRating);
			if (options.tooltip) options.tooltip.hide();
        });
        
        stars.mousemove(function(e){
			// normalize given width according to number of steps (do it every time as as this can be dynamic)
			var w = stars.data("size").width * (options.numStars / options.numSteps);
			
			// get offset to viewport for calc
			offset = $(this).offset();
			
			// show yellow stars
            var n = Math.floor((e.pageX - offset.left) / w) + 1;
            stars.css("backgroundPosition", -(w * options.numSteps) + "px -" + (n * stars.data("size").height) + "px");
			
			// if given a tooltip obj, show it
			if (options.tooltip) {
				// if given tips, use them
				if (options.tips)
					options.tooltip.html(options.tips[n-1]);
				else // use standard message
					options.tooltip.html("Rate it " + (n / options.numSteps * options.numStars) + " stars")
				
				// set position of tooltip
				options.tooltip.css({
						left: offset.left + (n * w) + 10,
						top: offset.top + 20
					}).show();
			}
        });
        
        stars.hover(function(){
        }, function(){
            stars.update();
			if (options.tooltip) options.tooltip.hide();
        });
		
		// show initial
		stars.update();
        
    });
};

