/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "WKPasswordView.h"

#if PLATFORM(IOS)

#import "UIKitSPI.h"
#import "WKContentView.h"
#import "WKWebViewContentProvider.h"
#import <WebCore/LocalizedStrings.h>
#import <wtf/RetainPtr.h>
#import <wtf/text/WTFString.h>

const CGFloat passwordEntryFieldPadding = 10;

@interface WKPasswordView () <UIDocumentPasswordViewDelegate>
@end

@implementation WKPasswordView {
    RetainPtr<NSString> _documentName;
    RetainPtr<UIScrollView> _scrollView;
    RetainPtr<UIDocumentPasswordView> _passwordView;
    CGFloat _savedMinimumZoomScale;
    CGFloat _savedMaximumZoomScale;
    CGFloat _savedZoomScale;
    CGSize _savedContentSize;
    RetainPtr<UIColor> _savedBackgroundColor;
}

- (instancetype)initWithFrame:(CGRect)frame documentName:(NSString *)documentName
{
    self = [super initWithFrame:frame];
    if (!self)
        return nil;

    _documentName = adoptNS([documentName copy]);
    _passwordView = adoptNS([[UIDocumentPasswordView alloc] initWithDocumentName:_documentName.get()]);
    [_passwordView setFrame:self.bounds];
    [_passwordView setPasswordDelegate:self];
    [_passwordView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];

    self.autoresizesSubviews = YES;
    [self addSubview:_passwordView.get()];

    return self;
}

- (NSString *)documentName
{
    return _documentName.get();
}

- (void)layoutSubviews
{
    if (_scrollView)
        [_scrollView setContentSize:self.frame.size];
}

- (void)showInScrollView:(UIScrollView *)scrollView
{
    _scrollView = scrollView;

    _savedMinimumZoomScale = [_scrollView minimumZoomScale];
    _savedMaximumZoomScale = [_scrollView maximumZoomScale];
    _savedZoomScale = [_scrollView zoomScale];
    _savedContentSize = [_scrollView contentSize];
    _savedBackgroundColor = [_scrollView backgroundColor];

    [_scrollView setMinimumZoomScale:1];
    [_scrollView setMaximumZoomScale:1];
    [_scrollView setZoomScale:1];
    [_scrollView setContentSize:self.frame.size];
    [_scrollView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];

    [scrollView addSubview:self];
}

- (void)hide
{
    [_scrollView setMinimumZoomScale:_savedMinimumZoomScale];
    [_scrollView setMaximumZoomScale:_savedMaximumZoomScale];
    [_scrollView setZoomScale:_savedZoomScale];
    [_scrollView setContentSize:_savedContentSize];
    [_scrollView setBackgroundColor:_savedBackgroundColor.get()];

    _scrollView = nil;
    _savedBackgroundColor = nil;

    [self removeFromSuperview];
}

- (void)showPasswordFailureAlert
{
    [[_passwordView passwordField] setText:@""];
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:WEB_UI_STRING("The document could not be opened with that password.", "document password failure alert message") message:@"" preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:WEB_UI_STRING_KEY("OK", "OK (document password failure alert)", "OK button label in document password failure alert") style:UIAlertActionStyleDefault handler:[](UIAlertAction *) { }];

    [alert addAction:defaultAction];

    [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}

- (void)_keyboardDidShow:(NSNotification *)notification
{
    UITextField *passwordField = [_passwordView passwordField];
    if (!passwordField.isEditing)
        return;

    CGRect keyboardRect = [UIPeripheralHost visiblePeripheralFrame];
    if (CGRectIsEmpty(keyboardRect))
        return;

    UIWindow *window = [_scrollView window];
    keyboardRect = [window convertRect:keyboardRect fromWindow:nil];
    keyboardRect = [_scrollView convertRect:keyboardRect fromView:window];

    CGRect passwordFieldFrame = [passwordField convertRect:passwordField.bounds toView:_scrollView.get()];

    CGSize contentSize = [_passwordView bounds].size;
    contentSize.height += CGRectGetHeight(keyboardRect);
    [_scrollView setContentSize:contentSize];

    if (CGRectIntersectsRect(passwordFieldFrame, keyboardRect)) {
        CGFloat yDelta = CGRectGetMaxY(passwordFieldFrame) - CGRectGetMinY(keyboardRect);

        CGPoint contentOffset = [_scrollView contentOffset];
        contentOffset.y += yDelta + passwordEntryFieldPadding;

        [_scrollView setContentOffset:contentOffset animated:YES];
    }
}

#pragma mark UIDocumentPasswordViewDelegate

- (void)userDidEnterPassword:(NSString *)password forPasswordView:(UIDocumentPasswordView *)passwordView
{
    auto protectedSelf = retainPtr(self);
    if (_userDidEnterPassword)
        _userDidEnterPassword(password);
}

- (void)didBeginEditingPassword:(UITextField *)passwordField inView:(UIDocumentPasswordView *)passwordView
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)didEndEditingPassword:(UITextField *)passwordField inView:(UIDocumentPasswordView *)passwordView
{
    [_scrollView setContentSize:[_passwordView frame].size];

    UIEdgeInsets contentInset = [_scrollView contentInset];
    [_scrollView setContentOffset:CGPointMake(-contentInset.left, -contentInset.top) animated:YES];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
}

@end

#endif // PLATFORM(IOS)
