// 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
// 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) {
  var elems = {
    pluginItem: function(args) {
      var id = args.id;
      var title = args.title;
      var desc = args.desc;
      var iconURL = args.iconURL;
      var $pluginItem = $('<li>').addClass('plugin-item').addClass(id);
      var $title = $('<span>').addClass('title').html(title);
      var $desc = $('<span>').addClass('desc').html(desc);
      var $icon = $('<span>').addClass('icon').append(
        $('<img>').attr({ src: iconURL })
      );

      $pluginItem.append(
        $icon, $title, $desc
      );

      return $pluginItem;
    },
    pluginListing: function(args) {
      var plugins = args.plugins;
      var $plugins = $('<ul>');
      var $pluginsListing = $('<div>').addClass('plugins-listing');

      $(plugins).each(function() {
        var plugin = this;
        var $plugin = elems.pluginItem({
          id: plugin.id,
          title: plugin.title,
          desc: plugin.desc,
          iconURL: 'plugins/' + plugin.id + '/icon.png'
        });
        var $browser = $('#browser .container');

        $plugin.click(function() {
          $browser.cloudBrowser('addPanel', {
            title: plugin.title,
            $parent: $('.panel:first'),
            complete: function($panel) {
              $panel.detailView({
                name: 'Plugin details',
                tabs: {
                  details: {
                    title: 'label.plugin.details',
                    fields: [
                      {
                        name: { label: 'label.name' }
                      },
                      {
                        desc: { label: 'label.description' },
                        externalLink: {
                          isExternalLink: true,
                          label: 'label.external.link'
                        }
                      },
                      {
                        authorName: { label: 'label.author.name' },
                        authorEmail: { label: 'label.author.email' },
                        id: { label: 'label.id' }
                      }
                    ],
                    dataProvider: function(args) {
                      args.response.success({ data: plugin });
                    }
                  }
                }
              });
            }
          });
        });

        $plugin.appendTo($plugins);
      });

      $pluginsListing.append($plugins);

      return $pluginsListing;
    }
  };

  cloudStack.uiCustom.plugins = function() {
    var plugins = cloudStack.plugins;

    return elems.pluginListing({
      plugins: $(plugins).map(function(index, pluginID) {
        var plugin = cloudStack.plugins[pluginID].config;

        return $.extend(plugin, { id: pluginID });
      })
    });
  };
}(jQuery, cloudStack));
