').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 = $('
').addClass('intro what-is-cloudstack');
                var $title = $('
').addClass('title').html(_l('label.what.is.cloudstack'));
                var $subtitle = $('
').addClass('subtitle').html(_l('label.introduction.to.cloudstack'));
                var $copy = getCopy('whatIsCloudStack', $('
'));
                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 = $('
').addClass('step change-user');
                var $form = $('
').appendTo($changeUser);
                // Fields
                var $password = $('
').addClass('required').attr({
                    id: 'password',
                    type: 'password',
                    name: 'password'
                });
                var $passwordConfirm = $('
').addClass('required').attr({
                    id: 'password-confirm',
                    type: 'password',
                    name: 'password-confirm'
                });
                var $save = elems.nextButton(_l('label.save.and.continue'), {
                    type: 'submit'
                });
                $form.append(
                    $('
').addClass('title').html(_l('message.change.password')),
                    $('
').addClass('field').append(
                        $('
' + _l('label.new.password') + ': '), $password
                    ),
                    $('
').addClass('field').append(
                        $('
' + _l('label.confirm.password') + ': '), $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 = $('
').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
                        }
                    },
                    provider: {
                        label: 'label.provider',
                        select: function(args) {
                            args.response.success({
                                data: [
                                    { id: 'NFS', description: 'NFS' }
                                ]
                            });
                        }
                    },
                    path: {
                        label: 'label.path',
                        validation: {
                            required: true
                        }
                    }
                }
            }),
            /**
             * Pre-launch text
             */
            launchInfo: function(args) {
                var $intro = $('
').addClass('intro');
                var $title = $('
').addClass('title')
                    .html(_l('label.congratulations'));
                var $subtitle = $('
').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 = $('
').addClass('intro');
                var $title = $('
').addClass('title')
                    .html(_l('label.corrections.saved'));
                var $subtitle = $('
').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 = $('
').addClass('intro');
                var $title = $('
').addClass('title')
                    .html(_l('message.installWizard.now.building'));
                var $subtitle = $('
').addClass('subtitle');
                showDiagram('.part.loading');
                $intro.append(
                    $title, $subtitle
                );
                cloudStack.installWizard.action({
                    data: state,
                    startFn: launchStart,
                    response: {
                        message: function(msg) {
                            var $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(
                                $('').html(
                                    _l('error.installWizard.message') + ':
').addClass('button').append(
                                    $('
').html(_l('label.back'))
                                ).click(function() {
                                    goTo(stepID, null, null, {
                                        nextStep: 'launchInfoError'
                                    });
                                })
                            );
                        }
                    }
                });
                return $intro;
            },
            complete: function(args) {
                var $intro = $('
').addClass('intro');
                var $title = $('
').addClass('title')
                    .html(_l('message.setup.successful'));
                var $subtitle = $('
').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));