(function ($) {
    function updateHidden(original) {
        $(original)
          .children().each(function () {
              this.selected = false;
          }).end()
          .siblings().contents('select').children().each(function () {
              if (this.selected) {
                  if (this.index>0) {
                      $(original)[0][this.index-1].selected = true;
                  }
              }
          });
    }

    function createDropdown(original, selectedIndex, first) {
        original = $(original);
        var cloned =  $("<select style='display: inline'></select>")[0];
        $(cloned)
          .attr("class", original.attr("class"))
          .append($('<option value=""></option>'))
          .append(original.children().clone())
          .show()
          .appendTo($(original).parent())
          .change(function () {
              updateHidden(original);
              selectedIndex = this.selectedIndex;
              // If the empty option has been selected on a dropdown
              // that is not the first then we want to delete that
              // dropdown.
              if (this.selectedIndex == 0 && !first) {
                  redisplay(original)
              }
          })
        .wrap('<div class="selection"></div>');
        $(cloned)
          .after($('<a class="remove_selection" href="#"><img src="/media/img/minus.png"/></a>')
                 .click(function (event) {
                     event.stopPropagation();
                     event.preventDefault();
                     if(original.parent().children().size() > 2) {
                         $(cloned).parent(".selection").remove();
                     }
                     updateHidden(original);
                 }));
        $(cloned)
          .after($('&nbsp;<a class="add_selection" href="#"><img src="/media/img/plus.png"/></a>')
                 .click(function (event) {
                     event.stopPropagation();
                     event.preventDefault();
                     createDropdown(original);
                 }));
        cloned.id = undefined;
        cloned.name = undefined;
        function focus() {
            cloned[cloned.selectedIndex].text = cloned[cloned.selectedIndex].original || cloned[cloned.selectedIndex].text;
        }
        function blur() {
            cloned[cloned.selectedIndex].original = cloned[cloned.selectedIndex].text;
            cloned[cloned.selectedIndex].text = cloned[cloned.selectedIndex].text.replace(/^[- ]*/, '');
        }
        if (selectedIndex != undefined) {
            selectedIndex = selectedIndex + 1;
            cloned.selectedIndex = selectedIndex;
            focus();
            blur();
        } else {
            cloned.selectedIndex = 0;
        }
        $(cloned).focus(focus).blur(blur);
        setTimeout(function () {updateHidden(original);}, 1);
    }
    
    function redisplay(original) {
        original = $(original);
        // Remove all existing dropdowns
        // Iterate over each option in the original (hidden) select
        // For all selected options create a seperate dropdown
        var selectedCount = 0;
        original
          .siblings().remove().end()
          .hide()
          .children().each(function () {
              if (this.selected) {
                  selectedCount += 1;
                  createDropdown(original, this.index, selectedCount==0);
              }
          });
        if (selectedCount == 0) {
            createDropdown(original, undefined, true);
        }
    }
    
    $.fn.categoryTree = function () {
        this.each(function () {
            $(this).wrap($('<div class="categorytree"></div>'));
            redisplay(this);
            $(this).change(function () {
                redisplay(this);
            });        
        });
    };

    $(document).ready(function () {
        $('.categorytree').categoryTree();
    });
})(jQuery);
