(function($, undef){
    var global = this;
    
    global.RWM = function ()
    {
        /* Initializations */
        $(document).ready(function(){
            $("#rw_advanced_settings .rw-tabs div").each(function(i, tab){
                $(tab).click(function(){
                    if (!$(tab).hasClass("rw-selected"))
                    {
                        // Switch selected tab.
                        $("#rw_advanced_settings .rw-tabs div").removeClass("rw-selected");
                        $(tab).addClass("rw-selected");
                        
                        $("#rw_advanced_settings_body").height($($("#rw_advanced_settings_body table")[i]).height() + 20);
                        
                        // Hide all advanced settings.
                        $("#rw_advanced_settings_body table").hide();

                        // Show specified section.
                        $($("#rw_advanced_settings_body table")[i]).fadeIn();
                        
                        $("#rw_advanced_settings_body").height("auto");
                        
                        if (typeof(undef) !== typeof(Wix)){
                            Wix.reportHeightChange($(document.body).children('div').first().height() + 110);
                        }
                    }
                });
            });
            
            $("#rw_embed .rw-tabs div").each(function(i, tab){
                $(tab).click(function(){
                    if (!$(tab).hasClass("rw-selected"))
                    {
                        // Switch selected tab.
                        $("#rw_embed .rw-tabs div").removeClass("rw-selected");
                        $(tab).addClass("rw-selected");
                        
                        $("#rw_embed_body").height($("#rw_embed_body").height());
                        
                        // Hide all advanced settings.
                        $("#rw_code_container").hide();

                        // Update code.
                        RWM.Code.refresh();

                        // Show specified section.
                        $("#rw_code_container").fadeIn();
                        
                        $("#rw_embed_body").height("auto");
                    }
                });
            });
            
            $(".rw-ui-img-radio").click(function(){
                // Alias.
                var e = $(this);
                
                if (e.attr('data-alert'))
                {
                    alert(e.attr('data-alert'));
                    return;
                }
                
                // Get ref to radio button.
                var button = e.children("input");
                
                // Get button family name.
                var name = button.attr("name"),
                    isSelected = e.hasClass("rw-selected");

                if (button.is(":radio")) // Radio button
                {
                    if (!isSelected) // Only if not selected
                    {
                        // Switch selection.
                        $("input[name=" + name + "]").parent().removeClass("rw-selected");
                        e.addClass("rw-selected");

                        // Select button.
                        $(button).attr("checked", "checked");
                    }
                }
                else // Checkbox
                {
                    button = e.children(":checkbox");
                    
                    if (e.hasClass("rw-select-all"))
                    {
                        button = $("input[name='" + name + "']");
                    }
                    else
                    {
                        var selectAllButton = $(".rw-select-all input[name='" + name + "']");
                        if (selectAllButton.length > 0)
                        {
                            if (
                                // If uncheck, uncheck the SELECT ALL checkbox.
                                isSelected || 
                                // Or if check, and there is only two unchecked checkboxes (the SELECT ALL AND THE CURRENT), check the SELECT ALL checkbox.
                                $("input[name='" + name + "']:not(:checked)").length == 2)
                            {
                                // Select/Unselect the select all button.
                                selectAllButton.attr("checked", !isSelected);
                                selectAllButton.parent().toggleClass("rw-selected", !isSelected);
                            }
                            else
                            {
                                // If all other checkboxes are selected, select the SELECT ALL checkbox.
                            }
                        }
                    }
                        
                    button.attr("checked", !isSelected);
                    button.parent().toggleClass("rw-selected", !isSelected);
                }
                
                // Update embeded code.
                RWM.Code.refresh();
            });
            
            $("#advanced_trigger").click(function(){
                // Toggle visibility.
                if ($("#rw_advanced_settings").is(":hidden"))
                {
                    $("#rw_advanced_settings").show();
                }
                else
                {
                    $("#rw_advanced_settings").hide();
                }
                
                if (typeof(undef) !== typeof(Wix)){
                    Wix.reportHeightChange($(document.body).children('div').first().height() + 110);
                }

                $(this).toggleClass("rw-open");
            });
            
            
            for (var j = 0, types = ["star", "nero"]; j < 2; j++)
            {
                $("#rw_" + types[j] + "_theme_select").click(function(event){
                    var list = $("#" + this.id + "_list");
                    
                    if (list.css("display") != "block")
                    {
                        list.children("li.rw-li.rw-hover").removeClass("rw-hover");
                        var selected = list.children("li.rw-li.rw-selected");
                        selected.addClass("rw-hover");
                        if ($(this).offset().top + 200 < $(document).height())
                        {
                            list.css("top", ($(this).height() - 1) + 'px');
                        }
                        else
                        {
                            list.css("top", "-200px");
                        }
                        list.show();
                        list[0].scrollTop = selected.position().top;
                        $(this).addClass("rw-clicked");
                    }else{
                        list.hide();
                        $(this).removeClass("rw-clicked");
                    }

                    event.stopPropagation();
                });
                
                $("#rw_" + types[j] + "_theme_select select").focus(function(event){
                    $(this.parentNode).children(".rw-select-frame").show();
                });
                
                $("#rw_" + types[j] + "_theme_select select").blur(function(event){
                    $(this.parentNode).children(".rw-select-frame").hide();
                });
                
                $("#rw_" + types[j] + "_theme_select").keydown(function(event){
                    var themes = $("#" + this.id + "_list li.rw-li");
                    var k, k_len;
                    for (k = 0, k_len = themes.length; k < k_len; k++)
                    {
                        if ($(themes[k]).hasClass("rw-selected")){ break; }
                    }
                    
                    switch(event.which)
                    {
                        case 37: // left
                        case 38: // up
                            if (k == 0){ return; }
                            themes[k-1].onclick();
                            break;
                        case 39: // right
                        case 40: // down
                            if (k == k_len - 1){ return; }
                            themes[k+1].onclick();
                            break;
                    }
                });
            }
            
            $(document).click(function(event)
            {
                $("#rw_star_theme_select_list").hide();
                $("#rw_nero_theme_select_list").hide().removeClass("rw-clicked");
                $("#rw_star_theme_select").removeClass("rw-clicked");
                $("#rw_nero_theme_select").removeClass("rw-clicked");
                
                if ($('#rw_widget_code').css("display") !== "none"){
                    $('#rw_widget_code').animate({'height': 'toggle', 'opacity': 'toggle'}, 'fast');
                }
            });
            
            
            $("#rw_get_widget").click(RWM.getWidget);
            $("#rw_widget_code").click(function(event){ event.stopPropagation(); });
            
            // Prepare for toggle height animation.
            $("#rw_widget_code").show().animate({height: "toggle", "opacity": "toggle"}, 0);
            
            // Prepare live preview title.
            $("#rw_live_preview_title").show();
            $("#rw_live_preview_title").fadeOut(0);
            
            
            // Show preview.
            $("#rw_layout_bottom_border").animate({bottom: "-7px"}, "slow", function(){
                $("#rw_layout_preview").animate({backgroundColor: "rgb(240,240,240)"}, "slow", function()
                {
                    $("#rw_live_preview_title").animate({opacity: "toggle"}, "slow");
                })
                                       .animate({backgroundColor: "red"}, "slow")
                                       .animate({backgroundColor: "rgb(240,240,240)"}, "slow")
                                       .animate({backgroundColor: "yellow"}, "slow")
                                       .animate({backgroundColor: "rgb(240,240,240)"}, "slow")
                                       .animate({backgroundColor: "red"}, "slow")
                                       .animate({backgroundColor: "rgb(240,240,240)"}, "slow")
                                       .animate({backgroundColor: "yellow"}, "slow")
                                       .animate({backgroundColor: "rgb(240,240,240)"}, "slow")
                                       .animate({backgroundColor: "red"}, "slow")
                                       .animate({backgroundColor: "rgb(240,240,240)"}, "slow");
            });
            
        });
        
        var firstWidgetShow = true;
        
        return {
            STAR : null,
            NERO : null,
            RECAPTCHA_PUBLIC: "6LeTBMASAAAAAFbVr_F3wW7CvQDNq6dYuLPJbj6_",
            getWidget : function(event)
            {
                var was_visible = ($('#rw_widget_code').css("display") !== "none");
                
                $('#rw_widget_code').animate({height: 'toggle', opacity: 'toggle'}, 'fast', function(){
                    if (firstWidgetShow)
                    {
                        $("#rw_first_use_description").animate({backgroundColor: 'white', borderBottomColor: 'orange', borderLeftColor: 'orange', borderRightColor: 'orange', borderTopColor: 'orange'}, 1500)
                                              .animate({backgroundColor: 'rgb(240,240,240)', borderBottomColor: 'rgb(240,240,240)', borderLeftColor: 'rgb(240,240,240)', borderRightColor: 'rgb(240,240,240)', borderTopColor: 'rgb(240,240,240)'}, 1000);
                    }
                });

                if (firstWidgetShow)
                {
                    RWM.Code.refresh();
                    RWM.Set.clipboard();
                    
                    firstWidgetShow = false;
                }

                // Stop event propagation so the code window won't be closed.
                event.stopPropagation();
            },
            firstUse : function()
            {
                $('#rw_first_use_description').animate({backgroundColor: 'white', borderBottomColor: 'orange', borderLeftColor: 'orange', borderRightColor: 'orange', borderTopColor: 'orange'}, "fast");
                
                Recaptcha.create(this.RECAPTCHA_PUBLIC,
                    "rw_captcha_container",
                    {
                        theme: "white",
                        callback: function()
                        {
                            $("#rw_first_use_button").hide();
                            $('#rw_first_use_container').show();
                            $("#recaptcha_response_field")[0].tabIndex = 11;
                            $('#user_email').focus();
                            //Recaptcha.focus_response_field();
                        }
                    }
                  );
            },
            genUser : function()
            {
                var challenge = Recaptcha.get_challenge();
                var response = Recaptcha.get_response();
                
                var err = $("#rw_captcha_error");
                
                err.html("");
                if (response.length == 0){
                    err.html("You must type the captcha in order to get your user key.");
                    Recaptcha.focus_response_field();
                    return;
                }
                
                $.get(
                    "/action/user.php",
                    {
                        challenge: challenge, 
                        response: response, 
                        domain: "",
                        email: $('#user_email').val()
                    },
                    function (res)
                    {
                        if (!res.success){
                            err.html(res.msg);
                            Recaptcha.reload();
                        }else{
                            $("#rw_first_use_description").html('\
<div class="rw-user-key">\
    <label>User Key:</label>\
    <input type="text" id="rw_user_key" value="' + res.data[0].uid.toUpperCase() + '"\ readonly="readonly=" />\
</div>\
<div class="rw-user-key">\
    <label>User ID:</label>\
    <input type="text" id="rw_user_id" value="' + res.data[0].huid.toUpperCase() + '"\ readonly="readonly=" />\
</div>\
<span><b>This is your unique user key &amp; id - SAVE THEM!</b></span>');
                            $('#rw_add_blogger').show();
                            RWM.Code.refresh();
                        }
                    },
                    "json"
                );
            },
            addBlogger : function ()
            {
                var options = RWM.Code.getSettingsJSON();
                $('#rw_add_blogger textarea').text(
'<div class="rw-js-container">\
    <script type="text/javascript">\
        var _rws = _rws || [];\
        _rws.push({\
            uid: "' + $('#rw_user_key').val() + '",\
            huid: "' + $('#rw_user_id').val() + '",' + (options.isEmpty() ? '' :'\
            options: ' + options) + ',\
            source: "Blogger"\
        });\
\
        if (typeof(RW) == "undefined"){\
            (function(){\
                var rw = document.createElement("script"),\
                    d = new Date(), ck = "Y" + d.getFullYear() + "M" + d.getMonth() + "D" + d.getDate();\
                rw.type = "text/javascript"; rw.async = true;\
                rw.src = "http://js.rating-widget.com/blogger.js?ck=" + ck;\
                var s = document.getElementsByTagName("script")[0];\
                s.parentNode.insertBefore(rw, s);\
            })();\
        }\
    </script>\
</div>');

                $('#rw_add_blogger').submit();
            },
            showCustomWindow : function()
            {
                var img_url = $('#rw_custom_url');
                if (img_url.val() == ""){
                    img_url.val("//img.rating-widget.com/rw." + rwStar.options.size + ".heart.png");
                }
                
                $('#rw_custom_color').fadeIn(function(){
                    img_url.select();
                });
            },
            cancelCustom : function()
            {
                $('#rw_custom_color').fadeOut(function(){
                    if (!global.customEdited){
                        $('#rw_custom_url').val('');
                    }
                });
            },
            setCustom : function()
            {
                global.customEdited = true;
                rwStar.setColor(rwStar.options.style, $('#rw_custom_url').val());
                $('#rw_custom_color').fadeOut();
            },
            _enrichQueryString : function (pUri, pName, pValue)
            {
                var query_pos = pUri.indexOf("?");
                
                // Add query to URI.
                if (-1 === query_pos){ pUri += "?"; }
                
                var pos = (query_pos > 0) ? pUri.indexOf(pName + "=", query_pos) : -1;
                if (pos >= 0)
                {
                    var end = pos + (pName + "=").length;
                    var cur = end;
                    var max = pUri.length;
                    while (cur < max && pUri.charAt(cur) !== "&"){
                        cur++;
                    }
                    
                    pUri = pUri.substr(0, end) + encodeURIComponent(pValue) + pUri.substr(cur);
                }
                else
                {
                    pUri += ((-1 === query_pos) ? "" : "&") + pName + "=" + encodeURIComponent(pValue);
                }        
                
                return pUri;
            },
            enrichQueryString : function (pUri, pNames, pValues)
            {
                for (var i = 0, len = pNames.length; i < len; i++)
                {
                    pUri = this._enrichQueryString(pUri, pNames[i], pValues[i]);
                }
                
                return pUri;
            }
        };
    }();
    
    RWM.Set = function ()
    {
        var prev_con;
        var clip = null;
        
        $(document).ready(function(){
            prev_con = $("#rw_preview_container")[0];
            
            if (typeof(ZeroClipboard) !== typeof(undef) && null != ZeroClipboard.setMoviePath){
                ZeroClipboard.setMoviePath("//js.rating-widget.com/vendors/ZeroClipboard.swf");
            }
        });
        
        var update_size_icons = function (pType)
        {
            var url,
                tinyUrl,
                smallUrl,
                mediumUrl,
                largeUrl,
                tinyIcon = $("#rw_star_size .rw-ui-sprite.rw-ui-tiny"),
                smallIcon = $("#rw_star_size .rw-ui-sprite.rw-ui-small"),
                mediumIcon = $("#rw_star_size .rw-ui-sprite.rw-ui-medium"),
                largeIcon = $("#rw_star_size .rw-ui-sprite.rw-ui-large");
            
            if (pType == RW.TYPE.STAR)
            {
                url = $("#rw_star_theme_selected li.rw-ui-star-selected").css("backgroundImage");
                tinyUrl = url.replace(/(.+)\.(l|m|s)\.png/, "$1.t.png");
                smallUrl = url.replace(/(.+)\.(l|m|s)\.png/, "$1.s.png");
                mediumUrl = url.replace(/(.+)\.(l|m|s)\.png/, "$1.m.png");
                largeUrl = url.replace(/(.+)\.(l|m|s)\.png/, "$1.l.png");

                tinyIcon.css("backgroundImage", tinyUrl).css("backgroundPosition", "-39px 0");
                smallIcon.css("backgroundImage", smallUrl).css("backgroundPosition", "-48px 0");
                mediumIcon.css("backgroundImage", mediumUrl).css("backgroundPosition", "-60px 0");
                largeIcon.css("backgroundImage", largeUrl).css("backgroundPosition", "-90px 0");
            }
            else if (pType == RW.TYPE.NERO)
            {
                url = $("#rw_nero_theme_selected .rw-ui-like-icon").css("backgroundImage");
                tinyUrl = url.replace(/(.+)\.(l|m|s)(r|l)\.png/, "$1.t$3.png");
                smallUrl = url.replace(/(.+)\.(l|m|s)(r|l)\.png/, "$1.s$3.png");
                mediumUrl = url.replace(/(.+)\.(l|m|s)(r|l)\.png/, "$1.m$3.png");
                largeUrl = url.replace(/(.+)\.(l|m|s)(r|l)\.png/, "$1.l$3.png");
                
                tinyIcon.css("backgroundImage", tinyUrl).css("backgroundPosition", "0 0");
                smallIcon.css("backgroundImage", smallUrl).css("backgroundPosition", "0 0");
                mediumIcon.css("backgroundImage", mediumUrl).css("backgroundPosition", "0 0");
                largeIcon.css("backgroundImage", largeUrl).css("backgroundPosition", "0 0");
            }
        };
        
        var update_thumbs_icons = function ()
        {
            var url = $("#rw_nero_theme_selected .rw-ui-like-icon").css("backgroundImage");
            url = url.replace('small', 'large').replace('medium', 'large');
            $("#rw_nero_show .rw-like").css("backgroundImage", url).css("backgroundPosition", "0 -30px");
            $("#rw_nero_show .rw-dislike").css("backgroundImage", url).css("backgroundPosition", "-30px -30px");
        };
        
        var update_container_width = function (pType, pSize)
        {
            if (pSize !== RW.SIZE.LARGE){
                //prev_con.style.width = "222px";
            }else{
                if (pType == RW.TYPE.STAR){
                    //prev_con.style.width = "322px";
                }else{
                    //prev_con.style.width = "282px";
                }
            }
        };
        
        var selected = false;
        var blink_cnt = 0;
        var blinkTimeout = null;
        var blink_code = function()
        {
            if (selected){
                RWM.Set.deselect();
            }else{
                RWM.Set.select("rw_code_container");
            }
            
            selected = !selected;
            blink_cnt++;
            
            if (blink_cnt < 3 || selected){
                blinkTimeout = setTimeout(blink_code, 100);
            }else{
                blink_cnt = 0;
                blinkTimeout = null;
            }
        };
        
        return {
            selectedType : "star",
            selectedTheme : {star: "star_yellow1", nero: "thumbs_1"},
            sizeIcons : function (pType)
            {
                update_size_icons(pType);
                update_thumbs_icons();
            },
            type : function(pType)
            {
                if (pType === this.selectedType){ return; }
                
                switch(pType)
                {
                    case RW.TYPE.NERO:
                        $("#rw_preview_star").css("display", "none");
                        $("#rw_star_theme_select").css("display", "none");
                        $("#rw_preview_nero").css("display", "");
                        $("#rw_nero_theme_select").css("display", "");

                        if ($("#rw_advanced_star_tab").hasClass("rw-selected")){
                            $($("#rw_advanced_settings .rw-tabs div")[0]).trigger("click");
                        }
                        $("#rw_advanced_star_tab").hide();
                        $("#rw_advanced_nero_tab").show();
                        
                        break;
                    case RW.TYPE.STAR:
                    default:
                        $("#rw_preview_nero").css("display", "none");
                        $("#rw_nero_theme_select").css("display", "none");
                        $("#rw_preview_star").css("display", "");
                        $("#rw_star_theme_select").css("display", "");

                        if ($("#rw_advanced_nero_tab").hasClass("rw-selected")){
                            $($("#rw_advanced_settings .rw-tabs div")[0]).trigger("click");
                        }
                        $("#rw_advanced_nero_tab").hide();
                        $("#rw_advanced_star_tab").show();

                        break;
                }

                this.selectedType = pType;
                
                update_size_icons(pType);
                update_thumbs_icons();
                update_container_width(pType, RWM.STAR.options.size);
            },
            direction : function(pDir)
            {
                if (pDir == RWM.STAR.advanced.layout.dir){ return; }

                RWM.STAR.setDirection(pDir);
                RWM.NERO.setDirection(pDir);

                if (RWM.STAR.advanced.layout.align.hor != RW.ALIGN.HOR.CENTER)
                {
                    var new_hor = (RWM.STAR.advanced.layout.align.hor == RW.ALIGN.HOR.LEFT) ? 
                                   RW.ALIGN.HOR.RIGHT :
                                   RW.ALIGN.HOR.LEFT;

                    $(($('#rw_layout_align .rw-ui-' + RWM.STAR.advanced.layout.align.ver + new_hor))[0].parentNode).trigger("click");
                }
            },
            align : function(pVer, pHor)
            {
                if (pVer == RWM.STAR.advanced.layout.align.ver &&
                    pHor == RWM.STAR.advanced.layout.align.hor)
                {
                    return; 
                }
                
                RWM.STAR.setAlignment(pVer, pHor);
                RWM.NERO.setAlignment(pVer, pHor);
                
                if (pVer == RW.ALIGN.VER.MIDDLE){
                    switch (pHor)
                    {
                        case RW.ALIGN.HOR.RIGHT: prev_con.style.textAlign = "left"; break;
                        case RW.ALIGN.HOR.LEFT: prev_con.style.textAlign = "right"; break;
                    }
                }else{
                    prev_con.style.textAlign = "center";
                }
            },
            size : function(pSize)
            {
                if (pSize == RWM.STAR.options.size){ return; }
                
                if (typeof(RW_EXTERNAL_FLAG) === "undefined" ||
                    false === RW_EXTERNAL_FLAG)
                {
                    update_container_width(this.selectedType, pSize);
                }
                
                RWM.STAR.setSize(pSize);
                RWM.NERO.setSize(pSize);

                if (RWM.NERO.options.style == RW.CUSTOM)
                {
                    var theme = RWT[$("#rw_nero_theme_select").val()].options;
                    RWM.NERO.setStyle(RW.CUSTOM, theme.imgUrl[RWM.NERO.options.size]);
                }
                
                if (RWM.STAR.options.style == RW.CUSTOM)
                {
                    var theme = RWT[$("#rw_star_theme_select").val()].options;
                    RWM.STAR.setStyle(RW.CUSTOM, theme.imgUrl[RWM.STAR.options.size]);
                }
                
                /*if (!global.customEdited){
                    // Update customize pic size.
                    RWM.STAR.setStyle(RWM.STAR.options.style, "//img.rating-widget.com/rw." + RWM.STAR.options.size + ".heart.png");
                }*/
                
                var sizeSelect = $("#rw_font_size select");
                sizeSelect.children("option[value=" + parseInt(RW._DEF_FONT_SIZE[pSize.toUpperCase()], 10) + "]").attr("selected", "selected");
                sizeSelect.trigger("change");

                var heightSelect = $("#rw_layout_line_height select");
                heightSelect.children("option[value=" + parseInt(RW._DEF_LINE_HEIGHT[pSize.toUpperCase()], 10) + "]").attr("selected", "selected");
                heightSelect.trigger("change");
            },
            background : function (pBackground)
            {
                if (pBackground !== "transparent" && pBackground !== "buddy"){ return; }
                
                if (pBackground === "buddy")
                {
                    RWM.STAR.setCSS("container", "background: #F4F4F4; padding: 1px 2px 0px 2px; margin-bottom: 2px; border-right: 1px solid #DDD; border-bottom: 1px solid #DDD; border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px;");
                    RWM.NERO.setCSS("container", "background: #F4F4F4; padding: 4px 8px 1px 8px; margin-bottom: 2px; border-right: 1px solid #DDD; border-bottom: 1px solid #DDD; border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px;");
                }
                else
                {
                    RWM.STAR.setCSS("container", "");
                    RWM.NERO.setCSS("container", "");
                }
            },
            theme : function(pTheme, pType)
            {
                if (pTheme == this.selectedTheme[pType]){ return; }
                
                var theme = RWT[pTheme].options;
                
                // Save theme images urls.
                var tmp_imgUrls = theme.imgUrl;
                
                if (pType == RW.TYPE.STAR)
                {
                    if (theme.style == RW.CUSTOM){
                        // Replace theme options image url with specified size image.
                        theme.imgUrl = theme.imgUrl[RWM.STAR.options.size];
                        RWM.STAR.setStyle(theme.style, theme.imgUrl);
                    }else{
                        RWM.STAR.setStyle(theme.style);
                    }

                    RWM.STAR.setOptions(RW._Set.enrichedCopy(theme, RWM.STAR.options));
                    RWM.STAR.options.theme = pTheme;
                    $('#colorSelector div').css('backgroundColor', RWM.STAR.options.advanced.font.color);
                }
                else if (pType == RW.TYPE.NERO)
                {
                    if (theme.style == RW.CUSTOM){
                        // Replace theme options image url with specified size image.
                        theme.imgUrl = theme.imgUrl[RWM.NERO.options.size];
                        
                        RWM.NERO.setStyle(theme.style, theme.imgUrl);
                    }else{
                        RWM.NERO.setStyle(theme.style);
                    }

                    RWM.NERO.setOptions(RW._Set.enrichedCopy(theme, RWM.NERO.options));
                    RWM.NERO.options.theme = pTheme;
                    $('#colorSelector div').css('backgroundColor', RWM.NERO.options.advanced.font.color);
                }
                
                this.selectedTheme[pType] = pTheme;
                
                update_size_icons(pType);
                
                if (pType == RW.TYPE.NERO){
                    update_thumbs_icons();
                }
                
                // Return images urls back.
                theme.imgUrl = tmp_imgUrls;
                
                RWM.Code.refresh();
                
                $("#rw_preview_" + this.selectedType).show();
            },
            text : function(pKey)
            {
                RWM.STAR.advanced.text[pKey] = RWM.NERO.advanced.text[pKey] = $("#rw_text_input_" + pKey).val();

                // Refresh UI.
                RWM.STAR.refresh();
                RWM.NERO.refresh();
                
                // Update code.
                RWM.Code.refresh();
            },
            language : function(pLng)
            {
                if (pLng == RWM.STAR.options.lng){ return; }
                RWM.STAR.setLanguage(pLng);
                RWM.NERO.setLanguage(pLng);
                
                if (RWM.STAR.advanced.layout.align.ver == RW.ALIGN.VER.MIDDLE){
                    switch (RWM.STAR.advanced.layout.align.hor)
                    {
                        case RW.ALIGN.HOR.RIGHT: prev_con.style.textAlign = "left"; break;
                        case RW.ALIGN.HOR.LEFT: prev_con.style.textAlign = "right"; break;
                    }
                }else{
                    prev_con.style.textAlign = "center";
                }

                // Update direction and alignment.
                $(($('#rw_layout_direction .rw-ui-' + RWM.STAR.advanced.layout.dir))[0].parentNode).trigger("click");    
                $(($('#rw_layout_align .rw-ui-' + RWM.STAR.advanced.layout.align.ver + RWM.STAR.advanced.layout.align.hor))[0].parentNode).trigger("click");
                
                // Update text.
                for (var key in RWM.STAR.advanced.text){
                    $("#rw_text_input_" + key).val(RWM.STAR.advanced.text[key]);
                }
                
                // Update code.
                RWM.Code.refresh();
            },
            frequency : function(f)
            {
                if (f == RWM.STAR.options.frequency)
                    return;
                    
                RWM.STAR.options.frequency = f;
                RWM.NERO.options.frequency = f;

                // Update code.
                RWM.Code.refresh();
            },
            clipboard : function ()
            {
                if (RW._is(clip))
                {
                    if (RW._is(clip.div) && RW._is(clip.div.parentNode)){
                        clip.div.parentNode.removeChild(clip.div);
                    }
                    clip.destroy();
                }

                clip = new ZeroClipboard.Client();
                clip.setHandCursor(true);
                clip.glue("rw_copy_to_clipboard", "rw_copy_to_clipboard_container");
                
                clip.addEventListener('onMouseDown', function (client, text) {
                    // Prepare clipboard text.
                    RWM.Set.select("rw_code_container");
                    clip.setText($("#rw_code_container").text());
                    RWM.Set.deselect();
                    if (RW._is(blinkTimeout)){ clearTimeout(blinkTimeout); }
                    selected = false;
                    blinkTimeout = setTimeout(blink_code, 100);
                });
            },
            deselect : function()
            {
                if (document.selection){
                    document.selection.empty();
                }else if (window.getSelection){
                    window.getSelection().removeAllRanges();
                }
            },
            select : function (pId)
            {
                this.deselect();
                var range;
                if (document.selection){
                    range = document.body.createTextRange();
                    range.moveToElementText(document.getElementById(pId));
                    range.select();
                }
                else if (window.getSelection)
                {
                    range = document.createRange();
                    range.selectNode(document.getElementById(pId));
                    window.getSelection().addRange(range);
                }
            },
            getSelected : function ()
            {
                var selected = '';
                if (document.getSelection){
                    selected = document.getSelection();
                }else if (window.getSelection){
                    selected = window.getSelection();
                }else if (document.selection){
                    selected = document.selection.createRange().text;
                }
                
                return selected.toString().replace(/\&nbsp\;/, ' ');
            }
        };
    }();

    RWM.Code = function ()
    {
        var _space = '&nbsp;',
            _tab = _space + _space + _space + _space,
            _tab2 = _tab + _tab,
            _tab3 = _tab2 + _tab,
            _tab4 = _tab3 + _tab,
            _tab5 = _tab4 + _tab;
        /**
        * Recursively builds the difference object between the input
        * object and the reference.
        */
        var get_objects_diff = function(diff, reference, object)
        {
            for (var p in object)
            {
                if (typeof(object[p]) == "object")
                {
                    diff[p] = {};
                    get_objects_diff(diff[p], reference[p], object[p]);
                }
                else
                {
                    if (object[p] != reference[p]){
                        diff[p] = object[p];
                    }
                }
            }
        };

        /**
        * Recursively remove all empty object members from object.
        * e.g. if the object is - {a: 0, b: {c: 's', d: {}}}
        *      after the process it will become - {a: 0, b: {c: 's'}}
        */
        var clean_empty_object_members = function(obj)
        {
            var is_empty = true;
            for (var p in obj)
            {
                if (typeof(obj[p]) != "object")
                {
                    is_empty = false;
                }
                else
                {
                    if (clean_empty_object_members(obj[p])){
                        delete obj[p];
                    }else{
                        is_empty = false;
                    }
                }
            }
            
            return is_empty;
        };

        var clone = function (str, len){
            var ret = "";
            for (var i = 0; i < len; i++){
                ret += str;
            }
            
            return ret;
        };

        var stringify_options = function(options, diff, tabs, space, eol, prepand, toJson)
        {
            space = RW._def(space, _space);
            eol = RW._def(eol, "<br />");

            // Theme options alias.
            var theme_options = RW._isNotEmptyString(options.theme) ? RWT[options.theme].options : {};

            /*
               To make proper diff between the options,
               the default options font size and line height
               must be changed according rating size.
               For example, if this won't be here and we'll set
               a rating with size = MEDIUM and lineHeight = "16px"
               then the lineHeight will disappear in the diff because
               global default line height is "16px" and not "20px" as
               it suppose to be for the size = MEDIUM.
            */
                var size = (RW._is(options.size) ?
                           options.size :
                           (RW._is(theme_options.size) ? theme_options.size : "")).toUpperCase();
                
                if (size !== "")
                {
                    RW._defaultOptions.advanced.font.size = RW._DEF_FONT_SIZE[size];
                    RW._defaultOptions.advanced.layout.lineHeight = RW._DEF_LINE_HEIGHT[size];
                }
                
                /*var dir = RW._is(options.advanced) && RW._is(options.advanced.layout) && RW._is(options.advanced.layout.dir) ? 
                            options.advanced.layout.dir :
                            RW.DIR.LTR;*/
                
            /*
               To make proper diff between the options,
               the default options direction should be set according to the language.
            */
                RW._defaultOptions.advanced.layout.dir = RWL[options.lng].dir;
                            

            // Get options diff compared to theme options.
            var theme_explicit_options = RW._Set.enrichedCopy(theme_options, RW._defaultOptions)
            

            /*
               Recover font size and line height.
            */
                if (size !== "")
                {
                    RW._defaultOptions.advanced.font.size = RW._DEF_FONT_SIZE.SMALL;
                    RW._defaultOptions.advanced.layout.lineHeight = RW._DEF_LINE_HEIGHT.SMALL;
                }
            
            // Revert to default direction.
                RW._defaultOptions.advanced.layout.dir = RW.DIR.LTR;
            
            // Update language text.
            if (RW._is(options.lng) && RW._is(RWL[options.lng])){
                theme_explicit_options.advanced.text = RWL[options.lng].text;
            }
            
            get_objects_diff(diff, theme_explicit_options, options);

            // Get explicit full options.
            //var explicit_options = RW._Set.enrichedCopy(options, theme_explicit_options);
            
            // If default font size or line height, remove from diff object.
            if (RW._is(diff.advanced) && 
                RW._is(diff.advanced.font) && 
                RW._is(diff.advanced.font.size) && 
                diff.advanced.font.size == RW._DEF_FONT_SIZE[options.size.toUpperCase()])
            {
                delete diff.advanced.font["size"];
            }
            if (RW._is(diff.advanced) && 
                RW._is(diff.advanced.layout) && 
                RW._is(diff.advanced.layout.lineHeight) && 
                diff.advanced.layout.lineHeight == RW._DEF_LINE_HEIGHT[options.size.toUpperCase()])
            {
                delete diff.advanced.layout["lineHeight"];
            }

            // If nero type - explicitly note that even if the type is specified in the theme.
            if (RW.TYPE.NERO === options.type)
                diff.type = RW.TYPE.NERO;
            
            // Clean empty object members.
            clean_empty_object_members(diff);

            // Delete syncing.
            if (RW._is(diff.sync))
                delete diff['sync'];

            // Explicitly set type.
            //diff.type = options.type;
            
            // Stringify clean diff object.
            tabs = RW._def(tabs, 4);
            
            // Defaults.
            prepand = RW._def(prepand, true);
            toJson = RW._def(toJson, false);
            
            var str = stringify_object(diff, tabs, space, eol, toJson);
            if (prepand && str != ""){
                str = "," + eol + str
            }
            
            return str;
        };
        
        var stringify_object = function(obj, tabs, space, eol, toJson)
        {
            space = RW._def(space, "&nbsp;");
            eol = RW._def(eol, "<br />");
            
            var str = rec_stringify_object(obj, tabs + 1, space, eol, toJson);
            if (str != "")
            {
                var pad = clone(space, tabs * 4);
                str = pad + "{" + eol + str + eol + pad + "}";
            }
            
            return str;
        };

        var rec_stringify_object = function(obj, tabs, space, eol, toJson)
        {
            var str = ""
            var pad = "";
            var pad = clone(space, tabs * 4);
            var wrap = (toJson ? '"' : '');
            
            for (var p in obj)
            {
                if (!str.isEmpty()){ str += "," + eol; }
                
                str += pad + wrap + p + wrap + ": ";
                
                if (RW._isString(obj[p])){
                    str += '"' + obj[p] + '"';
                }else if (typeof(obj[p]) == "object"){
                    str += "{" + eol +
                    rec_stringify_object(obj[p], tabs + 1, space, eol, toJson) + eol + pad + "}";
                }else{
                    str += obj[p];
                }
            }
            
            return str;
        };

        return {
            TYPES : ["js", "jq"],
            getSettingsJSON : function ()
            {
                var rw = RWM.STAR;
                if ($("#rw_rate_type input:checked").val() == RW.TYPE.NERO){
                    rw = RWM.NERO;
                }

                var diff = {};
                var options_str = stringify_options(rw.options, diff, 0, ' ', ' ', false, true);
                
                return options_str;
            },
            get : function ()
            {
                var rw = RWM.STAR;
                if ($("#rw_rate_type input:checked").val() == RW.TYPE.NERO){
                    rw = RWM.NERO;
                }
                
                var diff = {};
                var options_str = stringify_options(rw.options, diff, 4, _space, '<br>', false);
                
                var hidden_options_input = $("#rw_options_hidden");
                if (hidden_options_input.length > 0)
                {
                    //if (rw.options.type == RW.TYPE.NERO){ diff.type = RW.TYPE.NERO; }
                    hidden_options_input.val(encodeURIComponent(RW.JSON.stringify(diff)));
                    //if (rw.options.type == RW.TYPE.NERO){ delete diff["type"]; }
                }
                
                if ($("#rw_code_container").length == 0)
                    return;
                
                var is_empty = options_str.isEmpty();
                
                var selected_type_id = 0;
                var tabs = $("#rw_embed .rw-tabs div");

                for (var i = 0, len = tabs.length; i < len; i++)
                {
                    if ($(tabs[i]).hasClass("rw-selected"))
                    { 
                        selected_type_id = i; 
                        break;
                    }
                }
                
                options_str = options_str.replace(/^(&nbsp;)+/, '');
                
                var code =  '<code>' +
                            '<span class="com">&lt;!-- Add this element exactly where you want the Rating-Widget to appear --&gt;</span><br />' +
                            '&lt;<span class="elm">div</span> <span class="attr">class</span>=<span class="attr-val">"rw-ui-container ' +
                            'rw-urid-1"</span>&gt;&lt;/<span class="elm">div</span>&gt;<br /><br />' +
                            '<span class="com">&lt;!--<br />' + 
                            _tab + 'You can add more Rating-Widgets in your site,<br />' + 
                            _tab + 'just pick some new <i><b style="color: black;">rating-widget-unique-id</b></i> (must be positive integer).<br />' + 
                            _tab + 'For example <i><b style="color: black;">(rating-widget-unique-id = 38)</b></i>:<br />' + 
                            _tab + '&lt;div class="rw-ui-container rw-urid-38"&gt;&lt;/div&gt;<br />' + 
                            '--&gt;</span><br /><br />' +
                            '<span class="com">&lt;!-- Add this javascript code immediately before the &lt;/body&gt; tag --&gt;</span><br />' +
                            '&lt;<span class="elm">div</span> <span class="attr">class</span>=<span class="attr-val">"rw-js-container"</span>&gt;<br />' +
                            _tab + '&lt;<span class="elm">script</span> <span class="attr">type</span>=<span class="attr-val">"text/javascript"</span>&gt;<br />' +
                            '<span class="js">' +
                                    _tab2 + '<span class="com">// Async Rating-Widget initialization.</span><br />' +
                                    _tab2 + '<span class="word">function</span> RW_Async_Init(){<br />' +
                                    _tab3 + 'RW.init({<br />' +
                                    _tab4 + 'uid: ' +
                                    '<span class="str">"' + 
                                    (($("#rw_user_key").length > 0) ? $("#rw_user_key").val() : '<i><b style="color: black;">your-unique-user-key</b></i>') +
                                    '"</span>,<br />' +
                                    _tab4 +  'huid: ' +
                                    '<span class="str">"' + 
                                    (($("#rw_user_id").length > 0) ? $("#rw_user_id").val() : '<i><b style="color: black;">your-unique-user-id</b></i>') +
                                    '"</span>,<br />' +
                                    (options_str.isEmpty() ? '' : 
                                    _tab4 + 'options: ' +
                                    options_str +
                                    '<br>') +
                                    _tab3 + '});<br />' +
                                    _tab3 + 'RW.render();<br />' +
                                    _tab2 + '}<br /><br />' +
                                    _tab2 + '<span class="com">// Append Rating-Widget JavaScript library.</span><br />' +
                                    _tab2 + '<span class="word">if</span> (<span class="word">typeof</span>(RW) == <span class="str">"undefined"</span>){<br />' + 
                                    _tab3 + '(<span class="word">function</span>(){<br />' +
                                    _tab4 + 'var rw = document.createElement("script"),<br>' + 
                                    _tab5 + 'd = new Date(), ck = "Y" + d.getFullYear() + "M" + d.getMonth() + "D" + d.getDate();<br />' + 
                                    _tab4 + 'rw.type = "text/javascript"; rw.async = true;<br />' +
                                    _tab4 + 'rw.src = "//js.rating-widget.com/external.min.js?ck=" + ck;<br />' +
                                    _tab4 + 'var s = document.getElementsByTagName("script")[0];<br />' +
                                    _tab4 + 's.parentNode.insertBefore(rw, s);<br />' +
                                    _tab3 + '})();<br />' +
                                    _tab2 + '}<br /><br />' + 
                            _tab + '&lt;/<span class="elm">script</span>&gt;<br />' + 
                            '&lt;/<span class="elm">div</span>&gt;' + 
                            '</span>' +
                            '</code>';
                
                return code;
            },
            refresh : function()
            {
                $("#rw_code_container").html(this.get());
            }
        };
    }();
})(jQuery);

