text: /**
   * Created by hujj on 2017/4/22.
   */
  /**
   Project: CheckTree jQuery Plugin
   Version: 0.2
   Project Website: http://static.geewax.org/checktree/
   Author: JJ Geewax <jj@geewax.org>
  
   License:
   The CheckTree jQuery plugin is currently available for use in all personal or
   commercial projects under both MIT and GPL licenses. This means that you can choose
   the license that best suits your project, and use it accordingly.
   */
  (function(jQuery) {
      jQuery.fn.checkTree = function(settings) {
  
          settings = jQuery.extend({
              /* Callbacks
               The callbacks should be functions that take one argument. The checkbox tree
               will return the jQuery wrapped LI element of the item that was checked/expanded.
               */
              onExpand: null,
              onCollapse: null,
              onCheck: null,
              onUnCheck: null,
              onHalfCheck: null,
              onLabelHoverOver: null,
              onLabelHoverOut: null,
  
              /* Valid choices: 'expand', 'check' */
              labelAction: "expand",
  
              // Debug (currently does nothing)
              debug: false
          }, settings);
  
          var $tree = this;
  
          $tree.find("li")
          // Hide all of the sub-trees
              .find("ul")
              .hide()
              .end()
  
              // Hide all checkbox inputs
              .find(":checkbox")
              .change(function() {
                  // Fired when the children of this checkbox have changed.
                  // Children can change the state of a parent based on what they do as a group.
                  var $all = jQuery(this).siblings("ul").find(":checkbox");
                  var $checked = $all.filter(":checked");
  
                  // All children are checked
                  if ($all.length == $checked.length) {
                      jQuery(this)
                          .attr("checked", "checked")
                          .siblings(".checkbox")
                          .removeClass("half_checked")
                          .addClass("checked")
                      ;
                      // Fire parent's onCheck callback
                      if (settings.onCheck) settings.onCheck(jQuery(this).parent());
                  }
  
                  // All children are unchecked
                  else if($checked.length == 0) {
                      jQuery(this)
                          .attr("checked", "")
                          .siblings(".checkbox")
                          .removeClass("checked")
                          .removeClass("half_checked")
                      ;
                      // Fire parent's onUnCheck callback
                      if (settings.onUnCheck) settings.onUnCheck(jQuery(this).parent());
                  }
  
                  // Some children are checked, makes the parent in a half checked state.
                  else {
                      // Fire parent's onHalfCheck callback only if it's going to change
                      if (settings.onHalfCheck && !jQuery(this).siblings(".checkbox").hasClass("half_checked"))
                          settings.onHalfCheck(jQuery(this).parent());
  
                      jQuery(this)
                          .attr("checked", "")
                          .siblings(".checkbox")
                          .removeClass("checked")
                          .addClass("half_checked")
                      ;
                  }
              })
              .attr("checked", "")
              .hide()
              .end()
  
  
              .find("label")
              // Clicking the labels should expand the children
              .click(function() {
                  var action = settings.labelAction;
                  switch(settings.labelAction) {
                      case 'expand':
                          jQuery(this).siblings(".arrow").click();
                          break;
                      case 'check':
                          jQuery(this).siblings(".checkbox").click();
                          break;
                  }
              })
  
              // Add a hover class to the labels when hovering
              .hover(
                  function() {
                      jQuery(this).addClass("hover");
                      if (settings.onLabelHoverOver) settings.onLabelHoverOver(jQuery(this).parent());
                  },
                  function() {
                      jQuery(this).removeClass("hover");
                      if (settings.onLabelHoverOut) settings.onLabelHoverOut(jQuery(this).parent());
                  }
              )
              .end()
  
              .each(function() {
                  // Create the image for the arrow (to expand and collapse the hidden trees)
                  var $arrow = jQuery('<div class="arrow"></div>');
  
                  // If it has children:
                  if (jQuery(this).is(":has(ul)")) {
                      $arrow.addClass("collapsed"); // Should start collapsed
  
                      // When you click the image, toggle the child list
                      $arrow.click(function() {
                          jQuery(this).siblings("ul").toggle();
  
                          if (jQuery(this).hasClass("collapsed")) {
                              //toggled = settings.expandedarrow;
                              jQuery(this)
                                  .addClass("expanded")
                                  .removeClass("collapsed")
                              ;
                              if (settings.onExpand) settings.onExpand(jQuery(this).parent());
                          }
                          else {
                              //toggled = settings.collapsedarrow;
                              jQuery(this)
                                  .addClass("collapsed")
                                  .removeClass("expanded")
                              ;
                              if (settings.onCollapse) settings.onCollapse(jQuery(this).parent());
                          }
                      });
                  }
  
                  // Create the image for the checkbox next to the label
                  var $checkbox = jQuery('<div class="checkbox"></div>');
  
                  // When you click the checkbox, it should do the checking/unchecking
                  $checkbox.click(function() {
                      // Make the current class checked
                      jQuery(this)
                      // if it's half checked, its now either checked or unchecked
                          .removeClass("half_checked")
                          .toggleClass("checked")
  
                          // Send a click event to the checkbox to toggle it as well
                          .siblings(":checkbox").click()
                      ;
  
                      // Check/uncheck children depending on our status.
                      if (jQuery(this).hasClass("checked")) {
                          // Fire the check callback for this parent
                          if (settings.onCheck) settings.onCheck(jQuery(this).parent());
  
                          jQuery(this).siblings("ul").find(".checkbox").not(".checked")
                              .removeClass("half_checked")
                              .addClass("checked")
                              .each(function() {
                                  if (settings.onCheck) settings.onCheck(jQuery(this).parent());
                              })
                              .siblings(":checkbox")
                              .attr("checked", "checked")
                          ;
                      }
                      else {
                          // Fire the uncheck callback for this parent
                          if (settings.onUnCheck) settings.onUnCheck(jQuery(this).parent());
  
                          jQuery(this).siblings("ul").find(".checkbox").filter(".checked")
                              .removeClass("half_checked")
                              .removeClass("checked")
                              .each(function() {
                                  if (settings.onUnCheck) settings.onUnCheck(jQuery(this).parent());
                              })
                              .siblings(":checkbox")
                              .attr("checked", "")
                          ;
                      }
                      // Tell our parent checkbox that we've changed
                      jQuery(this).parents("ul").siblings(":checkbox").change();
                  });
  
                  // Prepend the arrow and checkbox images to the front of the LI
                  jQuery(this)
                      .prepend($checkbox)
                      .prepend($arrow)
                  ;
              })
          ;
  
          return $tree;
      };
  })(jQuery);