(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;
	};
})();
