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

#import "FindIndicator.h"
#import "WKView.h"
#import <WebCore/GraphicsContext.h>

static const double bounceAnimationDuration = 0.12;
static const double timeBeforeFadeStarts = bounceAnimationDuration + 0.2;
static const double fadeOutAnimationDuration = 0.3;

using namespace WebCore;

@interface WebFindIndicatorView : NSView {
    RefPtr<WebKit::FindIndicator> _findIndicator;
}

- (id)_initWithFindIndicator:(PassRefPtr<WebKit::FindIndicator>)findIndicator;
@end

@implementation WebFindIndicatorView

- (id)_initWithFindIndicator:(PassRefPtr<WebKit::FindIndicator>)findIndicator
{
    if ((self = [super initWithFrame:NSZeroRect]))
        _findIndicator = findIndicator;

    return self;
}

- (void)drawRect:(NSRect)rect
{
    GraphicsContext graphicsContext(static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]));

    _findIndicator->draw(graphicsContext, enclosingIntRect(rect));
}

- (BOOL)isFlipped
{
    return YES;
}

@end

@interface WebFindIndicatorWindowAnimation : NSAnimation<NSAnimationDelegate> {
    WebKit::FindIndicatorWindow* _findIndicatorWindow;
    void (WebKit::FindIndicatorWindow::*_animationProgressCallback)(double progress);
    void (WebKit::FindIndicatorWindow::*_animationDidEndCallback)();
}

- (id)_initWithFindIndicatorWindow:(WebKit::FindIndicatorWindow *)findIndicatorWindow 
                 animationDuration:(CFTimeInterval)duration
         animationProgressCallback:(void (WebKit::FindIndicatorWindow::*)(double progress))animationProgressCallback
           animationDidEndCallback:(void (WebKit::FindIndicatorWindow::*)())animationDidEndCallback;
@end

@implementation WebFindIndicatorWindowAnimation

- (id)_initWithFindIndicatorWindow:(WebKit::FindIndicatorWindow *)findIndicatorWindow 
                 animationDuration:(CFTimeInterval)animationDuration
         animationProgressCallback:(void (WebKit::FindIndicatorWindow::*)(double progress))animationProgressCallback
           animationDidEndCallback:(void (WebKit::FindIndicatorWindow::*)())animationDidEndCallback
{
    if ((self = [super initWithDuration:animationDuration animationCurve:NSAnimationEaseInOut])) {
        _findIndicatorWindow = findIndicatorWindow;
        _animationProgressCallback = animationProgressCallback;
        _animationDidEndCallback = animationDidEndCallback;
        [self setDelegate:self];
        [self setAnimationBlockingMode:NSAnimationNonblocking];
    }
    return self;
}

- (void)setCurrentProgress:(NSAnimationProgress)progress
{
    (_findIndicatorWindow->*_animationProgressCallback)(progress);
}

- (void)animationDidEnd:(NSAnimation *)animation
{
    ASSERT(animation == self);

    (_findIndicatorWindow->*_animationDidEndCallback)();
}

@end

