// 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) {
    /**
     * Serialize form data as object
     */
    var getData = function($wizard, options) {
        if (!options) options = {};

        var $forms = $wizard.find('form').filter(function() {
            return !options.all ? !$(this).closest('.multi-edit').length : true;
        });
        var $physicalNetworkItems = $wizard.find(
            '.steps .setup-physical-network .select-container.multi'
        ).filter(':not(.disabled)');
        var $publicTrafficItems = $wizard.find(
            '.steps .setup-public-traffic .data-body .data-item');
        var $storageTrafficItems = $wizard.find(
            '.steps .setup-storage-traffic .data-body .data-item');
        var groupedForms = {};

        if ($physicalNetworkItems.find('li.traffic-type-draggable.storage').length) {
            $wizard.find('li.conditional.storage-traffic').show();
        } else {
            $wizard.find('li.conditional.storage-traffic').hide();
        }

        if (options.all) {
            return cloudStack.serializeForm($forms, {
                escapeSlashes: true
            });
        }

        // Group form fields together, by form ID
        $forms.each(function() {
            var $form = $(this);
            var id = $form.attr('rel');

            if (!id) return true;

            groupedForms[id] = cloudStack.serializeForm($form, {
                escapeSlashes: true
            });

            return true;
        });

        // Get physical network data
        groupedForms.physicalNetworks = $.map(
            $physicalNetworkItems,
            function(network) {
                var $network = $(network);
                var $guestForm = $wizard.find('form[guest-network-id=' + $network.index() + ']');
                var trafficTypeConfiguration = {};

                $network.find('.traffic-type-draggable').each(function() {
                    var $trafficType = $(this);
                    var trafficTypeID = $trafficType.attr('traffic-type-id');


                    trafficTypeConfiguration[trafficTypeID] = $trafficType.data('traffic-type-data');
                });

                return {
                    id: $network.index(),
                    name: $network.find('.field.name input[type=text]').val(),
                    isolationMethod: $network.find('.field.name select').val(),

                    // Traffic type list
                    trafficTypes: $.map(
                        $network.find('.traffic-type-draggable'),
                        function(trafficType) {
                            var $trafficType = $(trafficType);

                            return $trafficType.attr('traffic-type-id');
                        }
                    ),

                    // Traffic type configuration data
                    trafficTypeConfiguration: trafficTypeConfiguration,

                    guestConfiguration: $guestForm.length ? cloudStack.serializeForm($guestForm) : null
                };
            }
        );

        // Get public traffic data (multi-edit)
        groupedForms.publicTraffic = $.map(
            $publicTrafficItems,
            function(publicTrafficItem) {
                var $publicTrafficItem = $(publicTrafficItem);
                var publicTrafficData = {};
                var fields = [
                    'gateway',
                    'netmask',
                    'vlanid',
                    'startip',
                    'endip'
                ];

                $(fields).each(function() {
                    publicTrafficData[this] =
                        $publicTrafficItem.find('td.' + this + ' span').html();
                });

                return publicTrafficData;
            }
        );

        // Get storage traffic data (multi-edit)
        groupedForms.storageTraffic = $.map(
            $storageTrafficItems,
            function(storageTrafficItem) {
                var $storageTrafficItem = $(storageTrafficItem);
                var storageTrafficData = {};
                var fields = [
                    'gateway',
                    'netmask',
                    'vlan',
                    'startip',
                    'endip'
                ];

                $(fields).each(function() {
                    storageTrafficData[this] =
                        $storageTrafficItem.find('td.' + this + ' span').html();
                });

                return storageTrafficData;
            }
        );

        // Hack to fix forward slash JS error
        $.each(groupedForms, function(key1, value1) {
            $.each(value1, function(key2, value2) {
                if (typeof value2 == 'string') {
                    groupedForms[key1][key2] = value2.replace(/__forwardSlash__/g, '\/');
                }
            });
        });

        // Include zone network type
        if (groupedForms.zone) {
            groupedForms.zone.networkType = $forms.find('input[name=network-model]:checked').val();

            // Include zone isolation mode, supported for Advanced zones only
            if (groupedForms.zone.networkType == 'Advanced') {
                groupedForms.zone.sgEnabled = $forms.find('input[name=zone-advanced-sg-enabled]')
                    .is(':checked') ? true : false;
            }
        }

        return groupedForms;
    };

    /**
     * Handles validation for custom UI components
     */
    var customValidation = {
        networkRanges: function($form) {
            if ($form.closest('.multi-edit').find('.data-item').length) {
                return true;
            }

            cloudStack.dialog.notice({
                message: _l('message.please.add.at.lease.one.traffic.range')
            });
            return false;
        },

        physicalNetworks: function($form) {
            var $enabledPhysicalNetworks = $form.filter(':not(.disabled)').filter(function() {
                return $(this).find('.traffic-type-draggable').length;
            });
            var $trafficTypes = $enabledPhysicalNetworks.find('.traffic-type-draggable');
            var $configuredTrafficTypes = $trafficTypes.filter(function() {
                var $trafficType = $(this);

                return ($trafficType.data('traffic-type-data') != null);
            });

            if ($enabledPhysicalNetworks.length > 1 &&
                $configuredTrafficTypes.length != $trafficTypes.length) {
                cloudStack.dialog.notice({
                    message: _l('message.configure.all.traffic.types')
                });

                return false;
            }

            return true;
        }
    };

    /**
     * Determine if UI components in step should be custom-validated
     * (i.e., not a standard form)
     */
    var checkCustomValidation = function($step) {
        var $multiEditForm = $step.find('.multi-edit form');
        var $physicalNetworks = $step.find('.select-container.multi');
        var isCustomValidated;

        if ($multiEditForm.length) {
            isCustomValidated = customValidation.networkRanges($multiEditForm);
        } else if ($physicalNetworks.length) {
            isCustomValidated = customValidation.physicalNetworks($physicalNetworks);
        } else {
            isCustomValidated = true;
        }

        return isCustomValidated;
    };

    var isAdvancedNetwork = function($wizard) {
        return getData($wizard, {
            all: true
        })['network-model'] == 'Advanced';
    };

    /**
     * Setup physical network wizard UI
     */
    var physicalNetwork = {
        init: function($wizard) {
            var $existingPhysicalNetworks = physicalNetwork.getNetworks($wizard);

            // Initialize physical networks
            if (!$existingPhysicalNetworks.length) {
                physicalNetwork.add($wizard);
            } else if (!isAdvancedNetwork($wizard)) {
                $existingPhysicalNetworks.filter(':first').siblings().each(function() {
                    physicalNetwork.remove($(this));
                });
            }

            physicalNetwork.updateNetworks(physicalNetwork.getNetworks($wizard));

            $wizard.find('.traffic-types-drag-area ul li').removeClass('required disabled clone');

            // Setup clone traffic types
            $(physicalNetwork.cloneTrafficTypes($wizard)).each(function() {
                var trafficTypeID = this;

                $wizard.find('.traffic-types-drag-area ul li').filter(function() {
                    return $(this).hasClass(trafficTypeID);
                }).addClass('clone');
            });

            // Setup required traffic types
            $(physicalNetwork.requiredTrafficTypes($wizard)).each(function() {
                var trafficTypeID = this;
                var $firstPhysicalNetwork = physicalNetwork.getNetworks($wizard).filter(':first');

                // First physical network gets required traffic types
                physicalNetwork.assignTrafficType(trafficTypeID, $firstPhysicalNetwork);

                $wizard.find('.traffic-types-drag-area ul li').filter(function() {
                    return $(this).hasClass(trafficTypeID);
                }).addClass('required');
            });

            // Setup disabled traffic types
            $(physicalNetwork.disabledTrafficTypes($wizard)).each(function() {
                var trafficTypeID = this;
                var $trafficType = physicalNetwork.getTrafficType(this, $wizard);

                physicalNetwork.unassignTrafficType($trafficType);

                $wizard.find('.traffic-types-drag-area ul li').filter(function() {
                    return $(this).hasClass(trafficTypeID);
                }).addClass('disabled');
            });
        },

        /**
         * Traffic type edit dialog
         */
        editTrafficTypeDialog: function($trafficType) {
            var trafficData = $trafficType.data('traffic-type-data') ?
                $trafficType.data('traffic-type-data') : {};
            var hypervisor = getData($trafficType.closest('.zone-wizard')).zone.hypervisor;
            var zoneType = getData($trafficType.closest('.zone-wizard')).zone.networkType;
            var fields;

            if (hypervisor == 'VMware') {
                fields = {
                    vSwitchName: {
                        label: 'label.vswitch.name' ,
                        defaultValue: trafficData.vSwitchName
                    },
                    vlanId: {
                            label: 'label.vlan.id',
                        defaultValue: trafficData.vlanId
                    }
                };

                if(zoneType == 'Advanced') {
                    if(trafficData.vSwitchType == null) {
                         var useDvs = false;
                         $.ajax({
                             url: createURL('listConfigurations'),
                             data: {
                                 name: 'vmware.use.dvswitch'
                             },
                             async: false,
                             success: function(json) {
                                 if (json.listconfigurationsresponse.configuration[0].value == 'true') {
                                     useDvs = true;
                                 }
                             }
                         });
                         if (useDvs == true) {
                             var useNexusDvs = false;
                             $.ajax({
                                 url: createURL('listConfigurations'),
                                 data: {
                                     name: 'vmware.use.nexus.vswitch'
                                 },
                                 async: false,
                                 success: function(json) {
                                     if (json.listconfigurationsresponse.configuration[0].value == 'true') {
                                         useNexusDvs = true;
                                     }
                                 }
                             });
                             if (useNexusDvs == true) {
                                 trafficData.vSwitchType = 'nexusdvs';
                                 fields.vSwitchName.defaultValue = 'epp0';
                             } else {
                                 trafficData.vSwitchType = 'vmwaredvs';
                                 fields.vSwitchName.defaultValue = 'dvSwitch0';
                             }
                         } else { //useDvs == false
                             trafficData.vSwitchType = 'vmwaresvs';
                             fields.vSwitchName.defaultValue = 'vSwitch0';
                         }
                    }

                    $.extend(fields, {
                        vSwitchType: {
                                label: 'label.vSwitch.type',
                            select: function (args) {
                                args.response.success({
                                    data: [{
                                        id: 'nexusdvs',
                                        description: 'Cisco Nexus 1000v Distributed Virtual Switch'
                                    }, {
                                        id: 'vmwaresvs',
                                        description: 'VMware vNetwork Standard Virtual Switch'
                                    }, {
                                        id: 'vmwaredvs',
                                        description: 'VMware vNetwork Distributed Virtual Switch'
                                    }]
                                });
                            },
                            defaultValue: trafficData.vSwitchType
                        }
                    });
                }
            } else {
                fields = {
                    label: {
                        label: hypervisor + ' ' + _l('label.traffic.label'),
                        defaultValue: trafficData.label
                    }
                };
            }

            cloudStack.dialog.createForm({
                form: {
                    title: _l('label.edit.traffic.type'),
                    desc: _l('message.edit.traffic.type'),
                    fields: fields
                },

                after: function(args) {
                    $trafficType.data('traffic-type-data', args.data);
                }
            });
        },

        /**
         * Get required traffic type IDs for proper validation
         */
        requiredTrafficTypes: function($wizard) {
            return cloudStack.zoneWizard.requiredTrafficTypes({
                data: getData($wizard)
            });
        },

        /**
         * Get required traffic type IDs for proper validation
         */
        disabledTrafficTypes: function($wizard) {
            return cloudStack.zoneWizard.disabledTrafficTypes({
                data: getData($wizard)
            });
        },

        /**
         * Get clone-type traffic type IDs for proper validation
         */
        cloneTrafficTypes: function($wizard) {
            return cloudStack.zoneWizard.cloneTrafficTypes({
                data: getData($wizard)
            });
        },

        /**
         * Physical network step: Renumber network form items
         */
        renumberFormItems: function($container) {
            var $items = $container.find('.select-container.multi');

            $items.each(function() {
                var $item = $(this);
                var $networkName = $item.find('.field.name input[type=text]');
                var $networkId = $item.find('input[name=id]');
                var $networkTypes = $item.find('.field.network-types input');
                var index = $item.index();

                $networkId.val(index);
                $networkName.attr('name', 'physicalNetworks[' + index + ']' + '.name');
                $networkTypes.val(index);
            });
        },

        /**
         * Get main physical network wizard step container
         *
         * @param $elem Any elem within the container
         */
        getMainContainer: function($elem) {
            return $elem.closest('.steps .setup-physical-network');
        },

        /**
         * Returns traffic elem
         *
         * @param trafficTypeID ID of desired traffic type
         */
        getTrafficType: function(trafficTypeID, $container) {
            var $trafficType = $container.find('li.traffic-type-draggable').filter(function() {
                return $(this).attr('traffic-type-id') == trafficTypeID;
            });

            if (physicalNetwork.isTrafficTypeClone($trafficType) && !$container.closest('.select-container.multi').length) {
                // Get traffic type from original container
                return $trafficType.filter(function() {
                    return $(this).closest(
                        physicalNetwork.getOriginalTrafficContainer($trafficType)
                    ).length;
                });
            }

            return $trafficType;
        },

        /**
         * Get original drag container for traffic type elem
         *
         * @param $trafficType Traffic type elem
         */
        getOriginalTrafficContainer: function($trafficType) {
            var $dragContainer = physicalNetwork.getMainContainer($trafficType)
                .find('.traffic-types-drag-area ul > li')
                .filter(function() {
                    return $(this).hasClass($trafficType.attr('traffic-type-id'));
                })
                .find('ul');

            return $dragContainer;
        },

        /**
         * Get all physical networks
         *
         * @param $container Physical network step - main container
         */
        getNetworks: function($container) {
            return $container.find('.select-container.multi');
        },

        /**
         * Determine if traffic type is a 'cloned' type
         *
         * @param $trafficType
         */
        isTrafficTypeClone: function($trafficType) {
            return physicalNetwork.getOriginalTrafficContainer($trafficType).parent().hasClass('clone');
        },

        /**
         * Assigns traffic type to specified physical network
         *
         * @param trafficTypeID ID of desired traffic type
         * @param $physicalNetwork Physical network elem
         */
        assignTrafficType: function(trafficTypeID, $physicalNetwork, data) {
            var $container = physicalNetwork.getMainContainer($physicalNetwork);
            var $trafficType = physicalNetwork.getTrafficType(trafficTypeID, $container);
            var $dropArea = $physicalNetwork.find('.drop-container ul');

            if ($physicalNetwork.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').length) return false;

            if (physicalNetwork.isTrafficTypeClone($trafficType)) {
                if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).length) {
                    $trafficType = $trafficType.clone()
                        .removeClass('disabled')
                        .appendTo($dropArea)
                        .draggable(physicalNetwork.draggableOptions($physicalNetwork.closest('.zone-wizard')));
                } else {
                    return false;
                }
            } else {
                $trafficType.appendTo($dropArea);
            }

            if (data) {
                $trafficType.data('traffic-type-data', data);
            }

            physicalNetwork.updateNetworks($.merge($physicalNetwork, $physicalNetwork.siblings()));

            return $trafficType;
        },

        /**
         * Assigns traffic type to original drag container
         *
         * @param trafficTypeID ID of desired traffic type
         * @param $container Physical network wizard step container
         * @param $physicalNetwork (optional) Specific physical network to remove from -- only for clones
         */
        unassignTrafficType: function($trafficType) {
            var $wizard = $trafficType.closest('.zone-wizard');
            var $originalContainer = physicalNetwork.getOriginalTrafficContainer($trafficType);
            var $physicalNetworks = physicalNetwork.getNetworks($wizard);
            var trafficTypeID = $trafficType.attr('traffic-type-id');

            if (!physicalNetwork.isTrafficTypeClone($trafficType) &&
                $.inArray(trafficTypeID, physicalNetwork.requiredTrafficTypes($wizard)) == -1) {
                $trafficType.appendTo($originalContainer);
            } else {
                physicalNetwork.assignTrafficType(
                    trafficTypeID,
                    $physicalNetworks.filter(':first')
                );

                if (physicalNetwork.isTrafficTypeClone($trafficType) &&
                    $physicalNetworks.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').length > 1) {
                    $trafficType.remove();
                }
            }

            return $trafficType;
        },

        /**
         * Returns true if new physical network item needs to be added
         */
        needsNewNetwork: function($containers) {
            // Basic zones do not have multiple physical networks
            if (!isAdvancedNetwork($containers.closest('.zone-wizard')))
                return false;

            var $emptyContainers = $containers.filter(function() {
                return !$(this).find('li').length;
            });

            return !$emptyContainers.length ? $containers.length : false;
        },

        /**
         * Cleanup physical network containers
         */
        updateNetworks: function($containers) {
            var $mainContainer = physicalNetwork.getMainContainer($containers);
            var $allPhysicalNetworks = physicalNetwork.getNetworks($mainContainer);
            var containerTotal = isAdvancedNetwork($containers.closest('.zone-wizard')) ?
                2 : 1;

            $allPhysicalNetworks.each(function() {
                var $ul = $(this).find('.drop-container ul');

                if (!$(this).find('li').length) {
                    $(this).addClass('disabled');
                    $ul.fadeOut();
                } else {
                    $(this).removeClass('disabled');
                    $ul.show();
                }
            });

            $containers.each(function() {
                var $currentContainer = $(this);
                if (!$currentContainer.find('li').length &&
                    $containers.length > containerTotal) {
                    $currentContainer.remove();
                }
            });

            $containers = $containers.closest('.setup-physical-network')
                .find('.select-container.multi');

            if (physicalNetwork.needsNewNetwork($containers)) {
                physicalNetwork.add($mainContainer.parent());
            }

            $containers.filter(':first').find('.remove.physical-network').remove();

            return $containers;
        },

        /**
         * Default options for initializing traffic type draggables
         */
        draggableOptions: function($wizard) {
            return {
                appendTo: $wizard,
                helper: 'clone',

                // Events
                start: function(event, ui) {
                    $(this).addClass('disabled');
                },

                stop: function(event, ui) {
                    $(this).removeClass('disabled');
                },

                cancel: '.edit-traffic-type'
            };
        },

        /**
         * Physical network step: Generate new network element
         */
        add: function($wizard) {
            var $container = $wizard.find('.setup-physical-network .content.input-area form');
            var $physicalNetworkItem = $('<div>').addClass('select-container multi');
            var $deleteButton = $('<div>').addClass('button remove physical-network')
                .attr({
                    title: _l('label.remove.this.physical.network')
                })
                .append('<span>').addClass('icon').html('&nbsp;');
            var $icon = $('<div>').addClass('physical-network-icon');

            var $nameField = $('<div>').addClass('field name').append(
                $('<div>').addClass('name').append(
                    $('<label>').html(_l('label.physical.network.name'))
                ),
                $('<div>').addClass('value').append(
                    $('<input>').attr({
                        type: 'text'
                    }).addClass('required disallowSpecialCharacters')
                )
            );


            var ovsTunnelManager = false;
            $.ajax({
                url: createURL('listConfigurations'),
                data: {
                    name: 'sdn.ovs.controller'
                },
                dataType: "json",
                async: false,
                success: function(json) {
                    var items = json.listconfigurationsresponse.configuration; //2 entries returned: 'sdn.ovs.controller', 'sdn.ovs.controller.default.label'
                    $(items).each(function() {
                        if (this.name == 'sdn.ovs.controller') {
                            if (this.value == 'true' || this.value == true) {
                                ovsTunnelManager = true;
                            }
                            return false; //break each loop
                        }
                    });
                }
            });
            //when OVS tunnel manager is used
            //if(ovsTunnelManager == true) {
            //Advanced zone supports 2 isolation method(VLAN, GRE), so show dropdown including the 2 options
            if ($wizard.find('.select-network-model input:radio[name=network-model]:checked').val() == 'Advanced') {
                $nameField.append(
                    $('<div>').append(
                        $('<span style=\"font-size:11px;padding-right:5px;padding-left:40px\">').html(_l('label.isolation.method')),
                        $('<select>').append(
                            $('<option>').attr({
                                value: 'VLAN'
                            }).html('VLAN'),
                            $('<option>').attr({
                                value: 'GRE'
                            }).html('GRE'),
                            $('<option>').attr({
                                value: 'STT'
                            }).html('STT'),
                            $('<option>').attr({
                                value: 'BCF_SEGMENT'
                            }).html('BCF_SEGMENT'),
                            $('<option>').attr({
                                value: 'SSP'
                            }).html('SSP'),
                            $('<option>').attr({
                                value: 'VXLAN'
                            }).html('VXLAN'),
                            $('<option>').attr({
                                value: 'ODL'
                            }).html('ODL'),
                            $('<option>').attr({
                                value: 'L3VPN'
                            }).html('L3VPN'),
                            $('<option>').attr({
                                value: 'VCS'
                            }).html('VCS')
                        )
                    )
                );
            }
            //Basic zone supports only 1 isolation method (L3), so there is no point showing dropdown.
            //            }
            //when OVS tunnel manager is not used, isolationmethods parameter in createPhysicalNetwork API is ignored. So no showing dropdown.
            //isolationmethods parameter has not been used by network gurus so far. By default(i.e. when OVS tunnel manager is not used), networks are isolated with VLANs in Advanced zone, with L3 in basic zone.
            //No longer the case, as the Nicira stuff also depends on this now


            var $dropContainer = $('<div>').addClass('drop-container').append(
                $('<span>').addClass('empty-message').html(
                    'Drag and drop traffic types you would like to add here.'
                ),
                $('<ul>').hide()
            ).droppable({
                over: function(event, ui) {
                    var $ul = $(this).find('ul');

                    $ul.addClass('active');

                    if (!$ul.find('li').length) {
                        $(this).closest('.select-container.multi').removeClass('disabled');
                        $ul.fadeIn();
                    }
                },

                out: function(event, ui) {
                    var $ul = $(this).find('ul');

                    $ul.removeClass('active');
                    physicalNetwork.updateNetworks($(this).closest('.select-container.multi'));
                },

                drop: function(event, ui) {
                    var trafficTypeID = ui.draggable.attr('traffic-type-id');
                    var $physicalNetwork = $(this).closest('.select-container.multi');
                    var trafficTypeData = ui.draggable.data('traffic-type-data');

                    if (trafficTypeID == 'guest' &&
                        ui.draggable.closest('.select-container.multi').length) {
                        ui.draggable.remove();
                    }

                    physicalNetwork.assignTrafficType(trafficTypeID, $physicalNetwork, trafficTypeData);
                }
            });

            var $idField = $('<input>').attr({
                type: 'hidden',
                name: 'id',
                value: 0
            });

            // Initialize new default network form elem
            $physicalNetworkItem.append(
                $icon,
                $nameField,
                $idField,
                $dropContainer
            );

            // Only advanced zones can remove physical network
            if (isAdvancedNetwork($wizard)) {
                $physicalNetworkItem.prepend($deleteButton);
            }

            $physicalNetworkItem.hide().appendTo($container).fadeIn('fast');
            $physicalNetworkItem.find('.name input').val('Physical Network ' + parseInt($physicalNetworkItem.index() + 1));
            physicalNetwork.renumberFormItems($container);

            // Remove network action
            $physicalNetworkItem.find('.button.remove.physical-network').click(function() {
                physicalNetwork.remove($physicalNetworkItem);
            });

            $physicalNetworkItem.addClass('disabled'); // Since there are no traffic types yet

            return $physicalNetworkItem;
        },

        /**
         * Physical network step: Remove specified network element
         *
         * @param $physicalNetworkItem Physical network container to remove
         */
        remove: function($physicalNetworkItem) {
            var $container = $physicalNetworkItem.closest('.setup-physical-network .content.input-area form');
            var $trafficTypes = $physicalNetworkItem.find('li.traffic-type-draggable');

            $trafficTypes.each(function() {
                var trafficTypeID = $(this).attr('traffic-type-id');

                physicalNetwork.assignTrafficType(
                    trafficTypeID,
                    $physicalNetworkItem.prev()
                );
            });

            $trafficTypes.filter('.clone').remove();
            physicalNetwork.updateNetworks($physicalNetworkItem.parent().find('.multi'));
            $container.validate('refresh');
        }
    };

    /**
     * Configure guest traffic UI
     */
    var guestTraffic = {
        init: function($wizard, args) {
            var $physicalNetworks = physicalNetwork.getNetworks($wizard);
            var $tabs = guestTraffic.makeTabs($physicalNetworks, args);
            var $container = guestTraffic.getMainContainer($wizard);

            // Cleanup
            guestTraffic.remove($wizard);

            $container.find('.content form').hide();
            $tabs.appendTo($container.find('.content .select-container'));
            var $subnav = $container.find('ul.subnav').remove(); // Fix to avoid subnav becoming tab ul
            $container.tabs();
            $container.prepend($subnav);
            $container.find('.field').hide();
            $container.find('[rel=vlanRange]').show();
        },

        /**
         * Cleanup
         */
        remove: function($wizard) {
            var $container = guestTraffic.getMainContainer($wizard);

            // Cleanup
            $container.tabs('destroy');
            $container.find('.physical-network-item').remove();
            $container.find('.content form').show();
        },

        getMainContainer: function($wizard) {
            return $wizard.find('.steps .setup-guest-traffic');
        },

        makeTabs: function($physicalNetworks, args) {
            var $tabs = $('<ul></ul>').addClass('physical-network-item');
            var $content = $();

            // Only use networks w/ guest traffic type
            $physicalNetworks = $physicalNetworks.filter(function() {
                return $(this).find('li.guest').length;

                return true;
            });

            $physicalNetworks.each(function() {
                var $network = $(this);
                var $form = makeForm(args, 'guestTraffic', {});
                var refID = $network.find('input[name=id]').val();
                var networkID = 'physical-network-' + refID;

                $form.attr('guest-network-id', refID);

                $tabs.append($('<li></li>').append(
                    $('<a></a>')
                    .attr({
                        href: '#' + networkID
                    })
                    .html($network.find('.field.name input').val())
                ));
                $.merge(
                    $content,
                    $('<div></div>')
                    .addClass('physical-network-item')
                    .attr({
                        id: networkID
                    })
                    .append($form)
                );

                $form.validate();
            });

            $tabs.find('li:first').addClass('first');
            $tabs.find('li:last').addClass('last');

            return $.merge($tabs, $content);
        }
    };

    /**
     * Generate dynamic form, based on ID of form object given
     */
    var makeForm = function(args, id, formState) {
        var form = cloudStack.dialog.createForm({
            noDialog: true,
            context: $.extend(true, {}, cloudStack.context, {
                zones: [formState]
            }),
            form: {
                title: '',
                desc: '',
                fields: args.forms[id].fields
            },
            after: function(args) {}
        });

        var $form = form.$formContainer.find('form');

        // Cleanup form to follow zone wizard CSS naming
        $form.attr('rel', id);
        $form.find('input[type=submit]').remove();
        $form.find('.form-item').addClass('field').removeClass('form-item');
        $form.find('label.error').hide();
        $form.find('.form-item .name').each(function() {
            $(this).html($(this).find('label'));
        });
        $form.find('label[for]').each(function() {
            var forAttr = $(this).attr('for');
            $form.find('#' + forAttr).attr('id', id + '_' + forAttr);
            $(this).attr('for', id + '_' + forAttr)
        });

        $form.find('select, input').change(function() {
            cloudStack.evenOdd($form, '.field:visible', {
                even: function($row) {
                    $row.removeClass('odd');
                },
                odd: function($row) {
                    $row.addClass('odd');
                }
            });
        });

        return $form;
    };

    cloudStack.uiCustom.zoneWizard = function(args) {
        return function() {
            var $wizard = $('#template').find('div.zone-wizard').clone();
            var $progress = $wizard.find('div.progress ul li');
            var $steps = $wizard.find('div.steps').children().hide().filter(':not(.disabled)');

            $wizard.data('startfn', null);

            // Close wizard
            var close = function() {
                $wizard.dialog('destroy');
                $('div.overlay').fadeOut(function() {
                    $('div.overlay').remove();
                });
            };

            // Save and close wizard
            var completeAction = function() {
                var $launchStep = $wizard.find('.steps .review');
                var data = getData($wizard);
                var enableZoneAction = args.enableZoneAction;

                // Convert last step to launch appearance
                $launchStep.find('.main-desc').hide();
                $launchStep.find('.main-desc.launch').show();
                $launchStep.find('.launch-container').show();
                $launchStep.find('ul').html('');
                $wizard.find('.buttons').hide();
                $wizard.find('.button.previous').remove();

                var makeMessage = function(message, isError) {
                    var $li = $('<li>')
                        .addClass(!isError ? 'loading' : 'info')
                        .append(
                            $('<span>').addClass('icon').html('&nbsp;'),
                            $('<span>').addClass('text').html(message)
                    );
                    var $launchContainer = $launchStep.find('.launch-container');

                    $launchStep.find('ul').append($li);
                    $li.prev().removeClass('loading');
                    $launchContainer.scrollTop($launchContainer.height());

                    if (isError) {
                        $li.prev().addClass('error');
                    }

                };

                args.action({
                    data: data,
                    wizard: $wizard,
                    startFn: $wizard.data('startfn'),
                    uiSteps: $.map(
                        $wizard.find('.steps > div'),
                        function(step) {
                            return $(step).attr('zone-wizard-step-id');
                        }
                    ),
                    response: {
                        success: function(args) {
                            $launchStep.find('ul li').removeClass('loading');

                            var closeWindow = function() {
                                close();
                                $(window).trigger('cloudStack.fullRefresh');
                            };

                            var enableZone = function() {
                                makeMessage(_l('message.enabling.zone'));

                                enableZoneAction({
                                    formData: data,
                                    data: data,
                                    launchData: args.data,
                                    response: {
                                        success: function(args) {
                                            closeWindow();
                                        },

                                        error: function(message) {
                                            cloudStack.dialog.notice({
                                                message: _l('error.could.not.enable.zone') + ':</br>' + message
                                            });
                                        }
                                    }
                                });
                            };

                            cloudStack.dialog.confirm({
                                message: _l('message.zone.creation.complete.would.you.like.to.enable.this.zone'),
                                action: function() {
                                    enableZone();
                                },
                                cancelAction: function() {
                                    closeWindow();
                                }
                            });
                        },
                        error: function(stepID, message, start) {
                            var goNextOverride = function(event) {
                                $(this).unbind('click', goNextOverride);
                                showStep(stepID, false, {
                                    nextStep: 'launch'
                                });

                                return false;
                            };

                            $wizard.find('.buttons').show();
                            $wizard.find('.buttons .button.next')
                                .removeClass('final')
                                .html('<span>Fix errors</span>')
                                .click(goNextOverride);
                            makeMessage(_l('error.something.went.wrong.please.correct.the.following') + ':<br/>' + message, true);
                            $wizard.data('startfn', start);
                        },
                        message: makeMessage
                    }
                });
            };

            // Go to specified step in wizard,
            // updating nav items and diagram
            var showStep = function(index, goBack, options) {
                if (!options) options = {};

                if (typeof index == 'string') {
                    index = $wizard.find('[zone-wizard-step-id=' + index + ']').index() + 1;
                }

                var targetIndex = index - 1;

                if (index <= 1) targetIndex = 0;
                if (targetIndex == $steps.length) {
                    completeAction();
                }

                $steps.hide();
                $wizard.find('.buttons').show();

                var $targetStep = $($steps[targetIndex]).show();
                var $uiCustom = $targetStep.find('[ui-custom]');
                var formState = getData($wizard, {
                    all: true
                });
                var groupedFormState = getData($wizard);
                var formID = $targetStep.attr('zone-wizard-form');
                var stepPreFilter = cloudStack.zoneWizard.preFilters[
                    $targetStep.attr('zone-wizard-prefilter')
                ];

                // Bypass step check
                if (stepPreFilter && !stepPreFilter({
                    data: formState,
                    groupedData: groupedFormState
                })) {
                    return showStep(!goBack ? index + 1 : index - 1,
                        goBack
                    );
                }

                if (formID) {
                    if (!$targetStep.find('form').length) {
                        makeForm(args, formID, formState).appendTo($targetStep.find('.content.input-area .select-container'));

                        setTimeout(function() {
                            cloudStack.evenOdd($targetStep, '.field:visible', {
                                even: function() {},
                                odd: function($row) {
                                    $row.addClass('odd');
                                }
                            });
                        }, 50);
                    } else {
                        // Always re-activate selects
                        $targetStep.find('form select').each(function() {
                            var $select = $(this);
                            var selectFn = $select.data('dialog-select-fn');
                            var originalVal = $select.val();

                            if (selectFn) {
                                $select.html('');
                                selectFn({
                                    context: {
                                        zones: [formState]
                                    }
                                });
                                $select.val(originalVal);
                                $select.trigger('change');
                            }
                        });
                    }

                    if (args.forms[formID].preFilter) {
                        var preFilter = args.forms[formID].preFilter({
                            $form: $targetStep.find('form'),
                            data: formState
                        });
                    }
                }

                // Custom UI manipulations for specific steps
                switch ($targetStep.attr('zone-wizard-step-id')) {
                    case 'configureGuestTraffic':
                        if (formState['network-model'] == 'Advanced' && formState['zone-advanced-sg-enabled'] == undefined) {
                            guestTraffic.init($wizard, args); //initialize multiple tabs (tabs is as many as Guest Traffic types in multiple physical networks in Advanced Zone without SG)
                        } else {
                            guestTraffic.remove($wizard);
                        }
                        break;

                    case 'setupPhysicalNetwork':
                        if(!goBack) {
                            physicalNetwork.init($wizard);
                        }
                }

                if ($uiCustom.length) {
                    $uiCustom.each(function() {
                        var $item = $(this);
                        var id = $item.attr('ui-custom');

                        $item.replaceWith(
                            args.customUI[id]({
                                data: formState,
                                context: cloudStack.context
                            })
                        )
                    });
                }

                if (!targetIndex) {
                    $wizard.find('.button.previous').hide();
                } else {
                    $wizard.find('.button.previous').show();
                }

                var $nextButton = $wizard.find('.button.next');
                $nextButton.find('span').html(_l('label.next'));
                $nextButton.removeClass('final post-launch');

                // Show launch button if last step
                if ($targetStep.index() == $steps.length - 1 || options.nextStep) {
                    $nextButton.find('span').html(options.nextStep ? _l('label.save.changes') : _l('label.launch.zone'));
                    $nextButton.addClass('final');

                    if (options.nextStep) {
                        $nextButton.addClass('post-launch');
                    }
                }

                // Update progress bar
                var $targetProgress = $progress.removeClass('active').filter(function() {
                    return $(this).index() <= targetIndex;
                }).toggleClass('active');

                setTimeout(function() {
                    if (!$targetStep.find('input[type=radio]:checked').length) {
                        $targetStep.find('input[type=radio]:first').click();
                    }
                }, 50);

                $targetStep.find('form').validate();
            };

            // Events
            $wizard.find('select').change(function(event) {
                // Conditional selects (on step 4 mainly)
                var $target = $(this);
                var $tagged = $wizard.find('.conditional.vlan-type-tagged');
                var $untagged = $wizard.find('.conditional.vlan-type-untagged');
                var $accountSpecific = $wizard.find('.field.conditional.ip-scope-account-specific');

                // VLAN - tagged
                if ($target.is('[name=vlan-type]')) {
                    $tagged.hide();
                    $untagged.hide();
                    $accountSpecific.hide();

                    if ($target.val() == 'tagged') {
                        $untagged.hide();
                        $tagged.show();
                    } else if ($target.val() == 'untagged') {
                        $tagged.hide();
                        $untagged.show();
                    }

                    $.merge($tagged, $untagged).find('select:visible').trigger('change');

                    cloudStack.evenOdd($wizard, '.field:visible', {
                        even: function($elem) {
                            $elem.removeClass('odd');
                            $elem.addClass('even');
                        },
                        odd: function($elem) {
                            $elem.removeClass('even');
                            $elem.addClass('odd');
                        }
                    });

                    return true;
                }

                // IP Scope - acct. specific
                if ($target.is('select.ip-scope')) {
                    $accountSpecific.hide();
                    if ($target.val() == 'account-specific') $accountSpecific.show();

                    cloudStack.evenOdd($wizard, '.field:visible', {
                        even: function($elem) {
                            $elem.removeClass('odd');
                            $elem.addClass('even');
                        },
                        odd: function($elem) {
                            $elem.removeClass('even');
                            $elem.addClass('odd');
                        }
                    });
                }

                return true;
            });

            $wizard.click(function(event) {
                var $target = $(event.target);

                // Radio button
                if ($target.is('[type=radio]')) {

                    if ($target.attr('name') == 'network-model') {
                        var $inputs = $wizard.find('.isolation-mode').find('input[name=isolation-mode]').attr({
                            disabled: 'disabled'
                        });

                        var $selectArea = $target.closest('.select-area');

                        if ($target.val() == 'Advanced') {
                            $inputs.attr('disabled', false);
                            $selectArea.removeClass('disabled')
                                .find('.isolation-mode input').attr('disabled', false);
                        } else if ($target.val() == 'Basic') {
                            $selectArea.siblings('.advanced-zone').addClass('disabled')
                                .find('.isolation-mode input').attr('disabled', 'disabled');
                        }
                    }

                    return true;
                }

                // Checkbox
                if ($target.is('[type=checkbox]:checked')) {
                    $('div.conditional.' + $target.attr('name')).hide();

                    return true;
                } else if ($target.is('[type=checkbox]:unchecked')) {
                    $('div.conditional.' + $target.attr('name')).show();

                    return true;
                }

                // Next button
                if ($target.closest('div.button.next').length) {
                    var $step = $steps.filter(':visible');
                    // Validation
                    var $form = $('form:visible').filter(function() {
                        // Don't include multi-edit (validation happens separately)
                        return !$(this).closest('.multi-edit').length;
                    });

                    // Handle validation for custom UI components
                    var isCustomValidated = checkCustomValidation($step);
                    if (($form.length && !$form.valid()) || !isCustomValidated) {
                        if (($form && $form.find('.error:visible').length) || !isCustomValidated)
                            return false;
                    }

                    //when hypervisor is BareMetal (begin)
                    var data = getData($wizard);
                    if (('zone' in data) && (data.zone.hypervisor == 'BareMetal')) {
                        if ($('.zone-wizard:visible').find('#add_zone_guest_traffic_desc:visible').length > 0) { //$steps.filter(':visible').index() == 6
                            showStep('launch');
                            completeAction();
                            return false;
                        }
                    }
                    //when hypervisor is BareMetal (end)

                    if (!$target.closest('.button.next.final').length)
                        showStep($steps.filter(':visible').index() + 2);
                    else {
                        if ($target.closest('.button.next.final.post-launch').length) {
                            showStep('launch');
                        }

                        completeAction();
                    }

                    return false;
                }

                // Previous button
                if ($target.closest('div.button.previous').length) {
                    showStep($steps.filter(':visible').index(), true);

                    return false;
                }

                // Close button
                if ($target.closest('div.button.cancel').length) {
                    close();

                    return false;
                }

                // Edit link
                if ($target.closest('div.edit').length) {
                    var $edit = $target.closest('div.edit');

                    showStep($edit.find('a').attr('href'));

                    return false;
                }

                // Edit traffic type button
                var $editTrafficTypeButton = $target.closest('.drop-container .traffic-type-draggable .edit-traffic-type');
                var $trafficType = $editTrafficTypeButton.closest('.traffic-type-draggable');

                if ($editTrafficTypeButton.length) {
                    physicalNetwork.editTrafficTypeDialog($trafficType);

                    return false;
                }

                return true;
            });

            // Add/remove network action
            $wizard.find('.button.add.new-physical-network').click(function() {
                addPhysicalNetwork($wizard);
            });

            // Traffic type draggables
            $wizard.find('.traffic-type-draggable').draggable(physicalNetwork.draggableOptions($wizard));

            // For removing traffic types from physical network
            $wizard.find('.traffic-types-drag-area').droppable({
                drop: function(event, ui) {
                    physicalNetwork.unassignTrafficType(ui.draggable);

                    return true;
                }
            });

            showStep(1);

            var $dialog = $wizard.dialog({
                title: _l('label.installWizard.addZone.title'),
                closeOnEscape: false,
                width: 750,
                height: 665,
                resizable: false
            });
            
            return cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
        };
    };
})(jQuery, cloudStack);
