(function ($) {
  // Polyfill for jQuery less than 1.6.
  if (typeof $.fn.prop != 'function') {
    jQuery.fn.extend({
      prop: jQuery.fn.attr
    });
  }

  Drupal.behaviors.vbo = {
    attach: function(context) {
      $('.vbo-views-form', context).each(function() {
        Drupal.vbo.initTableBehaviors(this);
        Drupal.vbo.initGenericBehaviors(this);
        Drupal.vbo.toggleButtonsState(this);
      });
    }
  }

  Drupal.vbo = Drupal.vbo || {};
  Drupal.vbo.initTableBehaviors = function(form) {
    // If the table is not grouped, "Select all on this page / all pages"
    // markup gets inserted below the table header.
    var selectAllMarkup = $('.vbo-table-select-all-markup', form);
    if (selectAllMarkup.length) {
      $('.views-table > tbody', form).prepend('<tr class="views-table-row-select-all even">></tr>');
      var colspan = $('table th', form).length;
      $('.views-table-row-select-all', form).html('<td colspan="' + colspan + '">' + selectAllMarkup.html() + '</td>');

      $('.vbo-table-select-all-pages', form).click(function() {
        Drupal.vbo.tableSelectAllPages(form);
        return false;
      });
      $('.vbo-table-select-this-page', form).click(function() {
        Drupal.vbo.tableSelectThisPage(form);
        return false;
      });
    }

    $('.vbo-table-select-all', form).show();
    // This is the "select all" checkbox in (each) table header.
    $('.vbo-table-select-all', form).click(function() {
      var table = $(this).closest('table')[0];
      $('input[id^="edit-views-bulk-operations"]:not(:disabled)', table).prop('checked', this.checked);
      Drupal.vbo.toggleButtonsState(form);

      // Toggle the visibility of the "select all" row (if any).
      if (this.checked) {
        $('.views-table-row-select-all', table).show();
      }
      else {
        $('.views-table-row-select-all', table).hide();
        // Disable "select all across pages".
        Drupal.vbo.tableSelectThisPage(form);
      }
    });

    // Set up the ability to click anywhere on the row to select it.
    if (Drupal.settings.vbo.row_clickable) {
      $('.views-table tbody tr', form).click(function(event) {
        if (event.target.tagName.toLowerCase() != 'input' && event.target.tagName.toLowerCase() != 'a') {
          $('input[id^="edit-views-bulk-operations"]:not(:disabled)', this).each(function() {
            var checked = this.checked;
            // trigger() toggles the checkmark *after* the event is set,
            // whereas manually clicking the checkbox toggles it *beforehand*.
            // that's why we manually set the checkmark first, then trigger the
            // event (so that listeners get notified), then re-set the checkmark
            // which the trigger will have toggled. yuck!
            this.checked = !checked;
            $(this).trigger('click');
            this.checked = !checked;
          });
        }
      });
    }
  }

  Drupal.vbo.tableSelectAllPages = function(form) {
    $('.vbo-table-this-page', form).hide();
    $('.vbo-table-all-pages', form).show();
    // Modify the value of the hidden form field.
    $('.select-all-rows', form).val('1');
  }
  Drupal.vbo.tableSelectThisPage = function(form) {
    $('.vbo-table-all-pages', form).hide();
    $('.vbo-table-this-page', form).show();
    // Modify the value of the hidden form field.
    $('.select-all-rows', form).val('0');
  }

  Drupal.vbo.initGenericBehaviors = function(form) {
    // Show the "select all" fieldset.
    $('.vbo-select-all-markup', form).show();

    $('.vbo-select-this-page', form).click(function() {
      $('input[id^="edit-views-bulk-operations"]', form).prop('checked', this.checked);
      Drupal.vbo.toggleButtonsState(form);
      $('.vbo-select-all-pages', form).prop('checked', false);

      // Toggle the "select all" checkbox in grouped tables (if any).
      $('.vbo-table-select-all', form).prop('checked', this.checked);
    });
    $('.vbo-select-all-pages', form).click(function() {
      $('input[id^="edit-views-bulk-operations"]', form).prop('checked', this.checked);
      Drupal.vbo.toggleButtonsState(form);
      $('.vbo-select-this-page', form).prop('checked', false);

      // Toggle the "select all" checkbox in grouped tables (if any).
      $('.vbo-table-select-all', form).prop('checked', this.checked);

      // Modify the value of the hidden form field.
      $('.select-all-rows', form).val(this.checked);
    });

    // Toggle submit buttons' "disabled" states with the state of the operation
    // selectbox.
    $('select[name="operation"]', form).change(function () {
      Drupal.vbo.toggleButtonsState(form);
    });

    $('.vbo-select', form).click(function() {
      // If a checkbox was deselected, uncheck any "select all" checkboxes.
      if (!this.checked) {
        $('.vbo-select-this-page', form).prop('checked', false);
        $('.vbo-select-all-pages', form).prop('checked', false);
        // Modify the value of the hidden form field.
        $('.select-all-rows', form).val('0')

        var table = $(this).closest('table')[0];
        if (table) {
          // Uncheck the "select all" checkbox in the table header.
          $('.vbo-table-select-all', table).prop('checked', false);

          // If there's a "select all" row, hide it.
          if ($('.vbo-table-select-this-page', table).length) {
            $('.views-table-row-select-all', table).hide();
            // Disable "select all across pages".
            Drupal.vbo.tableSelectThisPage(form);
          }
        }
      }

      Drupal.vbo.toggleButtonsState(form);
    });
  }

  Drupal.vbo.toggleButtonsState = function(form) {
    // If no rows are checked, disable any form submit actions.
    var selectbox = $('select[name="operation"]', form);
    var checkedCheckboxes = $('.vbo-select:checked', form);
    var buttons = $('[id^="edit-select"] input[type="submit"]', form);

    if (selectbox.length) {
      var has_selection = checkedCheckboxes.length && selectbox.val() !== '0';
      buttons.prop('disabled', !has_selection);
    }
    else {
      buttons.prop('disabled', !checkedCheckboxes.length);
    }
  };

})(jQuery);
