/*
 * Copyright (C) 2014 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 "WKPDFPageNumberIndicator.h"

#if PLATFORM(IOS)

#import "UIKitSPI.h"
#import <WebCore/LocalizedStrings.h>
#import <pal/spi/cocoa/QuartzCoreSPI.h>
#import <wtf/RetainPtr.h>
#import <wtf/text/WTFString.h>

const CGFloat indicatorMargin = 20;
const CGFloat indicatorVerticalPadding = 6;
const CGFloat indicatorHorizontalPadding = 10;
const CGFloat indicatorCornerRadius = 7;
const CGFloat indicatorLabelOpacity = 0.4;
const CGFloat indicatorFontSize = 16;

const NSTimeInterval indicatorTimeout = 2;
const NSTimeInterval indicatorFadeDuration = 0.5;
const NSTimeInterval indicatorMoveDuration = 0.3;

@implementation WKPDFPageNumberIndicator {
    RetainPtr<UILabel> _label;
    RetainPtr<_UIBackdropView> _backdropView;
    RetainPtr<NSTimer> _timer;

    bool _hasValidPageCountAndCurrentPage;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (!self)
        return nil;

    self.alpha = 0;
    self.layer.allowsGroupOpacity = NO;
    self.layer.allowsGroupBlending = NO;

    _UIBackdropViewSettings *backdropViewSettings = [_UIBackdropViewSettings settingsForPrivateStyle:_UIBackdropViewStyle_Light];
    backdropViewSettings.scale = 0.5;

    _backdropView = adoptNS([[_UIBackdropView alloc] initWithSettings:backdropViewSettings]);
    [_backdropView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [self addSubview:_backdropView.get()];
    [self _makeRoundedCorners];

    _label = adoptNS([[UILabel alloc] initWithFrame:CGRectZero]);

    [_label setOpaque:NO];
    [_label setBackgroundColor:nil];
    [_label setTextAlignment:NSTextAlignmentCenter];
    [_label setFont:[UIFont boldSystemFontOfSize:indicatorFontSize]];
    [_label setTextColor:[UIColor blackColor]];
    [_label setAlpha:indicatorLabelOpacity];
    [_label setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [[_label layer] setCompositingFilter:[CAFilter filterWithType:kCAFilterPlusD]];

    [self addSubview:_label.get()];
    
    return self;
}

- (void)dealloc
{
    [_timer invalidate];
    [super dealloc];
}

- (void)setCurrentPageNumber:(unsigned)currentPageNumber
{
    if (_currentPageNumber == currentPageNumber)
        return;

    _currentPageNumber = currentPageNumber;
    [self _updateLabel];
}

- (void)setPageCount:(unsigned)pageCount
{
    if (_pageCount == pageCount)
        return;

    _pageCount = pageCount;
    [self _updateLabel];
}

- (void)show
{
    self.alpha = 1;

    if (_timer)
        [_timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:indicatorTimeout]];
    else
        _timer = [NSTimer scheduledTimerWithTimeInterval:indicatorTimeout target:self selector:@selector(hide:) userInfo:nil repeats:NO];
}

- (void)hide
{
    [self hide:nil];
}

- (void)hide:(NSTimer *)timer
{
    [UIView animateWithDuration:indicatorFadeDuration animations:^{
        self.alpha = 0;
    }];

    [_timer invalidate];
    _timer = nullptr;
}

- (void)moveToPoint:(CGPoint)point animated:(BOOL)animated
{
    point.x += indicatorMargin;
    point.y += indicatorMargin;

    void (^animations)() = ^{
        self.frameOrigin = point;
    };
    if (animated)
        [UIView animateWithDuration:indicatorMoveDuration animations:animations];
    else
        animations();
}

- (CGSize)sizeThatFits:(CGSize)size
{
    CGSize labelSize = [_label sizeThatFits:[_label size]];
    labelSize.width += 2 * indicatorHorizontalPadding;
    labelSize.height += 2 * indicatorVerticalPadding;
    return labelSize;
}

- (void)_updateLabel
{
    [_label setText:[NSString localizedStringWithFormat:WEB_UI_STRING("%d of %d", "Label for PDF page number indicator."), _currentPageNumber, _pageCount]];
    [self sizeToFit];

    if (!_pageCount || !_currentPageNumber)
        return;

    // We don't want to show the indicator when the PDF loads, but rather on the first subsequent change.
    if (_hasValidPageCountAndCurrentPage)
        [self show];
    _hasValidPageCountAndCurrentPage = true;
}

- (void)_makeRoundedCorners
{
    CGSize cornerImageSize = CGSizeMake(2 * indicatorCornerRadius + 2, 2 * indicatorCornerRadius + 2);
    CGRect cornerImageBounds = CGRectMake(0, 0, cornerImageSize.width, cornerImageSize.height);

    UIGraphicsBeginImageContextWithOptions(cornerImageSize, NO, [UIScreen mainScreen].scale);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextAddRect(context, cornerImageBounds);

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:cornerImageBounds byRoundingCorners:(UIRectCorner)UIAllCorners cornerRadii:CGSizeMake(indicatorCornerRadius, indicatorCornerRadius)];
#pragma clang diagnostic pop
    CGContextAddPath(context, [cornerPath CGPath]);
    CGContextEOClip(context);
    CGContextFillRect(context, cornerImageBounds);
    CGContextRestoreGState(context);

    UIImage *cornerImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    UIView *contentView = [_backdropView contentView];

    UIEdgeInsets capInsets = UIEdgeInsetsMake(indicatorCornerRadius, indicatorCornerRadius, indicatorCornerRadius, indicatorCornerRadius);
    cornerImage = [cornerImage resizableImageWithCapInsets:capInsets];

    RetainPtr<UIImageView> cornerMaskView = adoptNS([[UIImageView alloc] initWithImage:cornerImage]);
    [cornerMaskView setAlpha:0];
    [cornerMaskView _setBackdropMaskViewFlags:_UIBackdropMaskViewAll];
    [cornerMaskView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [cornerMaskView setFrame:contentView.bounds];

    [contentView addSubview:cornerMaskView.get()];
}

@end

#endif /* PLATFORM(IOS) */
