multi-device: update Ring account creation wizard

This patch implements multi-device support

- The account creation wizzard has now two options "Existing Ring
  account" and "New Ring account".

  "Existing Ring account": Allows for fetching a Ring account archive
  from the DHT. Requires pin and password.

  "New Ring account": This is the previously existing wizard. It was
  modified to ask for a password which will be used to encrypt the
  account archive. This password is then required for exporting the
  account on the Ring.

- Creating a new Ring account with the "+" button now triggers the
  account creation wizard.

Change-Id: I6840d968e52de014ab0aa9dd6f5bc1ab31f9e9ec
Tuleap: #958
diff --git a/src/AccountsVC.mm b/src/AccountsVC.mm
index 1557915..b62b623 100644
--- a/src/AccountsVC.mm
+++ b/src/AccountsVC.mm
@@ -38,6 +38,7 @@
 #import "AccRingVC.h"
 #import "AccDevicesVC.h"
 #import "PathPasswordWC.h"
+#import "RingWizardWC.h"
 
 @interface AccountsVC () <PathPasswordDelegate>
 
@@ -63,6 +64,7 @@
 @property AccAdvancedVC* advancedVC;
 @property AccSecurityVC* securityVC;
 @property PathPasswordWC* passwordWC;
+@property RingWizardWC* wizard;
 
 @end
 
@@ -79,6 +81,7 @@
 @synthesize accountDetailsView;
 @synthesize treeController;
 @synthesize passwordWC;
+@synthesize wizard;
 
 NSInteger const TAG_CHECK       =   100;
 NSInteger const TAG_NAME        =   200;
@@ -164,18 +167,52 @@
     [self.ringDevicesTabItem setView:self.devicesVC.view];
 }
 
-- (IBAction)addAccount:(id)sender {
+- (void)createSIPAccount
+{
     QModelIndex qIdx =  AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
 
     auto newAccName = [[NSString alloc] initWithFormat:@"%@ account",
-                AccountModel::instance().protocolModel()->data(qIdx, Qt::DisplayRole).toString().toNSString(), nil];
+                                          AccountModel::instance().protocolModel()->data(qIdx, Qt::DisplayRole).toString().toNSString(), nil];
     auto acc = AccountModel::instance().add([newAccName UTF8String], qIdx);
     acc->setDisplayName(acc->alias());
     AccountModel::instance().save();
 }
 
