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

        scope:{
           label:'label.scope',
           select:function(args){
             var scopeData=[];
                //intelligence to handle different hypervisors to be added here
           /*  if( selectedHypervisor == 'XenServer'){
                       scopeData.push({ id: 'cluster', description: _l('label.cluster') });
               }*/
             // else if (selectedHypervisor == 'KVM'){
                  scopeData.push({ id: 'cluster', description: _l('label.cluster') });
                  scopeData.push({ id: 'zone', description: _l('label.zone.wide') });

              args.response.success({

                data: scopeData
              });
           }
          },

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