// 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) {
  var installWizard = function(args) {
    var context = args.context;
    var $installWizard = $('<div>').addClass('install-wizard');
    var $container = args.$container;
    var state = {}; // Hold wizard form state
    var launchStart; // Holds last launch callback, in case of error
    var $launchState;

    /**
     * Successful installation action
     */
    var complete = function() {
      $installWizard.remove();
      $('html body').removeClass('install-wizard');

      args.complete();
    };

    /**
     * Retrive copy text and append to element -- async
     * @param id
     * @param $elem
     */
    var getCopy = function(id, $elem) {
      cloudStack.installWizard.copy[id]({
        response: {
          success: function(args) {
            $elem.append(_l(args.text));
          }
        }
      });

      return $elem;
    };

    /**
     * Go to specified step in flow -- for use in individual steps
     * @param stateStepID ID to group state elements in (i.e., zone, pod, cluster, ...)
     * @param $elem (optional) Element containing <form>, to serialize for state
     */
    var goTo = cloudStack._goto = function(stepID, stateID, $elem, options) {
      if (!options) options = {};

      var $body = $installWizard.find('.body');

      if (stateID && $elem) {
        state[stateID] = cloudStack.serializeForm($elem.is('form') ? $elem : $elem.find('form'));
      }

      $body.children().fadeOut('fast', function() {
        var $nextStep = steps[stepID]({ nextStep: options.nextStep });

        $body.children().detach();
        $nextStep.appendTo($body).hide();
        $nextStep.addClass('step').fadeIn();
      });
    };

    /**
     * Generic page elements
     */
    var elems = {
      /**
       * A standard intro text wizard step template
       */
      stepIntro: function(args) {
        var title = args.title;
        var subtitle = args.subtitle;
        var copyID = args.copyID;
        var prevStepID = args.prevStepID;
        var nextStepID = args.nextStepID;
        var diagram = args.diagram;

        var $intro = $('<div></div>').addClass('intro');
        var $title = $('<div></div>').addClass('title')
              .html(title);
        var $subtitle = $('<div></div>').addClass('subtitle')
              .html(subtitle);
        var $copy = getCopy(copyID, $('<p></p>'));
        var $prev = elems.prevButton(_l('label.back'));
        var $continue = elems.nextButton('OK');

        $continue.click(function() {
          goTo(nextStepID);

          return false;
        });

        $prev.click(function() {
          goTo(prevStepID);
        });

        return function(args) {
          showDiagram(diagram);

          return $intro.append(
            $title, $subtitle,
            $copy,
            $prev,
            $continue
          );
        };
      },

      /**
       * A standard form-based wizard step template
       * -- relies on createForm for form generation
       */
      step: function(args) {
        var title = args.title;
        var formData = args.form;
        var diagram = args.diagram;
        var id = args.id;
        var stateID = args.stateID;
        var tooltipID = args.tooltipID;
        var prevStepID = args.prevStepID;
        var nextStepID = args.nextStepID;
        var form;

        var $container = $('<div></div>').addClass(id);
        var $form = $('<div>').addClass('setup-form');
        var $save = elems.nextButton(_l('label.continue'), { type: 'submit' });
        var $prev = elems.prevButton(_l('label.back'));
        var $title = $('<div></div>').addClass('title').html(_l(title));

        // Generate form
        form = cloudStack.dialog.createForm({
          noDialog: true,
          form: {
            title: title,
            desc: '',
            fields: formData
          },
          after: function(args) {
            goTo(nextStepID, stateID, $form);
          }
        });

        $form.append(form.$formContainer);
        $form.find('.form-item').addClass('field');
        $prev.appendTo($form.find('form'));
        $save.appendTo($form.find('form'));

        // Submit handler
        $form.find('form').submit(function() {
          form.completeAction($form);

          return false;
        });

        // Go back handler
        $prev.click(function(event) {
          goTo(prevStepID);
        });

        // Cleanup
        $form.find('.message').remove();
        $form.find('label.error').hide();
        $container.append($form.prepend($title));

        showTooltip($form, tooltipID);

        return function(args) {
          var overrideGotoEvent = function(event) {
            goTo(args.nextStep, stateID, $form);

            return false;
          };

          if (args && args.nextStep) {
            $save.unbind('click');
            $save.click(overrideGotoEvent);
          }

          // Setup diagram, tooltips
          showDiagram(diagram);
          setTimeout(function() {
            $form.find('input[type=text]:first').focus();
          }, 600);

          return $container;
        };
      },

      /**
       * A form item tooltip
       */
      tooltip: function(title, content) {
        return $('<div>').addClass('tooltip-info').append(
          $('<div>').addClass('arrow'),
          $('<div>').addClass('title').html(_l(title)),
          $('<div>').addClass('content').append($('<p>').html(_l(content)))
        );
      },

      /**
       * The main header
       */
      header: function() {
        return $('<div></div>').addClass('header')
          .append(
            $.merge(
              $('<h2></h2>').html(_l('label.installWizard.title')),
              $('<h3></h3>').html(_l('label.installWizard.subtitle'))
            )
          );
      },

      /**
       * The wizard body (contains form)
       */
      body: function() {
        return $('<div></div>').addClass('body');
      },

      /**
       * A standard next button
       */
      nextButton: function(label, options) {
        var $button = options && !options.type ?
              $('<div>').addClass('button goTo').html(label) :
          $('<input>').attr({ type: 'submit' }).addClass('button goTo').val(label);

        return $button;
      },

      /**
       * A standard previous/go back button
       */
      prevButton: function(label) {
        return $('<div>').addClass('button go-back').html(label);
      },

      diagramParts: function() {
        return $('<div>').addClass('diagram').append(
          $('<div>').addClass('part zone'),
          $('<div>').addClass('part pod'),
          $('<div>').addClass('part cluster'),
          $('<div>').addClass('part host'),
          $('<div>').addClass('part primaryStorage'),
          $('<div>').addClass('part secondaryStorage'),
          $('<div>').addClass('part loading').append($('<div>').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(_l('label.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();
      });
    };

    /**
     * Layout/behavior for each step in wizard
     */
    var steps = {
      start: function(args) {
        if (cloudStack.preInstall) {
          return cloudStack.preInstall({
            complete: function() {
              goTo('intro');
            }
          });
        }

        return steps.intro(args);
      },
      intro: function(args) {
        var $intro = $('<div></div>').addClass('intro what-is-cloudstack');
        var $title = $('<div></div>').addClass('title').html(_l('label.what.is.cloudstack'));
        var $subtitle = $('<div></div>').addClass('subtitle').html(_l('label.introduction.to.cloudstack'));
        var $copy = getCopy('whatIsCloudStack', $('<p></p>'));
        var $continue = elems.nextButton(_l('label.continue.basic.install'));
        var $advanced = elems.nextButton(_l('label.skip.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 = $('<div></div>').addClass('step change-user');
        var $form = $('<form></form>').appendTo($changeUser);

        // Fields
        var $password = $('<input>').addClass('required').attr({
          id: 'password',
          type: 'password',
          name: 'password'
        });
        var $passwordConfirm = $('<input>').addClass('required').attr({
          id: 'password-confirm',
          type: 'password',
          name: 'password-confirm'
        });
        var $save = elems.nextButton(_l('label.save.and.continue'), { type: 'submit' });

        $form.append(
          $('<div></div>').addClass('title').html(_l('message.change.password')),
          $('<div></div>').addClass('field').append(
            $('<label>' + _l('label.new.password') + ':</label>'), $password
          ),
          $('<div></div>').addClass('field').append(
            $('<label>' + _l('label.confirm.password') + ':</label>'), $passwordConfirm
          ),
          $save
        );

        $form.validate({
          rules: {
            'password-confirm': {
              equalTo: '#password'
            }
          },
          messages: {
            'password-confirm': {
              equalTo: _l('error.password.not.match')
            }
          }
        });

        // Save event
        $form.submit(function() {
          if (!$form.valid()) return false;

          var $loading = $('<div></div>').addClass('loading-overlay').prependTo($form);
          cloudStack.installWizard.changeUser({
            data: cloudStack.serializeForm($form),
            response: {
              success: function(args) {
                goTo('addZoneIntro', 'newUser', $form);
              }
            }
          });

          return false;
        });

        showDiagram('');

        return $changeUser;
      },

      /**
       * Add zone intro text
       * @param args
       */
      addZoneIntro: elems.stepIntro({
        title: _l('label.installWizard.addZoneIntro.title'),
        subtitle: _l('label.installWizard.addZoneIntro.subtitle'),
        copyID: 'whatIsAZone',
        prevStepID: 'changeUser',
        nextStepID: 'addZone',
        diagram: '.part.zone'
      }),

      /**
       * Add zone form
       */
      addZone: elems.step({
        title: _l('label.installWizard.addZone.title'),
        id: 'add-zone',
        stateID: 'zone',
        tooltipID: 'addZone',
        diagram: '.part.zone',
        prevStepID: 'addZoneIntro',
        nextStepID: 'addPodIntro',
        form: {
          name: { label: 'label.name', validation: { required: true } },
          ip4dns1: { label: 'label.dns.1', validation: { required: true } },
          ip4dns2: { label: 'label.dns.2' },
          internaldns1: { label: 'label.internal.dns.1', validation: { required: true } },
          internaldns2: { label: 'label.internal.dns.2' }
        }
      }),

      /**
       * Add pod intro text
       * @param args
       */
      addPodIntro: elems.stepIntro({
        title: _l('label.installWizard.addPodIntro.title'),
        subtitle: _l('label.installWizard.addPodIntro.subtitle'),
        copyID: 'whatIsAPod',
        prevStepID: 'addZone',
        nextStepID: 'addPod',
        diagram: '.part.zone, .part.pod'
      }),

      /**
       * Add pod form
       * @param args
       */
      addPod: elems.step({
        title: _l('label.add.pod'),
        id: 'add-pod',
        stateID: 'pod',
        tooltipID: 'addPod',
        diagram: '.part.zone, .part.pod',
        prevStepID: 'addPodIntro',
        nextStepID: 'configureGuestTraffic',
        form: {
          name: { label: 'label.name', validation: { required: true }},
          reservedSystemGateway: { label: 'label.gateway', validation: { required: true }},
          reservedSystemNetmask: { label: 'label.netmask', validation: { required: true }},
          ipRange: {
            label: 'label.ip.range',
            range: ['reservedSystemStartIp', 'reservedSystemEndIp'],
            validation: { required: true }
          }
        }
      }),

      /**
       * Add guest network form
       */
      configureGuestTraffic: elems.step({
        title: _l('label.add.guest.network'),
        id: 'add-guest-network',
        stateID: 'guestTraffic',
        tooltipID: 'configureGuestTraffic',
        diagram: '.part.zone, .part.pod',
        prevStepID: 'addPod',
        nextStepID: 'addClusterIntro',
        form: {
          guestGateway: { label: 'label.gateway', validation: { required: true } },
          guestNetmask: { label: 'label.netmask', validation: { required: true } },
          guestIPRange: { label: 'label.ip.range', range: ['guestStartIp', 'guestEndIp'], validation: { required: true } }
        }
      }),

      /**
       * Add cluster intro text
       * @param args
       */
      addClusterIntro: elems.stepIntro({
        title: _l('label.installWizard.addClusterIntro.title'),
        subtitle: _l('label.installWizard.addClusterIntro.subtitle'),
        copyID: 'whatIsACluster',
        prevStepID: 'configureGuestTraffic',
        nextStepID: 'addCluster',
        diagram: '.part.zone, .part.cluster'
      }),

      /**
       * Add cluster form
       * @param args
       */
      addCluster: elems.step({
        title: _l('label.add.cluster'),
        id: 'add-cluster',
        stateID: 'cluster',
        tooltipID: 'addCluster',
        prevStepID: 'addClusterIntro',
        nextStepID: 'addHostIntro',
        diagram: '.part.zone, .part.cluster',
        form: {
          hypervisor: {
            label: 'label.hypervisor',
            select: function(args) {
              args.response.success({ data: [
                { id: 'XenServer', description: 'XenServer' },
                { id: 'KVM', description: 'KVM'}
              ]});
            }
          },
          name: { label: 'label.name', validation: { required: true }}
        }
      }),

      /**
       * Add host intro text
       * @param args
       */
      addHostIntro: elems.stepIntro({
        title: _l('label.installWizard.addHostIntro.title'),
        subtitle: _l('label.installWizard.addHostIntro.subtitle'),
        copyID: 'whatIsAHost',
        prevStepID: 'addCluster',
        nextStepID: 'addHost',
        diagram: '.part.zone, .part.host'
      }),

      /**
       * Add host form
       * @param args
       */
      addHost: elems.step({
        title: _l('label.add.host'),
        id: 'add-host',
        stateID: 'host',
        tooltipID: 'addHost',
        prevStepID: 'addHostIntro',
        nextStepID: 'addPrimaryStorageIntro',
        diagram: '.part.zone, .part.host',
        form: {
          hostname: {
            label: 'label.host.name',
            validation: { required: true }
          },

          username: {
            label: 'label.username',
            validation: { required: true }
          },

          password: {
            label: 'label.password',
            validation: { required: true },
            isPassword: true
          }
        }
      }),

      /**
       * Add primary storage intro text
       * @param args
       */
      addPrimaryStorageIntro: elems.stepIntro({
        title: _l('label.installWizard.addPrimaryStorageIntro.title'),
        subtitle: _l('label.installWizard.addPrimaryStorageIntro.subtitle'),
        copyID: 'whatIsPrimaryStorage',
        prevStepID: 'addHost',
        nextStepID: 'addPrimaryStorage',
        diagram: '.part.zone, .part.primaryStorage'
      }),

      /**
       * Add primary storage
       * @param args
       */
      addPrimaryStorage: elems.step({
        title: _l('label.add.primary.storage'),
        id: 'add-primary-storage',
        stateID: 'primaryStorage',
        tooltipID: 'addPrimaryStorage',
        prevStepID: 'addPrimaryStorageIntro',
        nextStepID: 'addSecondaryStorageIntro',
        diagram: '.part.zone, .part.primaryStorage',
        form: {
          name: {
            label: 'label.name',
            validation: { required: true }
          },

          protocol: {
            label: 'label.protocol',
            select: function(args) {
              args.response.success({
                data: { id: 'nfs', description: 'NFS' }
              });
            }
          },

          server: {
            label: 'label.server',
            validation: { required: true }
          },

          path: {
            label: 'label.path',
            validation: { required: true }
          }
        }
      }),

      /**
       * Add secondary storage intro text
       * @param args
       */
      addSecondaryStorageIntro: elems.stepIntro({
        title: _l('label.installWizard.addSecondaryStorageIntro.title'),
        subtitle: _l('label.installWizard.addSecondaryStorageIntro.subtitle'),
        copyID: 'whatIsSecondaryStorage',
        prevStepID: 'addPrimaryStorage',
        nextStepID: 'addSecondaryStorage',
        diagram: '.part.zone, .part.secondaryStorage'
      }),

      /**
       * Add secondary storage
       * @param args
       */
      addSecondaryStorage: elems.step({
        title: _l('label.add.secondary.storage'),
        id: 'add-secondary-storage',
        stateID: 'secondaryStorage',
        tooltipID: 'addSecondaryStorage',
        prevStepID: 'addSecondaryStorageIntro',
        nextStepID: 'launchInfo',
        diagram: '.part.zone, .part.secondaryStorage',
        form: {
          nfsServer: {
            label: 'label.nfs.server',
            validation: { required: true }
          },
          path: {
            label: 'label.path',
            validation: { required: true }
          }
        }
      }),

      /**
       * Pre-launch text
       */
      launchInfo: function(args) {
        var $intro = $('<div></div>').addClass('intro');
        var $title = $('<div></div>').addClass('title')
              .html(_l('label.congratulations'));
        var $subtitle = $('<div></div>').addClass('subtitle')
              .html(_l('label.installWizard.click.launch'));
        var $continue = elems.nextButton(_l('label.launch'));
        var $prev = elems.prevButton(_l('label.back'));

        $continue.click(function() {
          goTo('launch');

          return false;
        });

        $prev.click(function() {
          goTo('addSecondaryStorage');
        });

        showDiagram('.part.zone, .part.secondaryStorage');

        return $intro.append(
          $title, $subtitle,
          $prev, $continue
        );
      },

      /**
       * Pre-launch test -- after error correction
       */
      launchInfoError: function(args) {
        var $intro = $('<div></div>').addClass('intro');
        var $title = $('<div></div>').addClass('title')
              .html(_l('label.corrections.saved'));
        var $subtitle = $('<div></div>').addClass('subtitle')
              .html(_l('message.installWizard.click.retry'));
        var $continue = elems.nextButton(_l('label.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 = $('<div>').addClass('intro');
        var $title = $('<div>').addClass('title')
              .html(_l('message.installWizard.now.building'));
        var $subtitle = $('<div></div>').addClass('subtitle');

        showDiagram('.part.loading');
        $intro.append(
          $title, $subtitle
        );

        cloudStack.installWizard.action({
          data: state,
          startFn: launchStart,
          response: {
            message: function(msg) {
              var $li = $('<li>').html(_l(msg));

              $subtitle.append($li);
              $li.siblings().addClass('complete');
            },
            success: function() {
              goTo('complete');
            },
            error: function(stepID, message, callback) {
              launchStart = callback;
              $subtitle.find('li:last').addClass('error');

              $subtitle.append(
                $('<p>').html(
                  _l('error.installWizard.message') + ':<br/>'
                    + message
                ),
                $('<div>').addClass('button').append(
                  $('<span>').html(_l('label.back'))
                ).click(function() {
                  goTo(stepID, null, null, {
                    nextStep: 'launchInfoError'
                  });
                })
              );
            }
          }
        });

        return $intro;
      },

      complete: function(args) {
        var $intro = $('<div></div>').addClass('intro');
        var $title = $('<div></div>').addClass('title')
              .html(_l('message.setup.successful'));
        var $subtitle = $('<div></div>').addClass('subtitle')
              .html(_l('label.may.continue'));
        var $continue = elems.nextButton(_l('label.launch'));

        showDiagram('');

        $continue.click(function() {
          $installWizard.fadeOut(function() {
            complete();
          });
        });

        return $intro.append(
          $title, $subtitle, $continue
        );
      }
    };

    var initialStep = steps.start().addClass('step');
    

    showDiagram('');
    $('html body').addClass('install-wizard');

    $installWizard.append(
      elems.header(),
      elems.body().append(initialStep),
      $diagramParts
    ).appendTo($container);
    

 };

  cloudStack.uiCustom.installWizard = installWizard;
}(jQuery, cloudStack));
