multi-device: rewording and view improvement

Correct wording concerning multidevice Linking function.
Fix windows size in the account creation wizard.
Addings user hints to better understand Linking function.

Tuleap: #1158
Change-Id: I0d68a68ba61f51200052bb1a4428b82e79848447
diff --git a/src/ExportPasswordWC.mm b/src/ExportPasswordWC.mm
index f9b914c..054442e 100644
--- a/src/ExportPasswordWC.mm
+++ b/src/ExportPasswordWC.mm
@@ -100,8 +100,8 @@
                                                      }
                                                          break;
                                                      case Account::ExportOnRingStatus::WRONG_PASSWORD:{
-                                                         NSLog(@"Export ended with Wrong Password");
-                                                         [self showError:NSLocalizedString(@"Export ended with Wrong Password", @"Error shown to the user" )];
+                                                         NSLog(@"Export ended with wrong password");
+                                                         [self showError:NSLocalizedString(@"The password you entered does not unlock this account", @"Error shown to the user" )];
                                                      }
                                                          break;
                                                      case Account::ExportOnRingStatus::NETWORK_ERROR:{
@@ -121,18 +121,23 @@
 }
 
 //TODO: Move String formatting to a dedicated Utility Classes
-- (NSAttributedString *)formatPinMessage:(NSString*) pin
+- (NSAttributedString*) formatPinMessage:(NSString*) pin
 {
-    NSMutableAttributedString* hereIsThePin = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Your generated pin:","Title shown to user to concat with Pin")];
-    NSMutableAttributedString* thePin = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@\n", pin]];
+    NSMutableAttributedString* thePin = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n%@\n", pin]];
     [thePin beginEditing];
     NSRange range = NSMakeRange(0, [thePin length]);
-    [thePin addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Helvetica-Bold" size:12.0] range:range];
-    [hereIsThePin appendAttributedString:thePin];
-    NSMutableAttributedString* infos = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"This pin and the account password should be entered on your new device within 5 minutes. On most client, this is done from \"Existing Ring account\" menu. You may generate a new pin at any moment.","Infos on how to use the pin")];
-    [hereIsThePin appendAttributedString:infos];
+    [thePin addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Helvetica-Bold" size:20.0] range:range];
 
-    return hereIsThePin;
+    NSMutableParagraphStyle* mutParaStyle=[[NSMutableParagraphStyle alloc] init];
+    [mutParaStyle setAlignment:NSCenterTextAlignment];
+    
+    [thePin addAttributes:[NSDictionary dictionaryWithObject:mutParaStyle forKey:NSParagraphStyleAttributeName] range:range];
+
+    NSMutableAttributedString* infos = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"To complete the processs, you need to open Ring on the new device and choose the option \"Link this device to an account\". Your pin is valid for 10 minutes.","Title shown to user to concat with Pin")];
+    [thePin appendAttributedString:infos];
+    [thePin endEditing];
+
+    return thePin;
 }
 
 @end
diff --git a/src/RingWizardLinkAccountVC.mm b/src/RingWizardLinkAccountVC.mm
index 9b287e9..df3f0dd 100644
--- a/src/RingWizardLinkAccountVC.mm
+++ b/src/RingWizardLinkAccountVC.mm
@@ -56,6 +56,7 @@
     __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
 
     __unsafe_unretained IBOutlet NSView* errorContainer;
+    __unsafe_unretained IBOutlet NSPopover* helpContainer;
 
     Account* accountToCreate;
     NSTimer* errorTimer;
@@ -83,6 +84,12 @@
     [errorContainer setHidden:YES];
 }
 
