// 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') &&
          $trafficType.data('traffic-type-data').label.length >= 1;
      });

      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;

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

        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')
        )				
      );	

      
			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>').addClass('name').append(
							$('<label>').html('Physical network name')
						),
						$('<div>').addClass('value').append(
							$('<input>').attr({ type: 'text' }).addClass('required')
						),
						$('<div>').append(
							$('<span style=\"font-size:11px\;padding-right:5px;padding-left:50px">').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')

							)
						)
					);
				}
				//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,
          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);
