// 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: dictionary['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: 'vSwitch Name' ,
	                    defaultValue: trafficData.vSwitchName
	                },
	                vlanId: { 
	                	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: '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')
                        )
                    )
                );
            }
            //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(dictionary['message.enabling.zone']);

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

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

                            cloudStack.dialog.confirm({
                                message: dictionary['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(dictionary['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);
