/**
 * 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
 *
 */

/**
 * Create a degradeable star rating interface out of a simple form structure.
 * Returns a modified jQuery object containing the new interface.
 *
 * @example jQuery('form.rating').rating();
 * @cat plugin
 * @type jQuery
 *
 */
(function($){ //create local scope
    var displayRating = function(obj) {
        var title = obj.title ? obj.title : '';

        $container = $(obj).html('');

        var averageIndex = 0;
        var averagePercent = 0;
        var size = 0;

        if (title != '') {
            var s = $.trim(title.split(':')[1]).split('/');
            size = s[1];
            var a = s[0].split('.');
            averageIndex = a[0];
            averagePercent = a[1] == undefined ? 0 : a[1][0];
        }

        for (var i = 0; i < size; i++) {
            $container.append('<span class="rating-star"><a class="rating-star" href="#' + (i+1) + '" title="' + title + '">' + (i+1) + '</a></span>');
        }

        $container
        .append('<div style="clear:both"></div>');

        var $stars = $('span.rating-star', obj).css('cursor', 'default');

        $('a.rating-star', obj)
        .css('cursor', 'default')
        .bind('click', function() { return false; });

        $stars.lt(averageIndex)
        .addClass('on')
        .end();

        var percent = (averagePercent) ? averagePercent * 10 : 0;
        if (percent > 0) {
            $stars.eq(averageIndex)
            .addClass('on')
            .find('a.rating-star')
            .css('width', percent + "%")
            .end();
        }
    }

    /**
     * Takes the form element, builds the rating interface and attaches the proper events.
     * @param {Object} $obj
     */
    var buildRating = function($obj) {
        var $obj = buildInterface($obj);
        var averageIndex = $obj.averageRating[0],
            averagePercent = $obj.averageRating[1],
            $stars = $($obj.find('div.rating-star')),
            $cancel = $($obj.find('div.rating-cancel'));
        $obj.end();

        // hover events.
        // and focus events added
        $stars
            .bind('mouseover', function(){
                event.drain();
                event.fill(this);
            })
            .bind('mouseout', function(){
                event.drain();
                event.reset();
            })
            .bind('focus', function(){
                event.drain();
                event.fill(this)
            })
            .bind('blur', function(){
                event.drain();
                event.reset();
            });

        // cancel button events
        $cancel
            .bind('mouseover', function(){
                event.drain();
                $(this).addClass('on')
            })
            .bind('mouseout', function(){
                event.reset();
                $(this).removeClass('on')
            })
            .bind('focus', function(){
                event.drain();
                $(this).addClass('on')
            })
            .bind('blur', function(){
                event.reset();
                $(this).removeClass('on')
            });

        // click events.
        $cancel.bind('click', function(){
            event.drain();
            averageIndex = 0;
            averagePercent = 0;
            $('input[@name='+$obj.name+']', $obj).val("0");

            /*$.post($obj.url, {
                "rating": $(this).find('a')[0].href.split('#')[1]
            });*/

            return false;
        });

        $stars.bind('click', function(){
            averageIndex = $stars.index(this) + 1;
            averagePercent = 0;
            $('input[@name='+$obj.name+']', $obj).val($(this).find('a.rating-star')[0].href.split('#')[1]);

            /*$.post($obj.url, {
                "rating": $(this).find('a')[0].href.split('#')[1]
            });*/

            return false;
        });

        var event = {
            fill: function(el){ // fill to the current mouse position.
                var index = $stars.index(el) + 1;
                $stars
                    .find('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').find('a.rating-star').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($select){
        var title = $select[0].title ? $select[0].title : '';

        var $container = $('<div></div>').attr({
            "title": title,
            "class": "rating-select"
        });

        $.extend($container, {
            averageRating: title != '' ? $.trim(title.split(':')[1]).split('.') : [0, 0],
            name: $select.attr('name')
        });

        var optionGroup = new Array;
        var numDelete = 0;

        $select.find('option').each(function() {
            if (this.value == "") {
                return;
            }

            if (this.value == "0") {
                numDelete++;
            }

            optionGroup.push(this);
        });

        var size = optionGroup.length - numDelete;

        for (var i = 0; i < optionGroup.length; i++) {
            var o = optionGroup[i];
            if (o.value == "0") {
                //$container.prepend('<div class="rating-cancel"><a class="rating-cancel" href="#0" title="Cancel Rating">Cancel Rating</a></div>');
            } else {
                $container.prepend('<div class="rating-star"><a class="rating-star" href="#' + o.value + '" title="' + o.value + '/'+ size +'">' + o.value + '</a></div>');
            }
        }

        $container.append('<div style="clear:both"></div>');
        $container.append('<input type="hidden" name="'+$select.attr('name')+'" value="0" />');

        $select.after($container);
        $select.remove();

        return $container;
    }

    /**
     * Set up the plugin
     */
    $.fn.rating = function(){
        var stack = [];
        this.each(function(){
            var ret = buildRating($(this));
            stack = $.merge(ret, stack);
        });
        return $(stack);
    }

    $.fn.displayRating = function(){
        this.each(function(){
            displayRating(this);
        });

        return this;
    }

	// fix ie6 background flicker problem.
	/*if ($.browser.msie == true) {
		document.execCommand('BackgroundImageCache', false, true);
	}*/
})(jQuery)
