/**
 * Star Rating - jQuery plugin
 *
 * Copyright (c) 2006 Wil Stuckey
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

// modified from http://sandbox.wilstuckey.com/jquery-ratings/js/jquery.rating.js
 
/**
 * 
 * Create a degradeable star rating interface out of a simple form structure.
 * Returns a modified jQuery object containing the new interface.
 * 
 * @name star rating
 * @author wstuckey 
 *  
 * @example jQuery('form.rating').rating();
 * @cat plugin
 * @type jQuery 
 */
(function(JQ){ //create local scope
    /**
     * Takes the form element, builds the rating interface and attaches the proper events.
     * @param {Object} $obj
     */
    var buildRating = function($obj){
        var $obj = buildInterface($obj),
            averageIndex = $obj.averageRating[0],
            averagePercent = $obj.averageRating[1],
            $stars = JQ($obj.children('.star')),
            $cancel = JQ($obj.end().children('.cancel'));
        $obj.end();
        
        // hover events.
        // and focus events added
        $stars
            .mouseover(function(){
                event.drain();
                event.fill(this);
                JQ('#rating_text_' + $obj.nid).html(this.firstChild.title);
            })
            .mouseout(function(){
                event.drain();
                event.reset();
                JQ('#rating_text_' + $obj.nid).html('');;
            })
            .focus(function(){
                event.drain();
                event.fill(this);
                JQ('#rating_text_' + $obj.nid).html(this.firstChild.title);
            })
            .blur(function(){
                event.drain();
                event.reset();
                JQ('#rating_text_' + $obj.nid).html('');;
            });
            
        // cancel button events
        $cancel
            .mouseover(function(){
                event.drain();
                JQ(this).addClass('on')
            })
            .mouseout(function(){
                event.reset();
                JQ(this).removeClass('on')
            })
            .focus(function(){
                event.drain();
                JQ(this).addClass('on')
            })
            .blur(function(){
                event.reset();
                JQ(this).removeClass('on')
            });
            
            // click events.
        $cancel.click(function(){
            event.drain();
            averageIndex = 0;
            averagePercent = 0;
            var index = JQ('#rating_options_' + $obj.nid).rating_option(JQ(this).children('a')[0].href.split('#')[1]);
            JQ('#rating_options_' + $obj.nid).get(0).selectedIndex = index;
            rating_submit_rating($obj.nid);
            return false;
        });
        $stars.click(function(){
            averageIndex = $stars.index(this) + 1;
            averagePercent = 0;
            var index = JQ('#rating_options_' + $obj.nid).rating_option(JQ(this).children('a')[0].href.split('#')[1]);
            JQ('#rating_options_' + $obj.nid).get(0).selectedIndex = index;
            rating_submit_rating($obj.nid);
            return false;
        });
        
         var event = {
            fill: function(el){ // fill to the current mouse position.
                var index = $stars.index(el) + 1;
                $stars
                    .children('a').css('width', '100%').end()
                    .lt(index).addClass('hover').end();
            },
            drain: function() { // drain all the stars.
                $stars
          .filter('.on').removeClass('on').end()
          .filter('.hover').removeClass('hover').end();
            },
            reset: function(){ // Reset the stars to the default index.
                $stars.lt(averageIndex).addClass('on').end();
                var percent = (averagePercent) ? averagePercent * 10 : 0;
                if (percent > 0) {
                    $stars.eq(averageIndex).addClass('on').children('a').css('width', percent + "%").end().end()
                }  
            }
        }        
        event.reset();
        return $obj;
    }
    
    /**
     * Accepts jQuery object containing a form element.
     * Returns the proper div structure for the star interface.
     * 
     * @return jQuery
     * @param {Object} $form
     * 
     */
    
    var buildInterface = function($form){
        var $container = JQ(document.createElement('div')).attr({
            "title": $form.title(),
            "class": $form.attr('class')
        });
        

        JQ.extend($container, {
            averageRating: JQ.trim($container.title().split(':')[1]).split('.'),
            nid: $form.attr('id').split('_')[2]
        });
                
        var $optionGroup = JQ('#rating_options_' + $container.nid).children('option');
        $optionGroup.sort(function(a,b){
            return (a.value-b.value);
        });
        
        for (var i = 0, option; option = $optionGroup[i]; i++){
            if (option.value == "0") {
                $div = JQ('<div class="cancel"><a href="#0" title="Cancel Rating">Cancel Rating</a></div>');
            } else {
                $div = JQ('<div class="star"><a class="mod" href="#' + option.value + '" title="' + option.text + '">' + option.value + '</a></div>');
            }
            $container.append($div[0]);   
        }
        
        var $rating_intro = JQ(document.createElement('div')).attr({
            "class": 'rating-intro'
        });
        
        $rating_intro.append(JQ('#rating_options_' + $container.nid).title() + ': ');
        
        $rating_intro.append(JQ(document.createElement('span')).attr({
            "id": 'rating_text_' + $container.nid,
            "class": 'rating-text'
        }));
        
        $container.prepend($rating_intro);
        
        $container.append(JQ(document.createElement('span')).attr({
            "id": 'rating_message_' + $container.nid,
            "class": 'rating-message'
        }));
                
        $form.after($container).hide();
        $container.show();
        return $container;
    }
    
    /**
     * Set up the plugin
     */
    JQ.fn.rating = function(){
        var stack = [];
        this.each(function(){
            var ret = buildRating(JQ(this));
            stack = JQ.merge(ret, stack);
        });
        return JQ(stack);
    }
    
  // fix ie6 background flicker problem.
  if (JQ.browser.msie == true) {
    document.execCommand('BackgroundImageCache', false, true);
  }
    
})(jQuery)

jQuery.fn.sort = function() {
  return this.pushStack( [].sort.apply( this, arguments ), []);
};

jQuery.fn.rating_option = function (value) {
        var select = JQ(this)[0];
        for ( var i=0; i<select.length; i++ )
        if (select[i].value == value)
            return i;
};

function rating_submit_rating(nid){
    JQ('#rating_form_' + nid).ajaxSubmit(
        {
            dataType: 'json',
            after: function(data){
                if (data.error){
                    JQ('#rating_message_' + nid).background('#f55');
                    JQ('#rating_message_' + nid).html(data.error).fadeIn('slow');
                    return false;
                }
                JQ('#rating_message_' + nid).background('#ff5');
                JQ('#rating_message_' + nid).html(data.response).fadeIn('slow').fadeOut('slow');
                
                mean = data.mean.split('.');
                var $obj = JQ('#rating_mean_' + nid);
                $stars = JQ($obj.children('.star'));
                $stars.filter('.on').removeClass('on').end();
                $stars.children('a').css('width', '100%').end();               
                $stars.lt(mean[0]).addClass('on').end();
                if (mean[1] > 0){
                  $stars.eq(mean[0]).addClass('on').children('a').css('width', mean[1] * 10 + "%").end().end()
                }
                JQ('#rating_num_votes_' + nid).html(data.num_votes);
            }
        }
    );
}

JQ(document).ready(
    function() {
        try{
            jQuery('form.rating').rating();
        }
        catch(e){};
    }
)