namespace WebKit {

PassOwnPtr<FindIndicatorWindow> FindIndicatorWindow::create(WKView *wkView)
{
    return adoptPtr(new FindIndicatorWindow(wkView));
}

FindIndicatorWindow::FindIndicatorWindow(WKView *wkView)
    : m_wkView(wkView)
    , m_bounceAnimationContext(0)
    , m_startFadeOutTimer(RunLoop::main(), this, &FindIndicatorWindow::startFadeOutTimerFired)
{
}

FindIndicatorWindow::~FindIndicatorWindow()
{
    closeWindow();
}

void FindIndicatorWindow::setFindIndicator(PassRefPtr<FindIndicator> findIndicator, bool fadeOut)
{
    if (m_findIndicator == findIndicator)
        return;

    m_findIndicator = findIndicator;

    // Get rid of the old window.
    closeWindow();

    if (!m_findIndicator)
        return;

    NSRect contentRect = m_findIndicator->frameRect();
    NSRect windowFrameRect = NSIntegralRect([m_wkView convertRect:contentRect toView:nil]);
    windowFrameRect.origin = [[m_wkView window] convertBaseToScreen:windowFrameRect.origin];

    NSRect windowContentRect = [NSWindow contentRectForFrameRect:windowFrameRect styleMask:NSBorderlessWindowMask];
    
    m_findIndicatorWindow.adoptNS([[NSWindow alloc] initWithContentRect:windowContentRect 
                                                              styleMask:NSBorderlessWindowMask 
                                                                backing:NSBackingStoreBuffered
                                                                  defer:NO]);

    [m_findIndicatorWindow.get() setBackgroundColor:[NSColor clearColor]];
    [m_findIndicatorWindow.get() setOpaque:NO];
    [m_findIndicatorWindow.get() setIgnoresMouseEvents:YES];

    RetainPtr<WebFindIndicatorView> findIndicatorView(AdoptNS, [[WebFindIndicatorView alloc] _initWithFindIndicator:m_findIndicator]);
    [m_findIndicatorWindow.get() setContentView:findIndicatorView.get()];

    [[m_wkView window] addChildWindow:m_findIndicatorWindow.get() ordered:NSWindowAbove];
    [m_findIndicatorWindow.get() setReleasedWhenClosed:NO];

    // Start the bounce animation.
    m_bounceAnimationContext = WKWindowBounceAnimationContextCreate(m_findIndicatorWindow.get());
    m_bounceAnimation.adoptNS([[WebFindIndicatorWindowAnimation alloc] _initWithFindIndicatorWindow:this
                                                                                  animationDuration:bounceAnimationDuration
                                                                          animationProgressCallback:&FindIndicatorWindow::bounceAnimationCallback
                                                                            animationDidEndCallback:&FindIndicatorWindow::bounceAnimationDidEnd]);
    [m_bounceAnimation.get() startAnimation];

    if (fadeOut)
        m_startFadeOutTimer.startOneShot(timeBeforeFadeStarts);
}

void FindIndicatorWindow::closeWindow()
{
    if (!m_findIndicatorWindow)
        return;

    m_startFadeOutTimer.stop();

    if (m_fadeOutAnimation) {
        [m_fadeOutAnimation.get() stopAnimation];
        m_fadeOutAnimation = nullptr;
    }

    if (m_bounceAnimation) {
        [m_bounceAnimation.get() stopAnimation];
        m_bounceAnimation = nullptr;
    }

    if (m_bounceAnimationContext)
        WKWindowBounceAnimationContextDestroy(m_bounceAnimationContext);
    
    [[m_findIndicatorWindow.get() parentWindow] removeChildWindow:m_findIndicatorWindow.get()];
    [m_findIndicatorWindow.get() close];
    m_findIndicatorWindow = nullptr;
}

void FindIndicatorWindow::startFadeOutTimerFired()
{
    ASSERT(!m_fadeOutAnimation);
    
    m_fadeOutAnimation.adoptNS([[WebFindIndicatorWindowAnimation alloc] _initWithFindIndicatorWindow:this
                                                                                   animationDuration:fadeOutAnimationDuration
                                                                           animationProgressCallback:&FindIndicatorWindow::fadeOutAnimationCallback
                                                                             animationDidEndCallback:&FindIndicatorWindow::fadeOutAnimationDidEnd]);
    [m_fadeOutAnimation.get() startAnimation];
}
                        
void FindIndicatorWindow::fadeOutAnimationCallback(double progress)
{
    ASSERT(m_fadeOutAnimation);

    [m_findIndicatorWindow.get() setAlphaValue:1.0 - progress];
}

void FindIndicatorWindow::fadeOutAnimationDidEnd()
{
    ASSERT(m_fadeOutAnimation);
    ASSERT(m_findIndicatorWindow);

    closeWindow();
}

void FindIndicatorWindow::bounceAnimationCallback(double progress)
{
    ASSERT(m_bounceAnimation);
    ASSERT(m_bounceAnimationContext);

    WKWindowBounceAnimationSetAnimationProgress(m_bounceAnimationContext, progress);
}

void FindIndicatorWindow::bounceAnimationDidEnd()
{
    ASSERT(m_bounceAnimation);
    ASSERT(m_bounceAnimationContext);
    ASSERT(m_findIndicatorWindow);

    WKWindowBounceAnimationContextDestroy(m_bounceAnimationContext);
    m_bounceAnimationContext = 0;
}

} // namespace WebKit