+
+- (IBAction)showHelp:(id)sender
+{
+    [helpContainer showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxYEdge];
+}
+
 - (IBAction)importRingAccount:(id)sender
 {
     [self showLoading];
diff --git a/src/RingWizardNewAccountVC.h b/src/RingWizardNewAccountVC.h
index e6232f1..4838997 100644
--- a/src/RingWizardNewAccountVC.h
+++ b/src/RingWizardNewAccountVC.h
@@ -21,6 +21,7 @@
 
 @protocol RingWizardNewDelegate <NSObject>
 - (void)didCreateAccountWithSuccess:(BOOL)success;
+- (void)showView:(NSView*)view;
 @end
 
 @interface RingWizardNewAccountVC : NSViewController
@@ -29,5 +30,9 @@
 
 @property (nonatomic, weak)NSString* alias;
 @property (nonatomic, weak)NSString* password;
+@property (nonatomic, weak)NSString* repeatPassword;
+@property (readonly)BOOL isRepeatPasswordValid;
+@property (readonly)BOOL isPasswordValid;
+
 - (void)show;
 @end
diff --git a/src/RingWizardNewAccountVC.mm b/src/RingWizardNewAccountVC.mm
index dff5258..254e544 100644
--- a/src/RingWizardNewAccountVC.mm
+++ b/src/RingWizardNewAccountVC.mm
@@ -49,21 +49,41 @@
 
 @implementation RingWizardNewAccountVC
 {
+    __unsafe_unretained IBOutlet NSView* loadingView;
+    __unsafe_unretained IBOutlet NSView* creationView;
+
     __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 NSSecureTextField* passwordRepeatField;
     __unsafe_unretained IBOutlet NSTextField* passwordLabel;
+    __unsafe_unretained IBOutlet NSTextField* passwordRepeatLabel;
+    __unsafe_unretained IBOutlet NSImageView* passwordCheck;
+    __unsafe_unretained IBOutlet NSImageView* passwordRepeatCheck;
     __unsafe_unretained IBOutlet NSButton* createButton;
     __unsafe_unretained IBOutlet NSButton* cancelButton;
+
+    __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
     Account* accountToCreate;
     NSTimer* errorTimer;
     QMetaObject::Connection stateChanged;
 }
 
-NSInteger const NICKNAME_TAG        = 1;
+NSInteger const NICKNAME_TAG                    = 1;
 
+//ERROR CODE for textfields validations
+NSInteger const ERROR_PASSWORD_TOO_SHORT        = -1;
+NSInteger const ERROR_REPEAT_MISMATCH           = -2;
+
+
+- (BOOL)produceError:(NSError**)error withCode:(NSInteger)code andMessage:(NSString*)message
+{
+    if (error != NULL){
+        NSDictionary *errorDetail = @{NSLocalizedDescriptionKey: message};
+        *error = [NSError errorWithDomain:@"Input" code:code userInfo:errorDetail];
+    }
+    return NO;
+}
 
 - (void)show
 {
@@ -81,11 +101,25 @@
     [photoView setWantsLayer: YES];
     photoView.layer.cornerRadius = photoView.frame.size.width / 2;
     photoView.layer.masksToBounds = YES;
+
+    [self display:creationView];
+}
+
+- (void)removeSubviews
+{
+    while ([self.view.subviews count] > 0){
+        [[self.view.subviews firstObject] removeFromSuperview];
+    }
+}
+
+- (void)display:(NSView *)view
+{
+    [self.delegate showView:view];
 }
 
 - (IBAction)editPhoto:(id)sender
 {
-   auto pictureTaker = [IKPictureTaker pictureTaker];
+    auto pictureTaker = [IKPictureTaker pictureTaker];
 
     [pictureTaker beginPictureTakerSheetForWindow:[self.delegate window]
                                      withDelegate:self
@@ -104,18 +138,66 @@
         [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
 }
 
+#pragma mark - Input validation
+- (BOOL)isPasswordValid
+{
+    return self.password.length >= 6;
+}
+
+- (BOOL)isRepeatPasswordValid
+{
+    return [self.password isEqualToString:self.repeatPassword];
+}
+
+- (BOOL)validateRepeatPassword:(NSError **)error
+{
+    if (!self.isRepeatPasswordValid){
+        return [self produceError:error
+                         withCode:ERROR_REPEAT_MISMATCH
+                       andMessage:NSLocalizedString(@"Passwords don't match",
+                                                     @"Indication for user")];
+    }
+    return YES;
+}
+
+- (BOOL)validatePassword:(NSError **)error
+{
+    if (!self.isRepeatPasswordValid){
+        return [self produceError:error
+                         withCode:ERROR_PASSWORD_TOO_SHORT
+                       andMessage:NSLocalizedString(@"Password is too short",
+                                                     @"Indication for user")];
+    }
+    return YES;
+}
+
+- (BOOL)validateUserInputPassword:(NSError **)error
+{
+    return [self validatePassword:error] && [self validateRepeatPassword:error];
+}
+
 - (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];
+    NSError *error = nil;
+    if (![self validateUserInputPassword:&error]){
+        NSAlert* alert = [NSAlert alertWithMessageText:[error localizedDescription]
+                                         defaultButton:NSLocalizedString(@"Revise Input",
+                                                                         @"Button title")
+                                       alternateButton:nil
+                                           otherButton:nil
+                             informativeTextWithFormat:@"%@",error];
+
+        [alert beginSheetModalForWindow:passwordField.window
+                          modalDelegate:nil
+                         didEndSelector:NULL
+                            contextInfo:NULL];
+
+        return;
+    }
+
+    [self display:loadingView];
     [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");
@@ -139,7 +221,7 @@
         profile->save();
     }
 
-    QModelIndex qIdx =  AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
+    QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
 
     [self setCallback];
 
@@ -229,4 +311,14 @@
     self.alias = alias;
 }
 
++ (NSSet *)keyPathsForValuesAffectingIsPasswordValid
+{
+    return [NSSet setWithObjects:@"password", nil];
+}
+
++ (NSSet *)keyPathsForValuesAffectingIsRepeatPasswordValid
+{
+    return [NSSet setWithObjects:@"password", @"repeatPassword", nil];
+}
+
 @end
diff --git a/src/RingWizardWC.h b/src/RingWizardWC.h
index b68c2c7..62a5ec5 100644
--- a/src/RingWizardWC.h
+++ b/src/RingWizardWC.h
@@ -25,7 +25,6 @@
     NSOpenSavePanelDelegate, RingWizardChooseDelegate, RingWizardNewDelegate,
     RingWizardLinkDelegate>
 
-
 - (void)showChooseWithCancelButton:(BOOL)showCancel;
 - (void)showNewAccountVC;
 - (void)showLinkAccountVC;
diff --git a/src/RingWizardWC.mm b/src/RingWizardWC.mm
index 373eb80..bb4e101 100644
--- a/src/RingWizardWC.mm
+++ b/src/RingWizardWC.mm
@@ -41,26 +41,26 @@
     IBOutlet RingWizardNewAccountVC* newAccountWC;
     IBOutlet RingWizardLinkAccountVC* linkAccountWC;
     IBOutlet RingWizardChooseVC* chooseActiontWC;
-    float initialHeight;
-    float currentHeight;
     BOOL isCancelable;
 }
 
+- (instancetype)initWithWindowNibName:(NSString *)windowNibName{
+    self = [super initWithWindowNibName:windowNibName];
+
+    chooseActiontWC = [[RingWizardChooseVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
+    linkAccountWC = [[RingWizardLinkAccountVC alloc] initWithNibName:@"RingWizardLinkAccount" bundle:nil];
+    newAccountWC = [[RingWizardNewAccountVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
+    return self;
+}
+
 - (void)windowDidLoad
 {
     [super windowDidLoad];
-
-    [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];
+    [self.window setBackgroundColor:[NSColor ringGreyHighlight]];
+    [self showChooseWithCancelButton:isCancelable];
 }
 
 - (void)removeSubviews
@@ -71,33 +71,31 @@
     }
 }
 
-#define minHeight 135
-- (void)showView: (NSView*) view
+#define headerHeight 60
+#define minHeight 141
+#define defaultMargin 20
+- (void)showView:(NSView*)view
 {
     [self removeSubviews];
     NSRect frame = [self.container frame];
-    frame.size.height = MAX(minHeight, view.bounds.size.height);
+    float sizeFrame = MAX(minHeight, view.bounds.size.height);
+    frame.size.height = sizeFrame;
     [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;
-    }
-    if (currentHeight != size){
-        currentHeight = size;
-        NSRect frameWindows = self.window.frame;
-        frameWindows.size.height = currentHeight;
-        [self.window setFrame:frameWindows display:YES animate:YES];
-    }
+    float size = headerHeight + sizeFrame + defaultMargin;
+    NSRect frameWindows = self.window.frame;
+    frameWindows.size.height = size;
+    [self.window setFrame:frameWindows display:YES animate:YES];
+
     [self.container addSubview:view];
 }
 
 - (void)showChooseWithCancelButton:(BOOL)showCancel
 {
-    [self showView: chooseActiontWC.view];
     [chooseActiontWC showCancelButton:showCancel];
     isCancelable = showCancel;
+    [self showView:chooseActiontWC.view];
 }
 
 - (void)showNewAccountVC