/*
 * Copyright (C) 2016 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"

#if PLATFORM(IOS)

#import "ValidationBubble.h"

#import <pal/spi/ios/UIKitSPI.h>
#import <wtf/RetainPtr.h>
#import <wtf/SoftLinking.h>
#import <wtf/text/WTFString.h>

SOFT_LINK_FRAMEWORK(UIKit);
SOFT_LINK_CLASS(UIKit, UIFont);
SOFT_LINK_CLASS(UIKit, UILabel);
SOFT_LINK_CLASS(UIKit, UIPopoverPresentationController);
SOFT_LINK_CLASS(UIKit, UITapGestureRecognizer);
SOFT_LINK_CLASS(UIKit, UIView);
SOFT_LINK_CLASS(UIKit, UIViewController);
SOFT_LINK_CONSTANT(UIKit, UIFontTextStyleCallout, UIFontTextStyle);
SOFT_LINK_CONSTANT(UIKit, UIAccessibilityAnnouncementNotification, UIAccessibilityNotifications);
#define UIAccessibilityPostNotification getUIAccessibilityPostNotification
SOFT_LINK(UIKit, UIAccessibilityPostNotification, void, (UIAccessibilityNotifications n, id argument), (n, argument));

@interface WebValidationBubbleTapRecognizer : NSObject
@end

@implementation WebValidationBubbleTapRecognizer {
    RetainPtr<UIViewController> _popoverController;
    RetainPtr<UITapGestureRecognizer> _tapGestureRecognizer;
}

- (WebValidationBubbleTapRecognizer *)initWithPopoverController:(UIViewController *)popoverController
{
    self = [super init];
    if (!self)
        return nil;

    _popoverController = popoverController;
    _tapGestureRecognizer = adoptNS([allocUITapGestureRecognizerInstance() initWithTarget:self action:@selector(dismissPopover)]);
    [[_popoverController view] addGestureRecognizer:_tapGestureRecognizer.get()];

    return self;
}

- (void)dealloc
{
    [[_popoverController view] removeGestureRecognizer:_tapGestureRecognizer.get()];
    [super dealloc];
}

- (void)dismissPopover
{
    [_popoverController dismissViewControllerAnimated:NO completion:nil];
}

@end

@interface WebValidationBubbleDelegate : NSObject <UIPopoverPresentationControllerDelegate> {
}
@end

@implementation WebValidationBubbleDelegate

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
{
    UNUSED_PARAM(controller);
    UNUSED_PARAM(traitCollection);
    // This is needed to force UIKit to use a popover on iPhone as well.
    return UIModalPresentationNone;
}

@end

namespace WebCore {

static const CGFloat horizontalPadding = 17;
static const CGFloat verticalPadding = 9;
static const CGFloat maxLabelWidth = 300;

ValidationBubble::ValidationBubble(UIView* view, const String& message, const Settings&)
    : m_view(view)
    , m_message(message)
{
    m_popoverController = adoptNS([allocUIViewControllerInstance() init]);
    [m_popoverController setModalPresentationStyle:UIModalPresentationPopover];

    RetainPtr<UIView> popoverView = adoptNS([allocUIViewInstance() initWithFrame:CGRectZero]);
    [m_popoverController setView:popoverView.get()];
    m_tapRecognizer = adoptNS([[WebValidationBubbleTapRecognizer alloc] initWithPopoverController:m_popoverController.get()]);

    RetainPtr<UILabel> label = adoptNS([allocUILabelInstance() initWithFrame:CGRectZero]);
    [label setText:message];
    [label setFont:[getUIFontClass() preferredFontForTextStyle:getUIFontTextStyleCallout()]];
    m_fontSize = [[label font] pointSize];
    [label setLineBreakMode:NSLineBreakByTruncatingTail];
    [label setNumberOfLines:4];
    [popoverView addSubview:label.get()];

    CGSize labelSize = [label sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
    [label setFrame:CGRectMake(horizontalPadding, verticalPadding, labelSize.width, labelSize.height)];
    [popoverView setFrame:CGRectMake(horizontalPadding, verticalPadding, labelSize.width + horizontalPadding * 2, labelSize.height + verticalPadding * 2)];

    [m_popoverController setPreferredContentSize:popoverView.get().frame.size];
}

ValidationBubble::~ValidationBubble()
{
    [m_popoverController dismissViewControllerAnimated:NO completion:nil];
}

void ValidationBubble::show()
{
    // Protect the validation bubble so it stays alive until it is effectively presented. UIKit does not deal nicely with
    // dismissing a popover that is being presented.
    RefPtr<ValidationBubble> protectedThis(this);
    [m_presentingViewController presentViewController:m_popoverController.get() animated:NO completion:[protectedThis]() {
        // Hide this popover from VoiceOver and instead announce the message.
        [protectedThis->m_popoverController.get().view setAccessibilityElementsHidden:YES];
    }];

    UIAccessibilityPostNotification(getUIAccessibilityAnnouncementNotification(), m_message);
}

static UIViewController *fallbackViewController(UIView *view)
{
    for (UIView *currentView = view; currentView; currentView = currentView.superview) {
        if (UIViewController *viewController = [getUIViewControllerClass() viewControllerForView:currentView])
            return viewController;
    }
    NSLog(@"Failed to find a view controller to show form validation popover");
    return nil;
}

void ValidationBubble::setAnchorRect(const IntRect& anchorRect, UIViewController* presentingViewController)
{
    if (!presentingViewController)
        presentingViewController = fallbackViewController(m_view);

    UIPopoverPresentationController *presentationController = [m_popoverController popoverPresentationController];
    m_popoverDelegate = adoptNS([[WebValidationBubbleDelegate alloc] init]);
    presentationController.delegate = m_popoverDelegate.get();
    presentationController.passthroughViews = [NSArray arrayWithObjects:presentingViewController.view, m_view, nil];

    presentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
    presentationController.sourceView = m_view;
    presentationController.sourceRect = CGRectMake(anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
    m_presentingViewController = presentingViewController;
}

} // namespace WebCore

#endif // PLATFORM(IOS)
