// 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() {
                    var $mainSection = $('#navigation ul li').filter('.' + plugin.id);

                    if ($mainSection.length) {
                        $mainSection.click();

                        return;
                    }

                    $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.pluginListing = 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));
