// 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, $) {
    cloudStack.uiCustom.affinity = function(args) {
        var listView = args.listView;
        var action = args.action;
        var tierSelect = args.tierSelect;

        return function(args) {
            var context = args.context;
            var $instanceRow = args.$instanceRow;

            var vmList = function(args) {
                // Create a listing of instances, based on limited information
                // from main instances list view
                var $listView;
                var instances = $.extend(true, {}, args.listView, {
                    context: context,
                    uiCustom: true
                });

                instances.listView.actions = {
                    select: {
                        label: _l('label.select.instance'),
                        type: 'checkbox',
                        action: {
                            uiCustom: function(args) {
                                var $item = args.$item;
                                var $input = $item.find('td.actions input:visible');

                                if ($input.attr('type') == 'checkbox') {
                                    if ($input.is(':checked'))
                                        $item.addClass('multi-edit-selected');
                                    else
                                        $item.removeClass('multi-edit-selected');
                                } else {
                                    $item.siblings().removeClass('multi-edit-selected');
                                    $item.addClass('multi-edit-selected');
                                }
                            }
                        }
                    }
                };

                $listView = $('<div>').listView(instances);

                // Change action label
                $listView.find('th.actions').html(_l('label.select'));

                return $listView;
            };

            var $dataList = vmList({
                listView: listView
            }).dialog({
                dialogClass: 'multi-edit-add-list panel',
                width: 825,
                title: _l('label.affinity.groups'),
                buttons: [{
                    text: _l('label.apply'),
                    'class': 'ok',
                    click: function() {
                        if ($dataList.find('.tier-select select').val() == -1) {
                            cloudStack.dialog.notice({
                                message: ('Please select a tier')
                            });
                            return false;
                        }

                        var complete = args.complete;
                        var start = args.start;

                        start();
                        $dataList.fadeOut(function() {
                            action({
                                tierID: $dataList.find('.tier-select select').val(),
                                _subselect: $dataList.find('tr.multi-edit-selected .subselect select').val(),
                                context: $.extend(true, {}, context, {
                                    affinityGroups: $dataList.find('tbody tr').map(function(index, elem) {
                                        var itemData = $(elem).data('json-obj');
                                        itemData._isSelected = false;

                                        if ($(elem).hasClass('multi-edit-selected')) {
                                            itemData._isSelected = true;
                                        }

                                        return itemData;
                                    })
                                }),
                                response: {
                                    success: function(args) {
                                        complete({
                                            _custom: args._custom,
                                            $item: $instanceRow
                                        });
                                    },
                                    error: function(args) {
                                        cloudStack.dialog.notice({
                                            message: args
                                        });
                                    }
                                }
                            });
                            $dataList.remove();
                        });

                        $('div.overlay').fadeOut(function() {
                            $('div.overlay').remove();
                            $(':ui-dialog').dialog('destroy');
                        });
                    }
                }, {
                    text: _l('label.cancel'),
                    'class': 'cancel',
                    click: function() {
                        $dataList.fadeOut(function() {
                            $dataList.remove();
                        });
                        $('div.overlay').fadeOut(function() {
                            $('div.overlay').remove();
                            $(':ui-dialog').dialog('destroy');
                        });
                    }
                }]
            }).parent('.ui-dialog').overlay();

            // Add tier select dialog
            if (tierSelect) {
                var $toolbar = $dataList.find('.toolbar');
                var $tierSelect = $('<div>').addClass('filters tier-select').prependTo($toolbar);
                var $tierSelectLabel = $('<label>').html('Select tier').appendTo($tierSelect);
                var $tierSelectInput = $('<select>').appendTo($tierSelect);

                // Get tier data
                tierSelect({
                    context: context,
                    $tierSelect: $tierSelect,
                    response: {
                        success: function(args) {
                            var data = args.data;

                            $(data).map(function(index, item) {
                                var $option = $('<option>');

                                $option.attr('value', item.id);
                                $option.html(item.description);
                                $option.appendTo($tierSelectInput);
                            });
                        },
                        error: function(message) {
                            cloudStack.dialog.notice({
                                message: message ? message : 'Could not retrieve VPC tiers'
                            });
                        }
                    }
                });
            }
        };
    };
}(cloudStack, jQuery));