-- (IBAction)protocolSelectedChanged:(id)sender {
+- (void)createRingAccount
+{
+    wizard = [[RingWizardWC alloc] initWithWindowNibName:@"RingWizard"];
+    [wizard showChooseWithCancelButton: YES];
+    // [wizard.window makeKeyAndOrderFront:self];
+#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9
+    [self.view.window beginSheet:wizard.window completionHandler:nil];
+#else
+    [NSApp beginSheet: wizard.window
+       modalForWindow: self.view.window
+        modalDelegate: self
+       didEndSelector: nil
+          contextInfo: nil];
+#endif
+    [wizard showWindow:self];
+}
 
+- (IBAction)addAccount:(id)sender
+{
+    QModelIndex qProtocolIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
+    auto protocol = qvariant_cast<Account::Protocol> (AccountModel::instance().protocolModel()->data( qProtocolIdx, Qt::UserRole));
+    switch (protocol){
+        case Account::Protocol::SIP:{
+            [self createSIPAccount];
+            break;
+        }
+        case Account::Protocol::RING:{
+            [self createRingAccount];
+            break;
+        }
+    }
+}
+
+- (IBAction)protocolSelectedChanged:(id)sender
+{
     int index = [sender indexOfSelectedItem];
     auto qIdx = AccountModel::instance().protocolModel()->index(index, 0);
     AccountModel::instance().protocolModel()->selectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
@@ -187,7 +224,6 @@
     for(NSTabViewItem* item in configPanels.tabViewItems) {
         [configPanels removeTabViewItem:item];
     }
-
     [configPanels insertTabViewItem:generalTabItem atIndex:0];
     [configPanels insertTabViewItem:mediaTabItem atIndex:1];
     [configPanels insertTabViewItem:advancedTabItem atIndex:2];
diff --git a/src/RingWizardChooseVC.h b/src/RingWizardChooseVC.h
new file mode 100644
index 0000000..acd19f0
--- /dev/null
+++ b/src/RingWizardChooseVC.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ *  Author: Loïc Siret <loic.siret@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+#import <Cocoa/Cocoa.h>
+
+@class RingWizardWC;
+
+
+typedef NS_ENUM(NSInteger, WizardAction) {
+    WIZARD_ACTION_INVALID = -1,
+    WIZARD_ACTION_NEW = 0,
+    WIZARD_ACTION_LINK = 1,
+};
+
+@protocol RingWizardChooseDelegate <NSObject>
+
+- (void)didCompleteWithAction:(WizardAction)action;
+
+@end
+
+@interface RingWizardChooseVC : NSViewController
+
+@property (weak, nonatomic) id <RingWizardChooseDelegate> delegate;
+
+@property BOOL isCancelable;
+
+- (void)showCancelButton:(BOOL)showCancel;
+
+@end
+
diff --git a/src/RingWizardChooseVC.mm b/src/RingWizardChooseVC.mm
new file mode 100644
index 0000000..1658d1b
--- /dev/null
+++ b/src/RingWizardChooseVC.mm
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ *  Author: Loïc Siret <loic.siret@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import "RingWizardChooseVC.h"
+
+@interface RingWizardChooseVC()
+
+@end
+
+@implementation RingWizardChooseVC
+
+@synthesize delegate;
+
+- (void)showCancelButton:(BOOL)showCancel{
+    self.isCancelable = showCancel;
+}
+
+- (IBAction)createRingAccount:(id)sender
+{
+    if ([self.delegate respondsToSelector:@selector(didCompleteWithAction:)]){
+        [delegate didCompleteWithAction:WizardAction::WIZARD_ACTION_NEW];
+    }
+}
+
+- (IBAction)linkExistingRingAccount:(id)sender
+{
+    if ([self.delegate respondsToSelector:@selector(didCompleteWithAction:)]){
+        [delegate didCompleteWithAction:WizardAction::WIZARD_ACTION_LINK];
+    }
+}
+
+- (IBAction)onCancel:(id)sender
+{
+    if ([self.delegate respondsToSelector:@selector(didCompleteWithAction:)]){
+        [delegate didCompleteWithAction:WIZARD_ACTION_INVALID];
+    }
+}
+
+@end
diff --git a/src/RingWizardLinkAccountVC.h b/src/RingWizardLinkAccountVC.h
new file mode 100644
index 0000000..bb8151c
--- /dev/null
+++ b/src/RingWizardLinkAccountVC.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ *  Author: Loïc Siret <loic.siret@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@protocol RingWizardLinkDelegate <NSObject>
+- (void)didLinkAccountWithSuccess:(BOOL)success;
+@end
+
+@interface RingWizardLinkAccountVC : NSViewController
+@property (nonatomic, weak) NSWindowController <RingWizardLinkDelegate>* delegate;
+@property (nonatomic, weak) NSString* pinValue;
+@property (nonatomic, weak) NSString* passwordValue;
+
+- (void)show;
+@end
diff --git a/src/RingWizardLinkAccountVC.mm b/src/RingWizardLinkAccountVC.mm
new file mode 100644
index 0000000..a30a69f
--- /dev/null
+++ b/src/RingWizardLinkAccountVC.mm
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ *  Author: Loïc Siret <loic.siret@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import "RingWizardLinkAccountVC.h"
+//Cocoa
+#import <AddressBook/AddressBook.h>
+#import <Quartz/Quartz.h>
+
+//Qt
+#import <QUrl>
+#import <QPixmap>
+
+//LRC
+#import <accountmodel.h>
+#import <protocolmodel.h>
+#import <profilemodel.h>
+#import <QItemSelectionModel>
+#import <account.h>
+#import <certificate.h>
+#import <profilemodel.h>
+#import <profile.h>
+#import <person.h>
+
+#import "Constants.h"
+
+@interface RingWizardLinkAccountVC ()
+
+@end
+
+@implementation RingWizardLinkAccountVC {
+    __unsafe_unretained IBOutlet NSView* initialContainer;
+    __unsafe_unretained IBOutlet NSTextField* pinField;
+    __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
+    __unsafe_unretained IBOutlet NSTextField* pinLabel;
+    __unsafe_unretained IBOutlet NSTextField* passwordLabel;
+    __unsafe_unretained IBOutlet NSButton* createButton;
+
+    __unsafe_unretained IBOutlet NSView* loadingContainer;
+    __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
+
+    __unsafe_unretained IBOutlet NSView* errorContainer;
+
+    Account* accountToCreate;
+    NSTimer* errorTimer;
+    QMetaObject::Connection stateChanged;
+}
+
+- (void)show
+{
+    [initialContainer setHidden:NO];
+    [loadingContainer setHidden:YES];
+    [errorContainer setHidden:YES];
+}
+
+- (void)showError
+{
+    [initialContainer setHidden:YES];
+    [loadingContainer setHidden:YES];
+    [errorContainer setHidden:NO];
+}
+- (void)showLoading
+{
+    [initialContainer setHidden:YES];
+    [loadingContainer setHidden:NO];
+    [progressBar startAnimation:nil];
+    [errorContainer setHidden:YES];
+}
+
+- (IBAction)importRingAccount:(id)sender
+{
+    [self showLoading];
+    if (auto profile = ProfileModel::instance().selectedProfile()) {
+        profile->person()->setFormattedName([NSFullUserName() UTF8String]);
+        profile->save();
+    }
+    accountToCreate = AccountModel::instance().add(QString::fromNSString(NSFullUserName()), Account::Protocol::RING);
+    accountToCreate->setArchivePin(QString::fromNSString(self.pinValue));
+    accountToCreate->setArchivePassword(QString::fromNSString(self.passwordValue));
+
+    [self setCallback];
+
+    [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
+    [self registerDefaultPreferences];
+}
+
+- (IBAction)dismissViewWithError:(id)sender
+{
+    [self.delegate didLinkAccountWithSuccess:NO];
+}
+
+- (IBAction)back:(id)sender
+{
+    [self show];
+}
+
+/**
+ * Set default values for preferences
+ */
+- (void)registerDefaultPreferences
+{
+    // enable AutoStartup
+    LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
+    if (loginItemsRef == nil) return;
+    CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
+    LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
+    if (itemRef) CFRelease(itemRef);
+
+    // enable Notifications
+    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
+}
+
+- (void)saveAccount
+{
+    accountToCreate->setUpnpEnabled(YES); // Always active upnp
+    accountToCreate << Account::EditAction::SAVE;
+}
+
+- (void)setCallback
+{
+    errorTimer = [NSTimer scheduledTimerWithTimeInterval:30
+                                                  target:self
+                                                selector:@selector(didLinkFailed) userInfo:nil
+                                                 repeats:NO];
+
+    stateChanged = QObject::connect(&AccountModel::instance(),
+                                    &AccountModel::accountStateChanged,
+                                    [=](Account *account, const Account::RegistrationState state) {
+                                        switch(state){
+                                            case Account::RegistrationState::READY:
+                                            case Account::RegistrationState::TRYING:
+                                            case Account::RegistrationState::UNREGISTERED:{
+                                                accountToCreate<< Account::EditAction::RELOAD;
+                                                QObject::disconnect(stateChanged);
+                                                [errorTimer invalidate];
+                                                [self.delegate didLinkAccountWithSuccess:YES];
+                                                break;
+                                            }
+                                            case Account::RegistrationState::ERROR:
+                                                QObject::disconnect(stateChanged);
+                                                [errorTimer invalidate];
+                                                [self showError];
+                                                break;
+                                            case Account::RegistrationState::INITIALIZING:
+                                            case Account::RegistrationState::COUNT__:{
+                                                //DO Nothing
+                                                break;
+                                            }
+                                        }
+                                    });
+}
+
+
+- (void)didLinkFailed
+{
+    [self showError];
+}
+
+@end
diff --git a/src/RingWizardNewAccountVC.h b/src/RingWizardNewAccountVC.h
new file mode 100644
index 0000000..e6232f1
--- /dev/null
+++ b/src/RingWizardNewAccountVC.h
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ *  Author: Loïc Siret <loic.siret@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@protocol RingWizardNewDelegate <NSObject>
+- (void)didCreateAccountWithSuccess:(BOOL)success;
+@end
+
+@interface RingWizardNewAccountVC : NSViewController
+
+@property (nonatomic, weak)NSWindowController <RingWizardNewDelegate>* delegate;
+
+@property (nonatomic, weak)NSString* alias;
+@property (nonatomic, weak)NSString* password;
+- (void)show;
+@end
diff --git a/src/RingWizardNewAccountVC.mm b/src/RingWizardNewAccountVC.mm
new file mode 100644
index 0000000..fbe3662
--- /dev/null
+++ b/src/RingWizardNewAccountVC.mm
@@ -0,0 +1,228 @@
+/*
+ *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ *  Author: Loïc Siret <loic.siret@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import "RingWizardNewAccountVC.h"
+
+
+//Cocoa
+#import <AddressBook/AddressBook.h>
+#import <Quartz/Quartz.h>
+
+//Qt
+#import <QUrl>
+#import <QPixmap>
+
+//LRC
+#import <accountmodel.h>
+#import <protocolmodel.h>
+#import <profilemodel.h>
+#import <QItemSelectionModel>
+#import <account.h>
+#import <certificate.h>
+#import <profilemodel.h>
+#import <profile.h>
+#import <person.h>
+
+#import "AppDelegate.h"
+#import "Constants.h"
+#import "views/NSImage+Extensions.h"
+#import "views/NSColor+RingTheme.h"
+
+@interface RingWizardNewAccountVC ()
+@end
+
+@implementation RingWizardNewAccountVC
+{
+    __unsafe_unretained IBOutlet NSButton* photoView;
+    __unsafe_unretained IBOutlet NSTextField* nicknameField;
+    __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
+    __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
+    __unsafe_unretained IBOutlet NSTextField* indicationLabel;
+    __unsafe_unretained IBOutlet NSTextField* passwordLabel;
+    __unsafe_unretained IBOutlet NSButton* createButton;
+    __unsafe_unretained IBOutlet NSButton* cancelButton;
+    Account* accountToCreate;
+    NSTimer* errorTimer;
+    QMetaObject::Connection stateChanged;
+}
+
+NSInteger const NICKNAME_TAG        = 1;
+
+
+- (void)show
+{
+    AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+    [nicknameField setTag:NICKNAME_TAG];
+    [nicknameField setStringValue:NSFullUserName()];
+    [self controlTextDidChange:[NSNotification notificationWithName:@"PlaceHolder" object:nicknameField]];
+
+    NSData* imgData = [[[ABAddressBook sharedAddressBook] me] imageData];
+    if (imgData != nil) {
+        [photoView setImage:[[NSImage alloc] initWithData:imgData]];
+    } else
+        [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
+
+    [photoView setWantsLayer: YES];
+    photoView.layer.cornerRadius = photoView.frame.size.width / 2;
+    photoView.layer.masksToBounds = YES;
+}
+
+- (IBAction)editPhoto:(id)sender
+{
+   auto pictureTaker = [IKPictureTaker pictureTaker];
+
+    [pictureTaker beginPictureTakerSheetForWindow:[self.delegate window]
+                                     withDelegate:self
+                                   didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
+                                      contextInfo:nil];
+
+}
+
+- (void)pictureTakerDidEnd:(IKPictureTaker *) picker
+                 returnCode:(NSInteger) code
+                contextInfo:(void*) contextInfo
+{
+    if (auto outputImage = [picker outputImage]) {
+        [photoView setImage:outputImage];
+    } else
+        [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
+}
+
+- (IBAction)createRingAccount:(id)sender
+{
+    [nicknameField setHidden:YES];
+    [progressBar setHidden:NO];
+    [createButton setHidden:YES];
+    [photoView setHidden:YES];
+    [passwordField setHidden:YES];
+    [passwordLabel setHidden:YES];
+    [cancelButton setHidden:YES];
+    [progressBar startAnimation:nil];
+    [indicationLabel setStringValue:NSLocalizedString(@"Just a moment...",
+                                                      @"Indication for user")];
+
+    if ([self.alias isEqualToString:@""]) {
+        self.alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
+    }
+    accountToCreate = AccountModel::instance().add(QString::fromNSString(self.alias), Account::Protocol::RING);
+
+    accountToCreate->setAlias([self.alias UTF8String]);
+    accountToCreate->setDisplayName([self.alias UTF8String]);
+
+    if (auto profile = ProfileModel::instance().selectedProfile()) {
+        profile->person()->setFormattedName([self.alias UTF8String]);
+        QPixmap p;
+        auto smallImg = [NSImage imageResize:[photoView image] newSize:{100,100}];
+        if (p.loadFromData(QByteArray::fromNSData([smallImg TIFFRepresentation]))) {
+            profile->person()->setPhoto(QVariant(p));
+        }
+        profile->save();
+    }
+
+    QModelIndex qIdx =  AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
+
+    [self setCallback];
+
+    [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
+    [self registerDefaultPreferences];
+}
+
+/**
+ * Set default values for preferences
+ */
+- (void)registerDefaultPreferences
+{
+    // enable AutoStartup
+    LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
+    if (loginItemsRef == nil) return;
+    CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
+    LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
+    if (itemRef) CFRelease(itemRef);
+
+    // enable Notifications
+    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
+}
+
+- (void)saveAccount
+{
+    accountToCreate->setArchivePassword(QString::fromNSString(passwordField.stringValue));
+    accountToCreate->setUpnpEnabled(YES); // Always active upnp
+    accountToCreate << Account::EditAction::SAVE;
+}
+
+- (void)setCallback
+{
+    errorTimer = [NSTimer scheduledTimerWithTimeInterval:30
+                                                  target:self
+                                                selector:@selector(didCreateFailed) userInfo:nil
+                                                 repeats:NO];
+    stateChanged = QObject::connect(&AccountModel::instance(),
+                     &AccountModel::accountStateChanged,
+                     [=](Account *account, const Account::RegistrationState state) {
+                                                             switch(state){
+                                                                 case Account::RegistrationState::READY:
+                                                                 case Account::RegistrationState::TRYING:
+                                                                 case Account::RegistrationState::UNREGISTERED:{
+                                                                     accountToCreate<< Account::EditAction::RELOAD;
+                                                                     QObject::disconnect(stateChanged);
+                                                                     [self.delegate didCreateAccountWithSuccess:YES];
+                                                                     break;
+                                                                 }
+                                                                 case Account::RegistrationState::ERROR:
+                                                                     QObject::disconnect(stateChanged);
+                                                                     [self.delegate didCreateAccountWithSuccess:NO];
+                                                                     break;
+                                                                 case Account::RegistrationState::INITIALIZING:
+                                                                 case Account::RegistrationState::COUNT__:{
+                                                                     //DO Nothing
+                                                                     break;
+                                                                 }
+                                                             }
+                                                         });
+}
+
+- (void)didCreateFailed
+{
+    [self.delegate didCreateAccountWithSuccess:NO];
+}
+
+- (IBAction)cancel:(id)sender
+{
+    [self.delegate didCreateAccountWithSuccess:NO];
+}
+
+#pragma mark - NSOpenSavePanelDelegate delegate methods
+
+- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError
+{
+    return YES;
+}
+
+-(void)controlTextDidChange:(NSNotification *)notif
+{
+    NSTextField* textField = [notif object];
+    // else it is NICKNAME_TAG field
+    NSString* alias = textField.stringValue;
+    if ([alias isEqualToString:@""]) {
+        alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
+    }
+    self.alias = alias;
+}
+
+@end
diff --git a/src/RingWizardWC.h b/src/RingWizardWC.h
index 885e314..b68c2c7 100644
--- a/src/RingWizardWC.h
+++ b/src/RingWizardWC.h
@@ -18,7 +18,15 @@
  */
 
 #import <Cocoa/Cocoa.h>
+#import "RingWizardChooseVC.h"
+#import "RingWizardNewAccountVC.h"
+#import "RingWizardLinkAccountVC.h"
+@interface RingWizardWC : NSWindowController <NSWindowDelegate, NSPathControlDelegate,
+    NSOpenSavePanelDelegate, RingWizardChooseDelegate, RingWizardNewDelegate,
+    RingWizardLinkDelegate>
 
-@interface RingWizardWC : NSWindowController <NSWindowDelegate, NSPathControlDelegate, NSOpenSavePanelDelegate>
 
+- (void)showChooseWithCancelButton:(BOOL)showCancel;
+- (void)showNewAccountVC;
+- (void)showLinkAccountVC;
 @end
diff --git a/src/RingWizardWC.mm b/src/RingWizardWC.mm
index 61650f0..373eb80 100644
--- a/src/RingWizardWC.mm
+++ b/src/RingWizardWC.mm
@@ -22,188 +22,149 @@
 #import <AddressBook/AddressBook.h>
 #import <Quartz/Quartz.h>
 
-//Qt
-#import <QUrl>
-#import <QPixmap>
-
-//LRC
-#import <accountmodel.h>
-#import <protocolmodel.h>
-#import <profilemodel.h>
-#import <QItemSelectionModel>
-#import <account.h>
-#import <certificate.h>
-#import <profilemodel.h>
-#import <profile.h>
-#import <person.h>
 
 #import "AppDelegate.h"
 #import "Constants.h"
 #import "views/NSImage+Extensions.h"
 #import "views/NSColor+RingTheme.h"
+#import "RingWizardNewAccountVC.h"
+#import "RingWizardLinkAccountVC.h"
+#import "RingWizardChooseVC.h"
 
+
+@interface RingWizardWC ()
+
+@property (retain, nonatomic)IBOutlet NSView* container;
+
+@end
 @implementation RingWizardWC {
-
-    __unsafe_unretained IBOutlet NSButton* photoView;
-    __unsafe_unretained IBOutlet NSTextField* nicknameField;
-    __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
-    __unsafe_unretained IBOutlet NSTextField* indicationLabel;
-    __unsafe_unretained IBOutlet NSButton* createButton;
-
-    Account* accountToCreate;
+    IBOutlet RingWizardNewAccountVC* newAccountWC;
+    IBOutlet RingWizardLinkAccountVC* linkAccountWC;
+    IBOutlet RingWizardChooseVC* chooseActiontWC;
+    float initialHeight;
+    float currentHeight;
+    BOOL isCancelable;
 }
 
-NSInteger const NICKNAME_TAG        = 1;
-
-- (void)windowDidLoad {
+- (void)windowDidLoad
+{
     [super windowDidLoad];
 
-    [nicknameField setTag:NICKNAME_TAG];
-
     [self.window setBackgroundColor:[NSColor ringGreyHighlight]];
+    chooseActiontWC = [[RingWizardChooseVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
+    [chooseActiontWC setDelegate:self];
+    linkAccountWC = [[RingWizardLinkAccountVC alloc] initWithNibName:@"RingWizardLinkAccount" bundle:nil];
+    [linkAccountWC setDelegate:self];
+    newAccountWC = [[RingWizardNewAccountVC alloc] initWithNibName:@"RingWizardNewAccount" bundle:nil];
+    [newAccountWC setDelegate:self];
+    initialHeight = self.window.frame.size.height;
+    currentHeight = self.window.frame.size.height;
+    isCancelable = NO;
+    [self showView:chooseActiontWC.view];
+}
 
-    AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
-
-    if(![appDelegate checkForRingAccount]) {
-        accountToCreate = AccountModel::instance().add(QString::fromNSString(NSFullUserName()), Account::Protocol::RING);
-
-        [nicknameField setStringValue:NSFullUserName()];
-        [self controlTextDidChange:[NSNotification notificationWithName:@"PlaceHolder" object:nicknameField]];
+- (void)removeSubviews
+{
+    while ([self.container.subviews count] > 0)
+    {
+        [[self.container.subviews firstObject] removeFromSuperview];
     }
-
-    NSData* imgData = [[[ABAddressBook sharedAddressBook] me] imageData];
-    if (imgData != nil) {
-        [photoView setImage:[[NSImage alloc] initWithData:imgData]];
-    } else
-        [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
-
-    [photoView setWantsLayer: YES];
-    photoView.layer.cornerRadius = photoView.frame.size.width / 2;
-    photoView.layer.masksToBounds = YES;
 }
 
-- (IBAction) editPhoto:(id)sender
+#define minHeight 135
+- (void)showView: (NSView*) view
 {
-    auto pictureTaker = [IKPictureTaker pictureTaker];
-    [pictureTaker beginPictureTakerSheetForWindow:self.window
-                                     withDelegate:self
-                                   didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
-                                      contextInfo:nil];
-}
-
-- (void) pictureTakerDidEnd:(IKPictureTaker *) picker
-                 returnCode:(NSInteger) code
-                contextInfo:(void*) contextInfo
-{
-    if (auto outputImage = [picker outputImage]) {
-        [photoView setImage:outputImage];
-    } else
-        [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
-}
-
-- (IBAction)shareRingID:(id)sender {
-    auto sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:[NSArray arrayWithObject:[nicknameField stringValue]]];
-    [sharingServicePicker showRelativeToRect:[sender bounds]
-                                      ofView:sender
-                               preferredEdge:NSMinYEdge];
-}
-
-- (IBAction)createRingAccount:(id)sender
-{
-    [nicknameField setHidden:YES];
-    [progressBar setHidden:NO];
-    [createButton setHidden:YES];
-    [photoView setHidden:YES];
-    [progressBar startAnimation:nil];
-    [indicationLabel setStringValue:NSLocalizedString(@"Just a moment...",
-                                                      @"Indication for user")];
-
-    if (auto profile = ProfileModel::instance().selectedProfile()) {
-        profile->person()->setFormattedName([[nicknameField stringValue] UTF8String]);
-        QPixmap p;
-        auto smallImg = [NSImage imageResize:[photoView image] newSize:{100,100}];
-        if (p.loadFromData(QByteArray::fromNSData([smallImg TIFFRepresentation]))) {
-            profile->person()->setPhoto(QVariant(p));
-        }
-        profile->save();
+    [self removeSubviews];
+    NSRect frame = [self.container frame];
+    frame.size.height = MAX(minHeight, view.bounds.size.height);
+    [view setFrame:frame];
+    [self.container setFrame:frame];
+    float size = 0;
+    NSView *container = self.window.contentView;
+    for (NSView *child in container.subviews){
+        size += child.frame.size.height;
     }
-
-    QModelIndex qIdx =  AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
-
-    [self setCallback];
-
-    [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
-    [self registerDefaultPreferences];
-}
-
-/**
- * Set default values for preferences
- */
-- (void) registerDefaultPreferences
-{
-    // enable AutoStartup
-    LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
-    if (loginItemsRef == nil) return;
-    CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
-    LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
-    if (itemRef) CFRelease(itemRef);
-
-    // enable Notifications
-    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
-}
-
-- (void) saveAccount
-{
-    accountToCreate->setUpnpEnabled(YES); // Always active upnp
-    accountToCreate << Account::EditAction::SAVE;
-}
-
-- (void) setCallback
-{
-    QObject::connect(&AccountModel::instance(),
-                     &AccountModel::accountStateChanged,
-                     [=](Account *account, const Account::RegistrationState state) {
-                         [self.window close];
-                         AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
-                         [appDelegate showMainWindow];
-                     });
-}
-
-- (IBAction)goToApp:(id)sender
-{
-    [self.window close];
-    AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
-    [appDelegate showMainWindow];
-}
-
-#pragma mark - NSOpenSavePanelDelegate delegate methods
-
-- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError
-{
-    return YES;
-}
-
-#pragma mark - NSTextFieldDelegate methods
-
--(void)controlTextDidChange:(NSNotification *)notif
-{
-    NSTextField* textField = [notif object];
-    // else it is NICKNAME_TAG field
-    NSString* alias = textField.stringValue;
-    if ([alias isEqualToString:@""]) {
-        alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
+    if (currentHeight != size){
+        currentHeight = size;
+        NSRect frameWindows = self.window.frame;
+        frameWindows.size.height = currentHeight;
+        [self.window setFrame:frameWindows display:YES animate:YES];
     }
-    accountToCreate->setAlias([alias UTF8String]);
-    accountToCreate->setDisplayName([alias UTF8String]);
+    [self.container addSubview:view];
+}
+
+- (void)showChooseWithCancelButton:(BOOL)showCancel
+{
+    [self showView: chooseActiontWC.view];
+    [chooseActiontWC showCancelButton:showCancel];
+    isCancelable = showCancel;
+}
+
+- (void)showNewAccountVC
+{
+    [self showView: newAccountWC.view];
+    [newAccountWC show];
+}
+
+- (void)showLinkAccountVC
+{
+    [self showView: linkAccountWC.view];
+    [linkAccountWC show];
 }
 
 # pragma NSWindowDelegate methods
 
 - (void)windowWillClose:(NSNotification *)notification
 {
-    AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
-    if ([appDelegate checkForRingAccount]) {
-        [appDelegate showMainWindow];
+    if (!isCancelable){
+        AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+        if ([appDelegate checkForRingAccount]) {
+            [appDelegate showMainWindow];
+        }
+    }
+}
+
+#pragma - WizardChooseDelegate methods
+
+- (void)didCompleteWithAction:(WizardAction)action
+{
+    if (action == WIZARD_ACTION_LINK){
+        [self showLinkAccountVC];
+    } else if (action == WIZARD_ACTION_NEW){
+        [self showNewAccountVC];
+    } else {
+        [self.window close];
+    }
+
+}
+
+#pragma - WizardCreateAccountDelegate methods
+
+- (void)didCreateAccountWithSuccess:(BOOL)success
+{
+    if (success) {
+        [self.window close];
+        if (!isCancelable){
+            AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+            [appDelegate showMainWindow];
+        }
+    } else {
+        [self showChooseWithCancelButton:isCancelable];
+    }
+}
+
+#pragma - WizardLinkAccountDelegate methods
+
+- (void)didLinkAccountWithSuccess:(BOOL)success
+{
+    if (success) {
+        [self.window close];
+        if (!isCancelable){
+            AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+            [appDelegate showMainWindow];
+        }
+    } else {
+        [self showChooseWithCancelButton:isCancelable];
     }
 }