/*
 * jQuery optionTree Plugin
 * version: 1.0.1
 * @requires jQuery v1.2 or later
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * @version $Id: jquery.optionTree.js 3 2009-03-03 00:06:13Z kkotowicz $
 * @author  Krzysztof Kotowicz <kkotowicz at gmail dot com>
 * @author  Esther Brunner <esther dot brunner at zeix dot com>
 */

/**
 * Converts passed JSON option tree into dynamically created <select> elements allowing you to
 * choose nested options.
 *
 * Adapted by Zeix for Kanton Zürich:
 *   - insert a label for each select
 *   - added ARIA attributes for better accessibilty
 *   - individual JSON request for each level (JSON filename must begin with "optiontree.")
 *
 * @param String url    - URL part to load JSON from (options.path + url + ".json";
 * @param array options - additional options (optional)
 */
(function($){
$.fn.optionTree = function(url, options) {

  options = $.extend({
    choose: 'Bitte wählen sie...',
    preselect: {},
    select_class: '',
    leaf_class: '',
    empty_value: '',
    path: ''
  }, options || {});
	
	var cleanName = function(name){
    return name.replace(/_*$/, '');
  };

  var removeNested = function(name){
    $("select[name^='" + name + "']").remove();
    $("label[for^='" + name + "']").remove();
    $("#" + name + "wrapper").remove();
  };

  var setValue = function(name, value){
    $("input[name='" + cleanName(name) + "']").val(value).change();
  };
  
  var tree;
  
  /**
   * JSON laden
   */
  this.load = function(){
	  var obj = this;
    url = options.path + url + ".json";
    $.getJSON(url, function(data){
	    tree = (data);
      return obj.process();
    });
  }
  
  /**
   * Ausführen
   */
  this.process = function(){
    var name = $(this).attr('name') + "_";

    // remove all dynamic options of lower levels
    removeNested(name);

    if (typeof tree == "object") { // many options exists for current nesting level

      // create select element with all the options
      // and bind onchange event to recursively call this function

      var $select = $("<select>").attr({'name':name,'id':name})
      .change(function(){
        $select.children().removeAttr("aria-selected");
        if (this.options[this.selectedIndex].value != '') {
          $(this).optionTree(tree[this.options[this.selectedIndex].value], options);
          $select.children().eq(this.selectedIndex).attr("aria-selected", "true");
        } else {
          removeNested(name + '_');
          setValue(name, options.empty_value);
        }
      });
      
      if ($(this).is('input')) $select.insertBefore(this);
      else $select.insertAfter($(this).parent());

      if (options.select_class) $select.addClass(options.select_class);

      $("<option>").html(options.choose).val('').appendTo($select);
      var label = name;
      $.each(tree, function(k, v) {
        if (k == "_label"){
          label = v;
        } else {
          var o = $("<option>").html(k).attr('value', k);
          if (options.leaf_class && typeof v != 'object') // this option is a leaf node
            o.addClass(options.leaf_class);
            o.appendTo($select);
          if (options.preselect && options.preselect[name] && options.preselect[name] == v) {
            o.get(0).selected = true;
            $select.change();
          }
        }
      });
      $select.wrap("<div class='row' id='"+ name +"wrapper' />");
      $select.before("<label for='" + name + "'> " + label + "</label>");
      

    } else { // single option is selected by the user (function called via onchange event())
      setValue(name, tree);
    }
  }

 if ((typeof url == "string") && (/dependingdropdown/.test(url))){
    this.load();
  } else {
    tree = url;
    return this.process();
  }
  
}
})(jQuery);

