(function() {
    var replace = function(input, type) {
        var link = jQuery(
            '<a href="#" class="' + type
            + (input.attr('checked')
                ? ' ' + type + '-checked'
                : '') + '"></a>');

        input.hide();
        input.before(link);
        link.data('input', input);
        return link;
    };

    // Checkboxes
    var checkize = function(link, input) {
        input.change(function(e) {
            var checked = input.attr("checked");
            if (checked) {
                link.addClass('checkbox-checked');
            }
            else {
                link.removeClass('checkbox-checked');
            }
        });

        link.click(function(e){
            var checked = input.attr("checked");
            if (checked) {
                input.removeAttr('checked');
                link.removeClass('checkbox-checked');
            }
            else {
                input.attr('checked', 'checked');
                link.addClass('checkbox-checked');
            }
            input.change(); // trigger the change event, since this might not happen
            return false;
        });
    };

    // Radiobuttons
    var radize = function(link, link_siblings) {
        link.click(function(e) {
            var input = link.data('input');
            input.click();
            for (n in link_siblings) {
                var sib = link_siblings[n];
                var sib_input = sib.data('input');
                var checked = sib_input.attr('checked');
                if (checked) sib.addClass('radio-checked');
                else sib.removeClass('radio-checked');
            }
            return false;
        });
    };

    jQuery.fn.checkize = function() {
        var links = new Array();

        this.each(function(i, input){
            input = $(input);

            // Checkbox
            if(input.attr("type") == "checkbox") {
                checkize(replace(input, 'checkbox'), input);

            // Radiobutton
            } else if (input.attr("type") == "radio") {
                var name = input.attr("name");
                if(!links[name]) {
                    links[name] = new Array();
                }
                links[name].push(replace(input, 'radio'));
            }

        });

        // Handle radiobutton collections
        for(i in links) {
            for(j in links[i]) {
                radize(links[i][j], links[i]);
            }
        }
        return this;
    };
})();
