//
// rating Plugin
// By Chris Richards
//
// Turns a select box into a star rating control.
//

//Keeps '$' pointing to the jQuery version
(function ($) { 
	
	$.fn.rating = function(options)
	{
		//
		// Settings
		//
		var settings =
		{
			showCancel: true,
			cancelValue: null,
			startValue: null
		};
		$.extend(settings, options);
		
		//
		// Events API
		//
		var events =
		{
			hoverOver: function(evt)
			{
				var elm = $(evt.target);
				
				//Are we over the Cancel or the star?
				if( elm.hasClass("ui-rating-cancel") )
				{
					elm.addClass("ui-rating-cancel-full");
				} 
				else 
				{
					elm.prevAll().andSelf()
						.not(".ui-rating-cancel")
						.addClass("ui-rating-hover");
				}
			},
			hoverOut: function(evt)
			{
				var elm = $(evt.target);
				//Are we over the Cancel or the star?
				if( elm.hasClass("ui-rating-cancel") )
				{
					elm.addClass("ui-rating-cancel-empty")
						.removeClass("ui-rating-cancel-full");
				}
				else
				{
					elm.prevAll().andSelf()
						.not(".ui-rating-cancel")
						.removeClass("ui-rating-hover");
				}
			},
			click: function(evt)
			{
				var elm = $(evt.target);
				var value = settings.cancelValue;
				//Are we over the Cancel or the star?
				if( elm.hasClass("ui-rating-cancel") )
				{
					//Clear all of the stars
					events.empty(elm);
				}
				else
				{
					//Set us, and the stars before us as full
					elm.closest(".ui-rating-star").prevAll().andSelf()
						.not(".ui-rating-cancel")
						.attr("className", "ui-rating-star ui-rating-full");
					//Set the stars after us as empty 
					elm.closest(".ui-rating-star").nextAll()
						.not(".ui-rating-cancel")
						.attr("className", "ui-rating-star ui-rating-empty");
					//Uncheck the cancel
					elm.siblings(".ui-rating-cancel")
						.attr("className", "ui-rating-cancel ui-rating-cancel-empty");
					//Use our value
					value = elm.attr("value");
				}
				
				//Set the select box to the new value
				if( !evt.data.hasChanged )
				{
					$(evt.data.selectBox).val( value ).trigger("change");
				}
			},
			change: function(evt)
			{
				var value =  $(this).val();
				events.setValue(value, evt.data.container, evt.data.selectBox);
			},
			setValue: function(value, container, selectBox)
			{
				//Set a new target and let the method know the select has already changed.
				var evt = {"target": null, "data": {}};
				evt.target = $(".ui-rating-star[value="+ value +"]", container);
				evt.data.selectBox = selectBox;
				evt.data.hasChanged = true;
				events.click(evt);
			},
			empty: function(elm)
			{
				//Clear all of the stars
				elm.attr("className", "ui-rating-cancel ui-rating-cancel-empty")
					.nextAll().attr("className", "ui-rating-star ui-rating-empty");
			}
		};
		
		//
		// HTML API
		//
		var HTML =
		{
			// Creates the holding container for the rating control
			createContainer: function(elm)
			{
				var div = $("<div/>").attr({
	                title: elm.title,
	                className: "ui-rating"
	            }).insertAfter( elm );
				return div;
			},
			// Creates a Star
			createStar: function(elm, div)
			{
				$("<a/>").attr({
					className: "ui-rating-star ui-rating-empty",
					title: $(elm).text(),
					value: elm.value
				}).appendTo(div);
			},
			// Create the Cancel Button
			createCancel: function(elm, div)
			{
				$("<a/>").attr({
					className: "ui-rating-cancel ui-rating-cancel-empty",
					title: "Cancel"
				}).appendTo(div);
			}
		};
		
		//
		// Process the matched elements
		//
		return this.each(function(){
			//We only do select types
			if( $(this).attr("type") !== "select-one" ) { return; }
			//Save 'this' for ease of development
			var selectBox = this;
			//Hide the selectBox
			$(selectBox).css("display", "none");
			//Does it have an ID? if not generate one
			var id = $(selectBox).attr("id");
			if( "" === id ) { id = "ui-rating-" + $.data(selectBox); $(selectBox).attr("id", id); }
			
			//Create the holding container
			var div = HTML.createContainer(selectBox);
			//Bind our events to the container
			$(div).bind("mouseover", events.hoverOver)
				.bind("mouseout", events.hoverOut)
				.bind("click",{"selectBox": selectBox}, events.click);
			
			//Should we create the Cancel button?
			if( settings.showCancel )
			{
				HTML.createCancel(this, div);
			}
			
			//Now loop over every option in the select box.
			$("option", selectBox).each(function(){
				//Create a Star
				HTML.createStar(this, div);
			});
			
			//Is there an element with the select option set?
			if( 0 !== $("#" + id + " option[selected]").size() ) 
			{
				//Set the Starting Value
				events.setValue( $(selectBox).val(), div, selectBox );
			} else {
				//Use a start value if we have it, otherwise use the cancel value.
				var val = null !== settings.startValue ? settings.startValue : settings.cancelValue;
				events.setValue( val, div, selectBox );
				//Make sure the selectbox knows our desision
				$(selectBox).val(val);
			}
			//Update the stars if the selectbox value changes.
			
			$(this).bind("change", {"selectBox": selectBox, "container": div},  events.change);
		});
		
	};

})(jQuery);


jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
