﻿(function($) {
    $.fn.Ratings = function(settings) {
        settings = $.extend({
            persistCookie: true,
            min: 1,
            max: 5,
            container: 'rate-container',
            base: 'rate-base',
            active: 'rate-active',
            inactive: 'rate-inactive',
            highlight: 'rate-highlight'
        },
        settings);

        this.glyphs = [];

        this.each(function() {
            var e = $(this);
            var url = e.attr("href");
            var disabled = !$.auth || url == '' || isTrue($.cookie("r" + url));
            var rating = parseFloat(/\d+(?:.\d+)?/.exec(e.attr("rel")));
            var glyphs = [];
            var c = 0;
            var control = $("<div/>").addClass(settings.container);
            var container = $("<div/>");
            control.append(container);

            for (var i = settings.min; i <= settings.max; ++i) {
                glyphs.push($("<div/>").addClass(settings.base).addClass(i <= rating ? settings.active : settings.inactive));

                if (!disabled) {
                    for (var j = 0; j < glyphs.length; ++j) {
                        glyphs[c].click(update(glyphs[j]));
                        glyphs[c].hover(rollover(glyphs[j]));
                    }

                    glyphs[c].click(rate(glyphs[c], url, i));
                }

                container.append(glyphs[c++]);
            }

            if (!disabled) {
                for (var i = 0; i < glyphs.length; ++i) {
                    glyphs[i].click(disable(glyphs));
                }
            }
            else if (!$.auth) {
                var prompt = $('<div><a href="' + $.login + '">Log in to rate</a></div').css("display", "none")

                container.hover(function() { prompt.fadeIn("slow") });
                control.append(prompt);
            }

            $(this).replaceWith(control);
        });

        function rollover(g) {
            return function() {
                if (isFalse(g.attr("disabled"))) {
                    g.toggleClass(settings.highlight);
                }
            };
        }

        function update(g) {
            return function() {
                g.removeClass(settings.inactive);
                g.addClass(settings.active);
            };
        }

        function disable(g) {
            return function() {
                for (var i = 0; i < g.length; ++i) {
                    g[i].removeClass(settings.highlight);
                    g[i].addClass(settings.disabled);
                    g[i].attr("disabled", true);
                }
            };
        }

        function rate(g, url, rating) {
            return function() {
                if (isFalse($.cookie("r" + url))) {
                    $.cookie("r" + url, true);
                    $.post(url, { rating: rating });
                }
            }
        }

        function isTrue(v) {
            return (typeof (v) === "boolean" && v) || (typeof (v) === "string" && v.toLowerCase() === "true");
        }

        function isFalse(v) {
            return !isTrue(v);
        }

        return this;
    };
})(jQuery);

$(document).ready(function() {
    $("a[rel^='ratingWidget']").Ratings();
});