/* Color picker */
(function($, undef){
    var initLayout = function() {
        $('#colorSelector').ColorPicker({
            color: '#000',
            onShow: function (colpkr) {
                $(colpkr).fadeIn(500);
                return false;
            },
            onHide: function (colpkr) {
                $(colpkr).fadeOut(500);
                return false;
            },
            onChange: function (hsb, hex, rgb) {
                $('#colorSelector div').css('backgroundColor', '#' + hex);
                rwStar.setFontColor('#' + hex);
                rwNero.setFontColor('#' + hex);
                RWM.Code.refresh();
            }
        });
        $('#hoverColorSelector').ColorPicker({
            color: '#000',
            onShow: function (colpkr) {
                $(colpkr).fadeIn(500);
                return false;
            },
            onHide: function (colpkr) {
                $(colpkr).fadeOut(500);
                return false;
            },
            onChange: function (hsb, hex, rgb) {
                $('#hoverColorSelector div').css('backgroundColor', '#' + hex);
                rwStar.setFontHOverColor('#' + hex);
                rwNero.setFontHOverColor('#' + hex);
                RWM.Code.refresh();
            }
        });
    };

    if (typeof(EYE) !== typeof(undef))
        EYE.register(initLayout, 'init');
})(jQuery)

if (typeof(RW_HOOK_READY) === "undefined"){ RW_HOOK_READY = []; }
RW_HOOK_READY.push(function(){
    if (RWM.STAR instanceof RW.Rating)
    {
        rwStar = RWM.STAR = RWM.STAR.getInstances(0);
        rwNero = RWM.NERO = RWM.NERO.getInstances(0);
    }
});
