').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, sectionID) {
      var $tooltip = elems.tooltip('Hints', '');
      $formContainer.find('input[type=text]').focus(function() {
        var $input = $(this);
        $tooltip.find('p').html('');
        $tooltip.appendTo($formContainer);
        $tooltip.css({
          top: $(this).position().top - 20
        });
        var content = getCopy(
          'tooltip.' + sectionID + '.' + $input.attr('name'),
          $tooltip.find('p')
        );
      });
      $formContainer.find('input').blur(function() {
        $tooltip.remove();
      });
      setTimeout(function() {
        $formContainer.find('input[type=text]:first').focus();
      }, 600);
    };
    /**
     * Layout/behavior for each step in wizard
     */
    var steps = {
      intro: function(args) {
        var $intro = $('
').addClass('intro what-is-cloudstack');
        var $title = $('
').addClass('title')
              .html('What is CloudStack™?');
        var $subtitle = $('
').addClass('subtitle')
              .html('Introduction to CloudStack™');
        var $copy = getCopy('whatIsCloudStack', $('
'));
        var $continue = elems.nextButton('Continue with basic installation');
        var $advanced = elems.nextButton(
          'I have used Cloudstack before, skip this guide'
        ).addClass('advanced-installation');
        $continue.click(function() {
          goTo('changeUser');
          return false;
        });
        $advanced.click(function() {
          complete();
          return false;
        });
        return $intro.append(
          $title, $subtitle,
          $copy,
          $advanced,
          $continue
        );
      },
      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('addZoneIntro', 'newUser', $form);
              }
            }
          });
          return false;
        });
        return $changeUser;
      },
      /**
       * 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
       */
      addZone: elems.step({
        title: 'Add zone',
        id: 'add-zone',
        stateID: 'zone',
        tooltipID: 'addZone',
        diagram: '.part.zone',
        nextStepID: 'addPodIntro',
        form: {
          name: { label: 'Name', validation: { required: true } },
          dns1: { label: 'DNS 1', validation: { required: true } },
          dns2: { label: 'DNS 2' },
          internaldns1: { label: 'Internal DNS 1', validation: { required: true } },
          internaldns2: { label: 'Internal DNS 2' }
        }
      }),
      /**
       * 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: elems.step({
        title: 'Add pod',
        id: 'add-pod',
        stateID: 'pod',
        tooltipID: 'addPod',
        diagram: '.part.zone, .part.pod',
        nextStepID: 'addGuestNetwork',
        form: {
          name: { label: 'Name', validation: { required: true }},
          gateway: { label: 'Gateway', validation: { required: true }},
          netmask: { label: 'Netmask', validation: { required: true }},
          ipRange: { label: 'IP Range', range: ['startip', 'endip'], validation: { required: true }}
        }
      }),
      /**
       * Add guest network form
       */
      addGuestNetwork: elems.step({
        title: 'Add guest network',
        id: 'add-guest-network',
        stateID: 'guestNetwork',
        tooltipID: 'addGuestNetwork',
        diagram: '.part.zone',
        nextStepID: 'addClusterIntro',
        form: {
          name: { label: 'Name', validation: { required: true } },
          description: { label: 'Description', validation: { required: true } },
          guestGateway: { label: 'Gateway', validation: { required: true } },
          guestNetmask: { label: 'Netmask', validation: { required: true } },
          guestIPRange: { label: 'IP Range', range: ['guestStartIp', 'guestEndIp'], validation: { required: true } }
        }
      }),
      /**
       * 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: elems.step({
        title: 'Add cluster',
        id: 'add-cluster',
        stateID: 'cluster',
        tooltipID: 'addCluster',
        nextStepID: 'addHostIntro',
        diagram: '.part.zone, .part.cluster',
        form: {
          hypervisor: {
            label: 'Hypervisor',
            select: function(args) {
              args.response.success({ data: [
                { id: 'XenServer', description: 'XenServer' }
              ]});
            }
          },
          name: { label: 'Name', validation: { required: true }}
        }
      }),
      /**
       * 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: elems.step({
        title: 'Add host',
        id: 'add-host',
        stateID: 'host',
        tooltipID: 'addHost',
        nextStepID: 'addPrimaryStorageIntro',
        diagram: '.part.zone, .part.host',
        form: {
          hostname: {
            label: 'Host name',
            validation: { required: true }
          },
          username: {
            label: 'User name',
            validation: { required: true }
          },
          password: {
            label: 'Password',
            validation: { required: true },
            isPassword: true
          }
        }
      }),
      /**
       * 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: elems.step({
        title: 'Add primary storage',
        id: 'add-primary-storage',
        stateID: 'primaryStorage',
        tooltipID: 'addPrimaryStorage',
        nextStepID: 'addSecondaryStorageIntro',
        diagram: '.part.zone, .part.primaryStorage',
        form: {
          name: {
            label: 'Name',
            validation: { required: true }
          },
          server: {
            label: 'Server',
            validation: { required: true }
          },
          path: {
            label: 'Path',
            validation: { required: true }
          }
        }
      }),
      /**
       * 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: elems.step({
        title: 'Add secondary storage',
        id: 'add-secondary-storage',
        stateID: 'secondaryStorage',
        tooltipID: 'addSecondaryStorage',
        nextStepID: 'launchInfo',
        diagram: '.part.zone, .part.secondaryStorage',
        form: {
          nfsServer: {
            label: 'NFS Server',
            validation: { required: true }
          },
          path: {
            label: 'Path',
            validation: { required: true }
          }
        }
      }),
      /**
       * 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 $continue = elems.nextButton('Launch');
        $continue.click(function() {
          goTo('launch');
          return false;
        });
        showDiagram('.part.zone, .part.secondaryStorage');
        return $intro.append(
          $title, $subtitle,
          $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('');
        cloudStack.installWizard.action({
          data: state,
          response: {
            success: function() {
              complete();
            }
          }
        });
        showDiagram('.part.loading');
        return $intro.append(
          $title, $subtitle
        );
      }
    };
    var initialStep = steps.intro().addClass('step');
    showDiagram('');
    $installWizard.append(
      elems.header(),
      elems.body().append(initialStep),
      $diagramParts
    ).appendTo($container);
  };
  cloudStack.uiCustom.installWizard = installWizard;
}(jQuery, cloudStack, testData));