').addClass('icon'))
        );
      }
    };
    var $diagramParts = elems.diagramParts();
    var showDiagram = function(parts) {
      $diagramParts.children().hide();
      $diagramParts.find(parts).show();
    };
    /**
     * Show tooltip for focused form elements
     */
    var showTooltip = function($formContainer) {
      var $tooltip = elems.tooltip('Hints', 'Help content goes here.');
      $formContainer.find('input').focus(function() {
        $tooltip.appendTo($formContainer);
        $tooltip.css({
          top: $(this).position().top - 20
        });
      });
      $formContainer.find('input').blur(function() {
        $tooltip.remove();
      });
    };
    /**
     * Layout/behavior for each step in wizard
     */
    var steps = {
      changeUser: function(args) {
        var $changeUser = $('
').addClass('step change-user');
        var $form = $('
').appendTo($changeUser);
        // Fields
        var $password = $('
').addClass('required').attr({ type: 'password', name: 'password' });
        var $passwordConfirm = $('
').addClass('required').attr({ type: 'password', name: 'password-confirm' });
        var $save = elems.nextButton('Save and continue', { type: 'submit' });
        $form.append(
          $('
').addClass('title').html('Please change your password.'),
          $('
').addClass('field').append(
            $('
New Password: '), $password
          ),
          $('
').addClass('field').append(
            $('
Confirm Password: '), $passwordConfirm
          ),
          $save
        );
        $form.validate();
        // Save event
        $form.submit(function() {
          if (!$form.valid()) return false;
          var $loading = $('
').addClass('loading-overlay').prependTo($form);
          cloudStack.installWizard.changeUser({
            data: cloudStack.serializeForm($form),
            response: {
              success: function(args) {
                goTo('intro', 'newUser', $form);
              }
            }
          });
          return false;
        });
        return $changeUser;
      },
      intro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
          .html('What is CloudStack?');
        var $subtitle = $('
').addClass('subtitle')
          .html('Subtitle text goes here');
        var $copy = getCopy('whatIsCloudStack', $('
'));
        var $continue = elems.nextButton('Continue with basic installation');
        var $advanced = elems.nextButton('Setup advanced installation').addClass('advanced-installation');
        $continue.click(function() {
          goTo('addZoneIntro');
          return false;
        });
        $advanced.click(function() {
          complete();
          
          return false;
        });
        return $intro.append(
          $title, $subtitle,
          $copy,
          $advanced,
          $continue
        );
      },
      /**
       * Add zone intro text
       * @param args
       */
      addZoneIntro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
          .html('Let\'s add a zone.');
        var $subtitle = $('
').addClass('subtitle')
          .html('What is a zone?');
        var $copy = getCopy('whatIsAZone', $('
'));
        var $continue = elems.nextButton('OK');
        $continue.click(function() {
          goTo('addZone');
          return false;
        });
        showDiagram('.part.zone');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Add zone form
       * @param args
       */
      addZone: function(args) {
        var $addZone = $('
').addClass('add-zone');
        var $addZoneForm = $('
').addClass('setup-form').append(
          $('#template').find('.multi-wizard.zone-wizard .steps .setup-zone').clone()
        );
        var $save = elems.nextButton('Continue', { type: 'submit' });
        var $title = $('
').addClass('title').html('Setup Zone');
        $addZoneForm.find('form').validate();
        $save.click(function() {
          if (!$addZoneForm.find('form').valid()) return false;
          goTo('addIPRange', 'zone', $addZoneForm);
          return false;
        });
        // Remove unneeded fields
        $addZoneForm.find('.main-desc, .conditional').remove();
        $addZoneForm.find('.field:last').remove();
        showDiagram('.part.zone');
        showTooltip($addZoneForm);
        return $addZone.append(
          $addZoneForm
            .prepend($title)
            .append($save)
        );
      },
      /**
       * Add IP range form
       * @param args
       */
      addIPRange: function(args) {
        var $addIPRange = $('
').addClass('add-zone');
        var $addIPRangeForm = $('
').addClass('setup-form').append(
          $('#template').find('.multi-wizard.zone-wizard .steps .add-ip-range').clone()
        );
        var $save = elems.nextButton('Continue', { type: 'submit' });
        var $title = $('
').addClass('title').html('Setup IP Range');
        $addIPRangeForm.find('form').validate();
        $save.click(function() {
          if (!$addIPRangeForm.find('form').valid()) return false;
          goTo('addPodIntro', 'zoneIPRange', $addIPRangeForm);
          return false;
        });
        showDiagram('.part.zone');
        showTooltip($addIPRangeForm);
        // Remove unneeded fields
        $addIPRangeForm.find('.main-desc, .conditional').remove();
        return $addIPRange.append(
          $addIPRangeForm
            .prepend($title)
            .append($save)
        );
      },
      /**
       * Add pod intro text
       * @param args
       */
      addPodIntro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
          .html('Let\'s add a pod.');
        var $subtitle = $('
').addClass('subtitle')
          .html('What is a pod?');
        var $copy = getCopy('whatIsAPod', $('
'));
        var $continue = elems.nextButton('OK');
        $continue.click(function() {
          goTo('addPod');
          return false;
        });
        showDiagram('.part.zone, .part.pod');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Add pod form
       * @param args
       */
      addPod: function(args) {
        var $addPod = $('
').addClass('add-pod');
        var $addPodForm = $('
').addClass('setup-form').append(
          $('#template').find('.multi-wizard.zone-wizard .steps .setup-pod').clone()
        );
        var $save = elems.nextButton('Continue', { type: 'submit' });
        var $title = $('
').addClass('title').html('Add a Pod');
        $addPodForm.find('form').validate();
        $save.click(function() {
          if (!$addPodForm.find('form').valid()) return false;
          goTo('addClusterIntro', 'pod', $addPodForm);
          return false;
        });
        // Remove unneeded fields
        $addPodForm.find('.main-desc, .conditional').remove();
        showDiagram('.part.zone, .part.pod');
        showTooltip($addPodForm);
        return $addPod.append(
          $addPodForm
            .prepend($title)
            .append($save)
        );
      },
      /**
       * Add cluster intro text
       * @param args
       */
      addClusterIntro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
          .html('Let\'s add a cluster.');
        var $subtitle = $('
').addClass('subtitle')
          .html('What is a cluster?');
        var $copy = getCopy('whatIsACluster', $('
'));
        var $continue = elems.nextButton('OK');
        $continue.click(function() {
          goTo('addCluster');
          return false;
        });
        showDiagram('.part.zone, .part.cluster');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Add cluster form
       * @param args
       */
      addCluster: function(args) {
        var $addCluster = $('
').addClass('add-cluster');
        var addClusterForm = cloudStack.dialog.createForm({
          context: {
            zones: [{}]
          },
          noDialog: true,
          form: cloudStack.sections.system
            .subsections.clusters.listView
            .actions.add.createForm,
          after: function(args) {
            goTo('addHostIntro', 'cluster', $addClusterForm);
          }
        });
        var $addClusterForm = $('
').addClass('setup-form').append(
          addClusterForm.$formContainer
        );
        var $save = elems.nextButton('Continue', { type: 'submit' }).appendTo($addClusterForm.find('form'));
        var $title = $('
').addClass('title').html('Add a Cluster');
        $addClusterForm.find('form').submit(function() {
          addClusterForm.completeAction($addClusterForm);
          return false;
        });
        showDiagram('.part.zone, .part.cluster');
        showTooltip($addClusterForm);
        // Cleanup
        $addClusterForm.find('.message').remove();
        $addClusterForm.find('.form-item').addClass('field').find('label.error').hide();
        $addClusterForm.find('.form-item[rel=podId]').remove();
        return $addCluster.append(
          $addClusterForm
            .prepend($title)
        );
      },
      /**
       * Add host intro text
       * @param args
       */
      addHostIntro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
          .html('Let\'s add a host.');
        var $subtitle = $('
').addClass('subtitle')
          .html('What is a host?');
        var $copy = getCopy('whatIsAHost', $('
'));
        var $continue = elems.nextButton('OK');
        $continue.click(function() {
          goTo('addHost');
          return false;
        });
        showDiagram('.part.zone, .part.host');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Add host form
       * @param args
       */
      addHost: function(args) {
        var $addHost = $('
').addClass('add-host');
        var addHostForm = cloudStack.dialog.createForm({
          context: { zones: [{}] },
          noDialog: true,
          form: {
            title: 'Add new host',
            desc: 'Please fill in the following information to add a new host fro the specified zone configuration.',
            fields: {
              hostname: {
                label: 'Host name',
                validation: { required: true }
              },
              username: {
                label: 'User name',
                validation: { required: true }
              },
              password: {
                label: 'Password',
                validation: { required: true },
                isPassword: true
              },
              //always appear (begin)
              hosttags: {
                label: 'Host tags',
                validation: { required: false }
              }
              //always appear (end)
            }
          },
          after: function(args) {
            goTo('addPrimaryStorageIntro', 'host', $addHostForm);
          }
        });
        var $addHostForm = $('
').addClass('setup-form').append(
          addHostForm.$formContainer
        );
        var $save = elems.nextButton('Continue', { type: 'submit' }).appendTo($addHostForm.find('form'));
        var $title = $('
').addClass('title').html('Add a Host');
        $addHostForm.find('form').submit(function() {
          addHostForm.completeAction($addHostForm);
          return false;
        });
        showDiagram('.part.zone, .part.host');
        showTooltip($addHostForm);
        // Cleanup
        $addHostForm.find('.message').remove();
        $addHostForm.find('.form-item').addClass('field').find('label.error').hide();
        $addHostForm.find('.form-item[rel=cluster], .form-item[rel=pod]').remove();
        return $addHost.append(
          $addHostForm
            .prepend($title)
        );
      },
      /**
       * Add primary storage intro text
       * @param args
       */
      addPrimaryStorageIntro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
              .html('Let\'s add primary storage.');
        var $subtitle = $('
').addClass('subtitle')
              .html('What is primary storage?');
        var $copy = getCopy('whatIsPrimaryStorage', $('
'));
        var $continue = elems.nextButton('OK');
        $continue.click(function() {
          goTo('addPrimaryStorage');
          return false;
        });
        showDiagram('.part.zone, .part.primaryStorage');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Add primary storage
       * @param args
       */
      addPrimaryStorage: function(args) {
        var $addPrimaryStorage = $('
').addClass('add-primary-storage');
        var addPrimaryStorageForm = cloudStack.dialog.createForm({
          noDialog: true,
          form: {
            title: 'Add new primary storage',
            desc: 'Please fill in the following information to add a new primary storage',
            fields: {
              name: {
                label: 'Name',
                validation: { required: true }
              },
              server: {
                label: 'Server',
                validation: { required: true }
              },
              path: {
                label: 'Path',
                validation: { required: true }
              },
              storageTags: {
                label: 'Storage Tags',
                validation: { required: false }
              }
            }
          },
          after: function(args) {
            goTo('addSecondaryStorageIntro', 'primaryStorage', $addPrimaryStorageForm);
          }
        });
        var $addPrimaryStorageForm = $('
').addClass('setup-form').append(
          addPrimaryStorageForm.$formContainer
        );
        var $save = elems.nextButton('Continue', { type: 'submit' }).appendTo($addPrimaryStorageForm.find('form'));
        var $title = $('
').addClass('title').html('Add Primary Storage');
        $addPrimaryStorageForm.find('form').submit(function() {
          addPrimaryStorageForm.completeAction($addPrimaryStorageForm);
          return false;
        });
        showDiagram('.part.zone, .part.primaryStorage');
        showTooltip($addPrimaryStorageForm);
        // Cleanup
        $addPrimaryStorageForm.find('.message').remove();
        $addPrimaryStorageForm.find('.form-item').addClass('field').find('label.error').hide();
        $addPrimaryStorageForm.find('.form-item[rel=clusterId], .form-item[rel=podId]').remove();
        return $addPrimaryStorage.append(
          $addPrimaryStorageForm
            .prepend($title)
        );
      },
      /**
       * Add secondary storage intro text
       * @param args
       */
      addSecondaryStorageIntro: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
              .html('Let\'s add secondary storage.');
        var $subtitle = $('
').addClass('subtitle')
              .html('What is a secondary storage?');
        var $copy = getCopy('whatIsSecondaryStorage', $('
'));
        var $continue = elems.nextButton('OK');
        $continue.click(function() {
          goTo('addSecondaryStorage');
          return false;
        });
        showDiagram('.part.zone, .part.secondaryStorage');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Add secondary storage
       * @param args
       */
      addSecondaryStorage: function(args) {
        var $addSecondaryStorage = $('
').addClass('add-secondary-storage');
        var addSecondaryStorageForm = cloudStack.dialog.createForm({
          noDialog: true,
          form: {
            title: 'Add new secondary storage',
            desc: 'Please fill in the following information to add a new secondary storage',
            fields: {
              nfsServer: {
                label: 'NFS Server',
                validation: { required: true }
              },
              path: {
                label: 'Path',
                validation: { required: true }
              }
            }
          },
          after: function(args) {
            goTo('launchInfo', 'secondaryStorage', $addSecondaryStorageForm);
          }
        });
        var $addSecondaryStorageForm = $('
').addClass('setup-form').append(
          addSecondaryStorageForm.$formContainer
        );
        var $save = elems.nextButton('Continue', { type: 'submit' }).appendTo($addSecondaryStorageForm.find('form'));
        var $title = $('
').addClass('title').html('Add Secondary Storage');
        $addSecondaryStorageForm.find('form').submit(function() {
          addSecondaryStorageForm.completeAction($addSecondaryStorageForm);
          return false;
        });
        showDiagram('.part.zone, .part.secondaryStorage');
        showTooltip($addSecondaryStorageForm);
        // Cleanup
        $addSecondaryStorageForm.find('.message').remove();
        $addSecondaryStorageForm.find('.form-item').addClass('field').find('label.error').hide();
        return $addSecondaryStorage.append(
          $addSecondaryStorageForm
            .prepend($title)
        );
      },
      /**
       * Pre-launch text
       */
      launchInfo: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
          .html('Congratulations!.');
        var $subtitle = $('
').addClass('subtitle')
          .html('Click the launch button.');
        var $copy = getCopy('whatIsACluster', $('
'));
        var $continue = elems.nextButton('Launch');
        $continue.click(function() {
          goTo('launch');
          return false;
        });
        showDiagram('.part.zone, .part.secondaryStorage');
        return $intro.append(
          $title, $subtitle,
          $copy,
          $continue
        );
      },
      /**
       * Initiates launch tasks
       */
      launch: function(args) {
        var $intro = $('
').addClass('intro');
        var $title = $('
').addClass('title')
              .html('Now building your cloud...');
        var $subtitle = $('
').addClass('subtitle')
              .html('You may want to get a cup of coffee right now.');
        cloudStack.installWizard.action({
          data: state,
          response: {
            success: function() {
              complete();
            }
          }
        });
        showDiagram('.part.loading');
        return $intro.append(
          $title, $subtitle
        );
      }
    };
    var initialStep = steps.changeUser().addClass('step');
    $installWizard.append(
      elems.header(),
      elems.body().append(initialStep),
      $diagramParts
    ).appendTo($container);
  };
  cloudStack.uiCustom.installWizard = installWizard;
}(jQuery, cloudStack, testData));