(function($) {
    $.fn.extend({
        styledradio: function(opts) {
            var $select, selectEl, containerID, $container, optionBoxID, $optionBox, opt, containerOffset,
                defaults = {
                    selectedCssClass: "StyledSelectedRadio",
                    checkboxCssClass: "StyledRadio",
                    focussedCssClass: "StyledFocussedRadio"
                };
            opts = $.extend(defaults, opts);
            if (this.length == 0 || this.get(0).tagName.toLowerCase() != "input") {
                return this;
            }
            selectEl = this[0];
            $select = $(selectEl);

            // Add container
            containerID = selectEl.id + "Container";
            $select.before("<div id=\"" + containerID + "\" class=\"" + selectEl.className + " " +
                (selectEl.checked ? opts.selectedCssClass : opts.checkboxCssClass) +
                "\"></div>");
            $container = $("#" + containerID);

            // Bind events
            var focusProxyID = selectEl.id + "FocusProxy";
            $select.before("<input type='text' id='" + focusProxyID + "' style='width: 0px; height: 0px; border: 1px solid #fff; font-size: 0px; line-height: 0px; margin: 0px; padding: 0px; color: #fff; float: left;'></input>");
            var $focusProxy = $("#" + focusProxyID);
            $container.bind("click", function(e) {
                $focusProxy.removeAttr("disabled");
                $focusProxy.get(0).focus();
                containerClicked(e);
                getAllRadios().each(function () {
                    $(this).triggerHandler("unselected");
                });
            });
            bindFocusEventSet();
            $focusProxy.bind("focus", function(e) {
                $container.addClass(opts.focussedCssClass);
            });
            $focusProxy.bind("blur", function(e) {
                $container.removeClass(opts.focussedCssClass);
                if (!$container.hasClass(opts.selectedCssClass)) {
                    $focusProxy.attr("disabled", "disabled");
                }
            });
            $container.bind("unselected", function(e) {
                if (!$container.hasClass(opts.selectedCssClass)) {
                    $focusProxy.attr("disabled", "disabled");
                }
            });
            if (!$container.hasClass(opts.selectedCssClass)) {
                $focusProxy.attr("disabled", "disabled");
            }

            // Hide original
            $select.hide();
            
            function bindFocusEventSet() {
                $focusProxy.bind("keydown.focusEventSet", function(e) {
                    var keynum;
                    if (!e) {
                        e = window.event;
                    }
                    keynum = e.keyCode ? e.keyCode : e.which;

                    if (keynum == 40 || keynum == 39) {
                        // DOWN ARROW or RIGHT ARROW pressed
                        var $radios =  getAllRadios();
                        var index = $radios.index($container);
                        index = (index + 1 == $radios.length) ? 0 : index + 1;
                        $radios.eq(index).triggerHandler("click");
                    } else if (keynum == 37 || keynum == 38) {
                        // DOWN ARROW or LEFT ARROW pressed
                        var $radios =  getAllRadios();
                        var index = $radios.index($container);
                        index = (index == 0) ? $radios.length - 1 : index - 1;
                        $radios.eq(index).triggerHandler("click");
                    }
                });
            }

            function containerClicked(e) {
                if (!selectEl.checked) {
                    selectEl.checked = !selectEl.checked;
                    if (selectEl.checked) {
                        $("div." + opts.selectedCssClass, $container.parent()).each(function() {
                            $(this).removeClass(opts.selectedCssClass);
                            $(this).addClass(opts.checkboxCssClass);
                        });
                        $container.removeClass(opts.checkboxCssClass);
                        $container.addClass(opts.selectedCssClass);
                    }
                }
            }
            
            function getAllRadios() {
                return $("div." + opts.checkboxCssClass + ",div." + opts.selectedCssClass, $container.parent());
            }
        }
    });
})(jQuery);
