

<!--
/*
 ### jQuery Star Rating Plugin v3.12 - 2009-04-16 ###
 * Home: http://www.fyneworks.com/jquery/star-rating/
 * Code: http://code.google.com/p/jquery-star-rating-plugin/
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 ###
*/
/*# AVOID COLLISIONS #*/
;if(window.jQuery) (function($){
/*# AVOID COLLISIONS #*/
 
 // IE6 Background Image Fix
 if ($.browser.msie) try { document.execCommand("BackgroundImageCache", false, true)} catch(e) { };
 // Thanks to http://www.visualjquery.com/rating/rating_redux.html
 
 // plugin initialization
 $.fn.rating = function(options){
  if(this.length==0) return this; // quick fail
  
  // Handle API methods
  if(typeof arguments[0]=='string'){
   // Perform API methods on individual elements
   if(this.length>1){
    var args = arguments;
    return this.each(function(){
     $.fn.rating.apply($(this), args);
    });
   };
   // Invoke API method handler
   $.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
   // Quick exit...
   return this;
  };
  
  // Initialize options for this call
  var options = $.extend(
   {}/* new object */,
   $.fn.rating.options/* default options */,
   options || {} /* just-in-time options */
  );
  
  // Allow multiple controls with the same name by making each call unique
  $.fn.rating.calls++;
  
  // loop through each matched element
  this
   .not('.star-rating-applied')
   .addClass('star-rating-applied')
  .each(function(){
   
   // Load control parameters / find context / etc
   var control, input = $(this);
   var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g,'');
   var context = $(this.form || document.body);
   
   // FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23
   var raters = context.data('rating');
   if(!raters || raters.call!=$.fn.rating.calls) raters = { count:0, call:$.fn.rating.calls };
   var rater = raters[eid];
   
   // if rater is available, verify that the control still exists
   if(rater) control = rater.data('rating');
   
   if(rater && control)//{// save a byte!
    // add star to control if rater is available and the same control still exists
    control.count++;
    
   //}// save a byte!
   else{
    // create new control if first star or control element was removed/replaced
    
    // Initialize options for this raters
    control = $.extend(
     {}/* new object */,
     options || {} /* current call options */,
     ($.metadata? input.metadata(): ($.meta?input.data():null)) || {}, /* metadata options */
     { count:0, stars: [], inputs: [] }
    );
    
    // increment number of rating controls
    control.serial = raters.count++;
    
    // create rating element
    rater = $('<span class="star-rating-control"/>');
    input.before(rater);
    
    // Mark element for initialization (once all stars are ready)
    rater.addClass('rating-to-be-drawn');
    
    // Accept readOnly setting from 'disabled' property
    if(input.attr('disabled')) control.readOnly = true;
    
    // Create 'cancel' button
    rater.append(
     control.cancel = $('<div class="rating-cancel"><a title="' + control.cancel + '">' + control.cancelValue + '</a></div>')
     .mouseover(function(){
      $(this).rating('drain');
      $(this).addClass('star-rating-hover');
      //$(this).rating('focus');
     })
     .mouseout(function(){
      $(this).rating('draw');
      $(this).removeClass('star-rating-hover');
      //$(this).rating('blur');
     })
     .click(function(){
      $(this).rating('select');
     })
     .data('rating', control)
    );
    
   }; // first element of group
   
   // insert rating star
   var star = $('<div class="star-rating rater-'+ control.serial +'"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
   rater.append(star);
   
   // inherit attributes from input element
   if(this.id) star.attr('id', this.id);
   if(this.className) star.addClass(this.className);
   
   // Half-stars?
   if(control.half) control.split = 2;
   
   // Prepare division control
   if(typeof control.split=='number' && control.split>0){
    var stw = ($.fn.width ? star.width() : 0) || control.starWidth;
    var spi = (control.count % control.split), spw = Math.floor(stw/control.split);
    star
    // restrict star's width and hide overflow (already in CSS)
    .width(spw)
    // move the star left by using a negative margin
    // this is work-around to IE's stupid box model (position:relative doesn't work)
    .find('a').css({ 'margin-left':'-'+ (spi*spw) +'px' })
   };
   
   // readOnly?
   if(control.readOnly)//{ //save a byte!
    // Mark star as readOnly so user can customize display
    star.addClass('star-rating-readonly');
   //}  //save a byte!
   else//{ //save a byte!
    // Enable hover css effects
    star.addClass('star-rating-live')
     // Attach mouse events
     .mouseover(function(){
      $(this).rating('fill');
      $(this).rating('focus');
     })
     .mouseout(function(){
      $(this).rating('draw');
      $(this).rating('blur');
     })
     .click(function(){
      $(this).rating('select');
     })
    ;
   //}; //save a byte!
   
   // set current selection
   if(this.checked) control.current = star;
   
   // hide input element
   input.hide();
   
   // backward compatibility, form element to plugin
   input.change(function(){
    $(this).rating('select');
   });
   
   // attach reference to star to input element and vice-versa
   star.data('rating.input', input.data('rating.star', star));
   
   // store control information in form (or body when form not available)
   control.stars[control.stars.length] = star[0];
   control.inputs[control.inputs.length] = input[0];
   control.rater = raters[eid] = rater;
   control.context = context;
   
   input.data('rating', control);
   rater.data('rating', control);
   star.data('rating', control);
   context.data('rating', raters);
  }); // each element
  
  // Initialize ratings (first draw)
  $('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn');
  
  return this; // don't break the chain...
 };
 
 /*--------------------------------------------------------*/
 
 /*
  ### Core functionality and API ###
 */
 $.extend($.fn.rating, {
  // Used to append a unique serial number to internal control ID
  // each time the plugin is invoked so same name controls can co-exist
  calls: 0,
  
  focus: function(){
   var control = this.data('rating'); if(!control) return this;
   if(!control.focus) return this; // quick fail if not required
   // find data for event
   var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
   // focus handler, as requested by focusdigital.co.uk
   if(control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
  }, // $.fn.rating.focus
  
  blur: function(){
   var control = this.data('rating'); if(!control) return this;
   if(!control.blur) return this; // quick fail if not required
   // find data for event
   var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
   // blur handler, as requested by focusdigital.co.uk
   if(control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
  }, // $.fn.rating.blur
  
  fill: function(){ // fill to the current mouse position.
   var control = this.data('rating'); if(!control) return this;
   // do not execute when control is in read-only mode
   if(control.readOnly) return;
   // Reset all stars and highlight them up to this element
   this.rating('drain');
   this.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-hover');
  },// $.fn.rating.fill
  
  drain: function() { // drain all the stars.
   var control = this.data('rating'); if(!control) return this;
   // do not execute when control is in read-only mode
   if(control.readOnly) return;
   // Reset all stars
   control.rater.children().filter('.rater-'+ control.serial).removeClass('star-rating-on').removeClass('star-rating-hover');
  },// $.fn.rating.drain
  
  draw: function(){ // set value and stars to reflect current selection
   var control = this.data('rating'); if(!control) return this;
   // Clear all stars
   this.rating('drain');
   // Set control value
   if(control.current){
    control.current.data('rating.input').attr('checked','checked');
    control.current.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-on');
   }
   else
    $(control.inputs).removeAttr('checked');
   // Show/hide 'cancel' button
   control.cancel[control.readOnly || control.required?'hide':'show']();
   // Add/remove read-only classes to remove hand pointer
   this.siblings()[control.readOnly?'addClass':'removeClass']('star-rating-readonly');
  },// $.fn.rating.draw
  
  select: function(value){ // select a value
   var control = this.data('rating'); if(!control) return this;
   // do not execute when control is in read-only mode
   if(control.readOnly) return;
   // clear selection
   control.current = null;
   // programmatically (based on user input)
   if(typeof value!='undefined'){
    // select by index (0 based)
    if(typeof value=='number')
     return $(control.stars[value]).rating('select');
    // select by literal value (must be passed as a string
    if(typeof value=='string')
     //return 
     $.each(control.stars, function(){
      if($(this).data('rating.input').val()==value) $(this).rating('select');
     });
   }
   else
    control.current = this[0].tagName=='INPUT' ? 
     this.data('rating.star') : 
     (this.is('.rater-'+ control.serial) ? this : null);
   
   // Update rating control state
   this.data('rating', control);
   // Update display
   this.rating('draw');
   // find data for event
   var input = $( control.current ? control.current.data('rating.input') : null );
   // click callback, as requested here: http://plugins.jquery.com/node/1655
   if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
  },// $.fn.rating.select
  
  readOnly: function(toggle, disable){ // make the control read-only (still submits value)
   var control = this.data('rating'); if(!control) return this;
   // setread-only status
   control.readOnly = toggle || toggle==undefined ? true : false;
   // enable/disable control value submission
   if(disable) $(control.inputs).attr("disabled", "disabled");
   else        $(control.inputs).removeAttr("disabled");
   // Update rating control state
   this.data('rating', control);
   // Update display
   this.rating('draw');
  },// $.fn.rating.readOnly
  
  disable: function(){ // make read-only and never submit value
   this.rating('readOnly', true, true);
  },// $.fn.rating.disable
  
  enable: function(){ // make read/write and submit value
   this.rating('readOnly', false, false);
  }// $.fn.rating.select
  
 });
 
 /*--------------------------------------------------------*/
 
 /*
  ### Default Settings ###
  eg.: You can override default control like this:
  $.fn.rating.options.cancel = 'Clear';
 */
 $.fn.rating.options = { //$.extend($.fn.rating, { options: {
   cancel: 'Cancel Rating',   // advisory title for the 'cancel' link
   cancelValue: '',           // value to submit when user click the 'cancel' link
   split: 0,                  // split the star into how many parts?
   
   // Width of star image in case the plugin can't work it out. This can happen if
   // the jQuery.dimensions plugin is not available OR the image is hidden at installation
   starWidth: 16//,
   
   //NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
   //half:     false,         // just a shortcut to control.split = 2
   //required: false,         // disables the 'cancel' button so user can only select one of the specified values
   //readOnly: false,         // disable rating plugin interaction/ values cannot be changed
   //focus:    function(){},  // executed when stars are focused
   //blur:     function(){},  // executed when stars are focused
   //callback: function(){},  // executed when a star is clicked
 }; //} });
 
 /*--------------------------------------------------------*/
 
 /*
  ### Default implementation ###
  The plugin will attach itself to file inputs
  with the class 'multi' when the page loads
 */
 $(function(){
  $('input[type=radio].star').rating();
 });
 
 
 
/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/
//-->
