/*
 * 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.
 */

#include "config.h"
#include "PageOverlay.h"

#include "WebPage.h"
#include "WebProcess.h"
#include <WebCore/Frame.h>
#include <WebCore/FrameView.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/Page.h>
#include <WebCore/ScrollbarTheme.h>

using namespace WebCore;

namespace WebKit {

static const double fadeAnimationDuration = 0.2;
static const double fadeAnimationFrameRate = 30;

PassRefPtr<PageOverlay> PageOverlay::create(Client* client)
{
    return adoptRef(new PageOverlay(client));
}

PageOverlay::PageOverlay(Client* client)
    : m_client(client)
    , m_webPage(0)
    , m_fadeAnimationTimer(WebProcess::shared().runLoop(), this, &PageOverlay::fadeAnimationTimerFired)
    , m_fadeAnimationStartTime(0.0)
    , m_fadeAnimationDuration(fadeAnimationDuration)
    , m_fadeAnimationType(NoAnimation)
    , m_fractionFadedIn(1.0)
{
}

PageOverlay::~PageOverlay()
{
}

IntRect PageOverlay::bounds() const
{
    FrameView* frameView = m_webPage->corePage()->mainFrame()->view();

    int width = frameView->width();
    int height = frameView->height();

    if (!ScrollbarTheme::nativeTheme()->usesOverlayScrollbars()) {
        if (frameView->verticalScrollbar())
            width -= frameView->verticalScrollbar()->width();
        if (frameView->horizontalScrollbar())
            height -= frameView->horizontalScrollbar()->height();
    }    
    return IntRect(0, 0, width, height);
}

void PageOverlay::setPage(WebPage* webPage)
{
    m_client->willMoveToWebPage(this, webPage);
    m_webPage = webPage;
    m_client->didMoveToWebPage(this, webPage);

    m_fadeAnimationTimer.stop();
}

void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect)
{
    if (m_webPage)
        m_webPage->drawingArea()->setPageOverlayNeedsDisplay(dirtyRect);
}

void PageOverlay::setNeedsDisplay()
{
    setNeedsDisplay(bounds());
}

void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect)
{
    // If the dirty rect is outside the bounds, ignore it.
    IntRect paintRect = intersection(dirtyRect, bounds());
    if (paintRect.isEmpty())
        return;

    graphicsContext.save();
    graphicsContext.beginTransparencyLayer(1);
    graphicsContext.setCompositeOperation(CompositeCopy);

    m_client->drawRect(this, graphicsContext, paintRect);

    graphicsContext.endTransparencyLayer();
    graphicsContext.restore();
}
    
bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent)
{
    // Ignore events outside the bounds.
    if (!bounds().contains(mouseEvent.position()))
        return false;

    return m_client->mouseEvent(this, mouseEvent);
}

void PageOverlay::startFadeInAnimation()
{
    m_fractionFadedIn = 0.0;
    m_fadeAnimationType = FadeInAnimation;

    startFadeAnimation();
}

void PageOverlay::startFadeOutAnimation()
{
    m_fractionFadedIn = 1.0;
    m_fadeAnimationType = FadeOutAnimation;

    startFadeAnimation();
}

void PageOverlay::startFadeAnimation()
{
    m_fadeAnimationStartTime = currentTime();
    
    // Start the timer
    m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate);
}

void PageOverlay::fadeAnimationTimerFired()
{
    float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration;

    if (animationProgress >= 1.0)
        animationProgress = 1.0;

    double sine = sin(piOverTwoFloat * animationProgress);
    float fadeAnimationValue = sine * sine;

    m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue;
    setNeedsDisplay();

    if (animationProgress == 1.0) {
        m_fadeAnimationTimer.stop();

        bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation;
        m_fadeAnimationType = NoAnimation;

        if (wasFadingOut) {
            // If this was a fade out, go ahead and uninstall the page overlay.
            m_webPage->uninstallPageOverlay(this, false);
        }
    }
}

} // namespace WebKit
