Drupal.AjaxLoad = Drupal.AjaxLoad || {};

/**
 * Load JavaScript and CSS files and data. 
 */
Drupal.AjaxLoad.loadFiles = function (target, response) {
  // Handle scripts.

  // Initialize the list of currently loaded external scripts.
  if (!Drupal.AjaxLoad.externalScripts) {
    Drupal.AjaxLoad.externalScripts = [];
    $('script[src]').each(function() {
      Drupal.AjaxLoad.externalScripts[Drupal.AjaxLoad.externalScripts.length] = $(this).attr('src');
    });
  }
  // See if we have any settings to extend. Do this first so that behaviors
  // can access the new settings easily.
  if (response.scripts) {
    // If there is not already a setting, create one.
    if (!Drupal.settings.ajaxLoad) {
      $.extend(Drupal.settings, {'ajaxLoad': {'loadPending': []}});
    }
    // Each Ajax operation needs its own counter.
    var index = parseInt(Drupal.settings.ajaxLoad.loadPending.length);
    Drupal.settings.ajaxLoad.loadPending[index] = 0;
    var newExternalScripts = 0;
    if (!response.__customSettings && response.scripts.setting) {
      $.extend(Drupal.settings, response.scripts.setting);
    }
    // Inline scripts will be handled separately.
    var types = ['core', 'module', 'theme'];
    $.each(types, function (i, type) {
      if (response.scripts[type]) {
        $.each(response.scripts[type], function (src, data) {
          // Load scripts.
          src = Drupal.settings.basePath + src;
          // Test if the script already exists.
          var found = false;
          for (var j = 0; j < Drupal.AjaxLoad.externalScripts.length; j++) {
            if (Drupal.AjaxLoad.externalScripts[j].indexOf(src) == 0) {
              found = true;
              break;
            }
          }
          if (!found) {
            $.getScript(src, function () {
              newExternalScripts++;
              Drupal.AjaxLoad.externalScripts[Drupal.AjaxLoad.externalScripts.length] = src;
              Drupal.AjaxLoad.loadComplete(index, target, response);
            });
            Drupal.settings.ajaxLoad.loadPending[index]++;
          }
        });
      }
    });
    // Ensure Drupal behaviors are attached to new content, even when no
    // new external scripts have been loaded.
    if (newExternalScripts == 0) {
      Drupal.attachBehaviors(target);
      // Ensure inline scripts are parsed after all external scripts have loaded.
      Drupal.AjaxLoad.loadInline(response);
    }
  }
  if (response.css) {
    // Handle stylesheets.
    var types = ['module', 'theme'];
    $.each(response.css, function (media, files) {
      $.each(types, function (i, type) {
        if (files[type]) {
          $.each(files[type], function (src, data) {
            src = Drupal.settings.basePath + src;
            // Test if the stylesheet already exists.
            if (!$('link[href*=' + src + ']').size()) {
              $('<link type="text/css" rel="stylesheet" media="' + media + '" href="' + src + '" />').appendTo('head');
            }
          });
        }
      });
    });
  }
};

/**
 * When all scripts have loaded, attach behaviors. 
 */
Drupal.AjaxLoad.loadInline = function(response) {
  // Handle inline scripts.
  if (response.scripts.inline) {
    $.each(response.scripts.inline, function (i, script) {
      // document.write calls would mess things up.
      if (script.code.indexOf('document.write') == -1) {
        eval(script.code);
      }
    });
  }
};

/**
 * When all scripts have loaded, attach behaviors. 
 */
Drupal.AjaxLoad.loadComplete = function(index, target, response) {
  Drupal.settings.ajaxLoad.loadPending[index]--;
  if (Drupal.settings.ajaxLoad.loadPending[index] == 0) {
    Drupal.attachBehaviors(target);
    // Ensure inline scripts are parsed after all external scripts have loaded.
    Drupal.AjaxLoad.loadInline(response);
  }
};
