// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack, require) {
  if (!cloudStack.pluginAPI) {
    cloudStack.pluginAPI = {};
  }

  var loadCSS = function(path) {
    if (document.createStyleSheet) {
      // IE-compatible CSS loading
      document.createStyleSheet(path);
    } else {
      var $link = $('<link>');

      $link.attr({
        rel: 'stylesheet',
        type: 'text/css',
        href: path
      });

      $('html head').append($link);
    }
  };

  $.extend(cloudStack.pluginAPI, {
    ui: {
      pollAsyncJob: pollAsyncJobResult,
      apiCall: function(command, args) {
        $.ajax({
          url: createURL(command),
          data: args.data,
          success: args.success,
          error: function(json) {
            args.error(parseXMLHttpResponse(json));
          }
        });
      },
      addSection: function(section) {
        cloudStack.sections[section.id] = $.extend(section, {
          customIcon: 'plugins/' + section.id + '/icon.png'
        });
      },
      extend: function(obj) {
        $.extend(true, cloudStack, obj);
      }
    }
  });
  
  cloudStack.sections.plugins = {
    title: 'label.plugins',
    show: cloudStack.uiCustom.pluginListing
  };

  // Load
  $(['modules', 'plugins']).each(function() {
    var type = this;
    var paths = $(cloudStack[type]).map(function(index, id) {
      return type + '/' + id + '/' + id;
    }).toArray();

    // Load modules
    require(
      paths,
      function() {
        $(cloudStack[type]).map(function(index, id) {
          var basePath = type + '/' + id + '/';
          var css = basePath + id + '.css';
          var configJS = type == 'plugins' ? basePath + 'config' : null;

          if (configJS) {
            // Load config metadata
            require([configJS]);
          }

          // Execute module
          cloudStack[type][id](
            $.extend(true, {}, cloudStack.pluginAPI, {
              pluginAPI: {
                extend: function(api) {
                  cloudStack.pluginAPI[id] = api;
                }
              }
            })
          );
          loadCSS(css);
        });
      }
    );
  });
}(jQuery, cloudStack, require));
