/**
 * @file
 * Handles the JS for the views file browser.
 *
 * Note that this does not currently support multiple file selection
 */

(function ($) {

namespace('Drupal.media.browser.views');
Drupal.behaviors.mediaViews = {
  attach: function (context, settings) {

    // Make sure when pressing enter on text inputs, the form isn't submitted
    $('.ctools-auto-submit-full-form .views-exposed-form input:text, input:text.ctools-auto-submit', context)
      .filter(':not(.ctools-auto-submit-exclude)')
      .bind('keydown keyup', function (e) {
        if(e.keyCode === 13) {
          e.stopImmediatePropagation();
          e.preventDefault();
        }
      });
    // Disable the links on media items list
    $('.view-content ul.media-list-thumbnails a').click(function() {
      return false;
    });

    // Return focus to the correct part of the form.
    $('.ctools-auto-submit-full-form .ctools-auto-submit-click', context).click(function () {
      settings.lastFocus = document.activeElement.id;

      // Add custom class to allow customize look and feel of the field while processing ajax
      // This way user can have a better user expierence using the exposed filters
      $(document.activeElement).addClass('media-ajaxing-disabled');
      // Remove focus to the active element
      $(document.activeElement).blur();

      // Before go with ajax, suppress key events
      $('body').bind('keydown keyup', suppressKeyEvents);
    });
    if (settings.lastFocus) {
      // Note, we just use each() so we can declare variables in a new scope.
      $('#' + settings.lastFocus, context).each(function () {
        var $this = $(this),
            val = $this.val();

        $this.focus();

        // Clear and reset the value to put the cursor at the end.
        $this.val('');
        $this.val(val);

        // After input recover focus, remove suppression of key events
        $('body').unbind('keydown keyup', suppressKeyEvents);
      });
    }

    // We loop through the views listed in Drupal.settings.media.browser.views
    // and set them up individually.
    var views_ids = [];
    for(var key in Drupal.settings.media.browser.views){
      views_ids.push(key);
    }

    for (var i = 0; i < views_ids.length; i++) {
      var views_id = views_ids[i];
      for (var j= 0; j < Drupal.settings.media.browser.views[views_id].length; j++) {
        var views_display_id = Drupal.settings.media.browser.views[views_id][j],
          view = $('.view-id-' + views_id + '.view-display-id-' + views_display_id);
        if (view.length) {
          Drupal.media.browser.views.setup(view);
        }
      }
    }

    // Reset the state on tab-changes- bind on the 'select' event on the tabset
    $('#media-browser-tabset').bind('tabsselect', function(event, ui) {
      var view = $('.view', ui.panel);
      if (view.length) {
        Drupal.media.browser.views.select(view);
      }
    });

  }
}

/**
 * Event-function that is called with a view, when the tab containing that
 * view is selected.
 */
Drupal.media.browser.views.select = function(view) {
  // Reset the list of selected files
  Drupal.media.browser.selectMedia([]);

  // Reset all 'selected'-status.
  $('.view-content .media-item', view).removeClass('selected').parent().attr('aria-checked', 'false');
}

/**
 * Setup function. Called once for every Media Browser view.
 *
 * Sets up event-handlers for selecting items in the view.
 */
Drupal.media.browser.views.setup = function(view) {
  // Ensure we only setup each view once..
  if ($(view).hasClass('media-browser-views-processed')) {
    return;
  }

  // Reset the list of selected files
  Drupal.media.browser.selectMedia([]);

  // Catch double click to submit a single item.
  $('.view-content .media-item', view).bind('dblclick', function () {
    var fid = $(this).closest('.media-item[data-fid]').data('fid'),
      selectedFiles = new Array();

    // Remove all currently selected files
    $('.view-content .media-item', view).removeClass('selected');

    // Mark it as selected
    $(this).addClass('selected');

    // Because the files are added using drupal_add_js() and due to the fact
    // that drupal_get_js() runs a drupal_array_merge_deep() which re-numbers
    // numeric key values, we have to search in Drupal.settings.media.files
    // for the matching file ID rather than referencing it directly.
    for (index in Drupal.settings.media.files) {
      if (Drupal.settings.media.files[index].fid == fid) {
        selectedFiles.push(Drupal.settings.media.files[index]);

        // If multiple tabs contains the same file, it will be present in the
        // files-array multiple times, so we break out early so we don't have
        // it in the selectedFiles array multiple times.
        // This would interfer with multi-selection, so...
        break;
      }
    }
    Drupal.media.browser.selectMediaAndSubmit(selectedFiles);
  });


  function onSelectMediaItem() {
    var fid = $(this).closest('.media-item[data-fid]').data('fid'),
      selectedFiles = new Array();

    // Remove all currently selected files
    $('.view-content .media-item', view).removeClass('selected').parent().attr('aria-checked', 'false');

    // Mark it as selected
    $(this).addClass('selected').parent().attr('aria-checked', 'true');

    // Multiselect!
    if (Drupal.settings.media.browser.params.multiselect) {
      // Loop through the already selected files
      for (index in Drupal.media.browser.selectedMedia) {
        var currentFid = Drupal.media.browser.selectedMedia[index].fid;

        // If the current file exists in the list of already selected
        // files, we deselect instead of selecting
        if (currentFid == fid) {
          $(this).removeClass('selected').parent().attr('aria-checked', 'false');
          // If we change the fid, the later matching won't
          // add it back again because it can't find it.
          fid = NaN;

          // The previously selected file wasn't clicked, so we retain it
          // as an active file
        }
        else {
          // Add to list of already selected files
          selectedFiles.push(Drupal.media.browser.selectedMedia[index]);

          // Mark it as selected
          $('.view-content *[data-fid=' + currentFid + '].media-item', view).addClass('selected').parent().attr('aria-checked', 'true');
        }
      }
    }

    // Because the files are added using drupal_add_js() and due to the fact
    // that drupal_get_js() runs a drupal_array_merge_deep() which re-numbers
    // numeric key values, we have to search in Drupal.settings.media.files
    // for the matching file ID rather than referencing it directly.
    for (index in Drupal.settings.media.files) {
      if (Drupal.settings.media.files[index].fid == fid) {
        selectedFiles.push(Drupal.settings.media.files[index]);

        // If multiple tabs contains the same file, it will be present in the
        // files-array multiple times, so we break out early so we don't have
        // it in the selectedFiles array multiple times.
        // This would interfer with multi-selection, so...
        break;
      }
    }
    Drupal.media.browser.selectMedia(selectedFiles);
  }

  // Catch the click or space bar press on a media item.
  $('.view-content .media-item', view).bind('click', onSelectMediaItem);
  $('.view-content .media-item', view).parent().bind('keydown', function (evt) {
    if (evt.which == 32 || evt.which == 13) {
      onSelectMediaItem.call($('.media-item', this).get(0), evt);
      return false;
    }
  });

  // Add the processed class, so we dont accidentally process the same element twice..
  $(view).addClass('media-browser-views-processed');
}

/**
 * Helper callback to supress propagation and default behaviour of an event
 *
 * This function is used in this way to make private and accesible only for the current scope
 */
var suppressKeyEvents = function(e) {
  e.stopImmediatePropagation();
  e.preventDefault();
}

}(jQuery));
