// 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'),
                            $('<option>').attr({
                                value: 'ODL'
                            }).html('ODL'),
                            $('<option>').attr({
                                value: 'L3VPN'
                            }).html('L3VPN')
                        )
                    )
                );
            }
            //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);
