/*
 * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "PageViewportController.h"

#include "PageViewportControllerClient.h"
#include "WebPageProxy.h"
#include <WebCore/FloatRect.h>
#include <WebCore/FloatSize.h>
#include <wtf/MathExtras.h>

using namespace WebCore;

namespace WebKit {

bool fuzzyCompare(float a, float b, float epsilon)
{
    return std::abs(a - b) < epsilon;
}

ViewportUpdateDeferrer::ViewportUpdateDeferrer(PageViewportController* PageViewportController, SuspendContentFlag suspendContentFlag)
    : m_controller(PageViewportController)
{
    m_controller->m_activeDeferrerCount++;

    // There is no need to suspend content for immediate updates
    // only during animations or longer gestures.
    if (suspendContentFlag == DeferUpdateAndSuspendContent)
        m_controller->suspendContent();
}

ViewportUpdateDeferrer::~ViewportUpdateDeferrer()
{
    if (--(m_controller->m_activeDeferrerCount))
        return;

    m_controller->resumeContent();

    // Make sure that tiles all around the viewport will be requested.
    m_controller->syncVisibleContents();
}

PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, PageViewportControllerClient* client)
    : m_webPageProxy(proxy)
    , m_client(client)
    , m_allowsUserScaling(false)
    , m_minimumScaleToFit(1)
    , m_activeDeferrerCount(0)
    , m_hasSuspendedContent(false)
    , m_hadUserInteraction(false)
    , m_effectiveScale(1)
{
    // Initializing Viewport Raw Attributes to avoid random negative scale factors
    // if there is a race condition between the first layout and setting the viewport attributes for the first time.
    m_rawAttributes.initialScale = 1;
    m_rawAttributes.minimumScale = 1;
    m_rawAttributes.maximumScale = 1;
    m_rawAttributes.userScalable = m_allowsUserScaling;

    ASSERT(m_client);
    m_client->setController(this);
}

float PageViewportController::innerBoundedViewportScale(float viewportScale) const
{
    return clampTo(viewportScale, toViewportScale(m_minimumScaleToFit), toViewportScale(m_rawAttributes.maximumScale));
}

float PageViewportController::outerBoundedViewportScale(float viewportScale) const
{
    if (m_allowsUserScaling) {
        // Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
        float hardMin = toViewportScale(std::max<float>(0.1, 0.5 * m_minimumScaleToFit));
        float hardMax = toViewportScale(std::min<float>(10, 2 * m_rawAttributes.maximumScale));
        return clampTo(viewportScale, hardMin, hardMax);
    }
    return innerBoundedViewportScale(viewportScale);
}

float PageViewportController::devicePixelRatio() const
{
    return m_webPageProxy->deviceScaleFactor();
}

FloatPoint PageViewportController::clampViewportToContents(const WebCore::FloatPoint& viewportPos, float viewportScale)
{
    const float horizontalRange = std::max(0.f, m_contentsSize.width() - m_viewportSize.width() / viewportScale);
    const float verticalRange = std::max(0.f, m_contentsSize.height() - m_viewportSize.height() / viewportScale);

    return FloatPoint(clampTo(viewportPos.x(), 0.f, horizontalRange), clampTo(viewportPos.y(), 0.f, verticalRange));
}

void PageViewportController::didCommitLoad()
{
    // Do not count the previous committed page contents as covered.
    m_lastFrameCoveredRect = FloatRect();

    // Reset the position to the top, page/history scroll requests may override this before we re-enable rendering.
    applyPositionAfterRenderingContents(FloatPoint());
}

void PageViewportController::didChangeContentsSize(const IntSize& newSize)
{
    m_contentsSize = newSize;
    updateMinimumScaleToFit();
}

void PageViewportController::didRenderFrame(const IntSize& contentsSize, const IntRect& coveredRect)
{
    // Only update the viewport's contents dimensions along with its render.
    m_client->didChangeContentsSize(contentsSize);

    m_lastFrameCoveredRect = coveredRect;

    // Apply any scale or scroll position we locked to be set on the viewport
    // only when there is something to display there. The scale goes first to
    // avoid offsetting our deferred position by scaling at the viewport center.
    // All position and scale changes resulting from a web process event should
    // go through here to be applied on the viewport to avoid showing incomplete
    // tiles to the user during a few milliseconds.
    ViewportUpdateDeferrer guard(this);
    if (m_effectiveScaleIsLocked) {
        m_client->setContentsScale(m_effectiveScale, false);
        m_effectiveScaleIsLocked = false;
    }
    if (m_viewportPosIsLocked) {
        FloatPoint clampedPos = clampViewportToContents(m_viewportPos, m_effectiveScale);
        // There might be rendered frames not covering our requested position yet, wait for it.
        if (FloatRect(clampedPos, viewportSizeInContentsCoordinates()).intersects(coveredRect)) {
            m_client->setViewportPosition(clampedPos);
            m_viewportPosIsLocked = false;
        }
    }
}

void PageViewportController::pageTransitionViewportReady()
{
    if (!m_rawAttributes.layoutSize.isEmpty()) {
        m_hadUserInteraction = false;
        applyScaleAfterRenderingContents(innerBoundedViewportScale(toViewportScale(m_rawAttributes.initialScale)));
    }

    // At this point we should already have received the first viewport arguments and the requested scroll
    // position for the newly loaded page and sent our reactions to the web process. It's now safe to tell
    // the web process to start rendering the new page contents and possibly re-use the current tiles.
    // This assumes that all messages have been handled in order and that nothing has been pushed back on the event loop.
    m_webPageProxy->commitPageTransitionViewport();
}

void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition)
{
    // Ignore the request if suspended. Can only happen due to delay in event delivery.
    if (m_activeDeferrerCount)
        return;

    FloatRect endVisibleContentRect(clampViewportToContents(cssPosition, m_effectiveScale), viewportSizeInContentsCoordinates());
    if (m_lastFrameCoveredRect.intersects(endVisibleContentRect))
        m_client->setViewportPosition(endVisibleContentRect.location());
    else
        // Keep the unclamped position in case the contents size is changed later on.
        applyPositionAfterRenderingContents(cssPosition);
}

void PageViewportController::didChangeViewportSize(const FloatSize& newSize)
{
    if (newSize.isEmpty())
        return;

    m_viewportSize = newSize;

    // Let the WebProcess know about the new viewport size, so that
    // it can resize the content accordingly.
    m_webPageProxy->setViewportSize(roundedIntSize(newSize));

    syncVisibleContents();
}

void PageViewportController::didChangeContentsVisibility(const FloatPoint& viewportPos, float viewportScale, const FloatPoint& trajectoryVector)
{
    if (!m_viewportPosIsLocked)
        m_viewportPos = viewportPos;
    if (!m_effectiveScaleIsLocked)
        m_effectiveScale = viewportScale;

    syncVisibleContents(trajectoryVector);
}

void PageViewportController::syncVisibleContents(const FloatPoint& trajectoryVector)
{
    DrawingAreaProxy* const drawingArea = m_webPageProxy->drawingArea();
    if (!drawingArea || m_viewportSize.isEmpty() || m_contentsSize.isEmpty())
        return;

    FloatRect visibleContentsRect(clampViewportToContents(m_viewportPos, m_effectiveScale), viewportSizeInContentsCoordinates());
    visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize));
    drawingArea->setVisibleContentsRect(visibleContentsRect, m_effectiveScale, trajectoryVector);

    m_client->didChangeVisibleContents();
}

void PageViewportController::didChangeViewportAttributes(const WebCore::ViewportAttributes& newAttributes)
{
    if (newAttributes.layoutSize.isEmpty())
        return;

    m_rawAttributes = newAttributes;
    WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes);

    m_allowsUserScaling = !!m_rawAttributes.userScalable;
    updateMinimumScaleToFit();

    m_client->didChangeViewportAttributes();
}

WebCore::FloatSize PageViewportController::viewportSizeInContentsCoordinates() const
{
    return WebCore::FloatSize(m_viewportSize.width() / m_effectiveScale, m_viewportSize.height() / m_effectiveScale);
}

void PageViewportController::suspendContent()
{
    if (m_hasSuspendedContent)
        return;

    m_hasSuspendedContent = true;
    m_webPageProxy->suspendActiveDOMObjectsAndAnimations();
}

void PageViewportController::resumeContent()
{
    m_client->didResumeContent();

    if (!m_hasSuspendedContent)
        return;

    m_hasSuspendedContent = false;
    m_webPageProxy->resumeActiveDOMObjectsAndAnimations();
}

void PageViewportController::applyScaleAfterRenderingContents(float scale)
{
    m_effectiveScale = scale;
    m_effectiveScaleIsLocked = true;
    syncVisibleContents();
}

void PageViewportController::applyPositionAfterRenderingContents(const FloatPoint& pos)
{
    m_viewportPos = pos;
    m_viewportPosIsLocked = true;
    syncVisibleContents();
}

void PageViewportController::updateMinimumScaleToFit()
{
    if (m_viewportSize.isEmpty())
        return;

    float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize));

    if (!fuzzyCompare(minimumScale, m_minimumScaleToFit, 0.001)) {
        m_minimumScaleToFit = minimumScale;

        if (!m_hadUserInteraction && !hasSuspendedContent())
            applyScaleAfterRenderingContents(toViewportScale(minimumScale));

        m_client->didChangeViewportAttributes();
    }
}

} // namespace WebKit
