// 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').size() : 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').size()) {
            $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.size() ? 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').size()) {
                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').size();
            });
            var $trafficTypes = $enabledPhysicalNetworks.find('.traffic-type-draggable');
            var $configuredTrafficTypes = $trafficTypes.filter(function() {
                var $trafficType = $(this);

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

            if ($enabledPhysicalNetworks.size() > 1 &&
                $configuredTrafficTypes.size() != $trafficTypes.size()) {
                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.size()) {
            isCustomValidated = customValidation.networkRanges($multiEditForm);
        } else if ($physicalNetworks.size()) {
            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.size()) {
                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($trafficType.hasClass('guest') || $trafficType.hasClass('public')) {            		
	            		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').size()) {
                // Get traffic type from original container
                return $trafficType.filter(function() {
                    return $(this).closest(
                        physicalNetwork.getOriginalTrafficContainer($trafficType)
                    ).size();
                });
            }

            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 + ']').size()) return false;

            if (physicalNetwork.isTrafficTypeClone($trafficType)) {
                if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).size()) {
                    $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 + ']').size() > 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').size();
            });

            return !$emptyContainers.size() ? $containers.size() : 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').size()) {
                    $(this).addClass('disabled');
                    $ul.fadeOut();
                } else {
                    $(this).removeClass('disabled');
                    $ul.show();
                }
            });

            $containers.each(function() {
                var $currentContainer = $(this);
                if (!$currentContainer.find('li').size() &&
                    $containers.size() > 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: '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('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('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: 'VNS'
                            }).html('VNS'),
                            $('<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: 'VSP'
                            }).html('VSP'),
                            $('<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').size()) {
                        $(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').size()) {
                        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').size();

                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.size()) {
                    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').size()) {
                        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':
                        physicalNetwork.init($wizard);
                }

                if ($uiCustom.size()) {
                    $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('Next');
                $nextButton.removeClass('final post-launch');

                // Show launch button if last step
                if ($targetStep.index() == $steps.size() - 1 || options.nextStep) {
                    $nextButton.find('span').html(options.nextStep ? 'Save changes' : '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').size()) {
                        $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').size()) {
                    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').size();
                    });

                    // Handle validation for custom UI components
                    var isCustomValidated = checkCustomValidation($step);
                    if (($form.size() && !$form.valid()) || !isCustomValidated) {
                        if (($form && $form.find('.error:visible').size()) || !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').size() > 0) { //$steps.filter(':visible').index() == 6
                            showStep('launch');
                            completeAction();
                            return false;
                        }
                    }
                    //when hypervisor is BareMetal (end)

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

                        completeAction();
                    }

                    return false;
                }

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

                    return false;
                }

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

                    return false;
                }

                // Edit link
                if ($target.closest('div.edit').size()) {
                    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.size()) {
                    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);

            return $wizard.dialog({
                title: 'Add zone',
                closeOnEscape: false,
                width: 750,
                height: 665,
                zIndex: 5000,
                resizable: false
            }).closest('.ui-dialog').overlay();
        };
    };
})(jQuery, cloudStack);
