/*
 * Copyright (C) 2013 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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 "core/frame/PageScaleConstraintsSet.h"

#include "platform/Length.h"
#include "wtf/Assertions.h"

namespace blink {

PageScaleConstraintsSet::PageScaleConstraintsSet()
    : m_defaultConstraints(-1, 1, 1)
    , m_finalConstraints(computeConstraintsStack())
    , m_lastContentsWidth(0)
    , m_needsReset(false)
    , m_constraintsDirty(false)
{
}

void PageScaleConstraintsSet::setDefaultConstraints(const PageScaleConstraints& defaultConstraints)
{
    m_defaultConstraints = defaultConstraints;
    m_constraintsDirty = true;
}

const PageScaleConstraints& PageScaleConstraintsSet::defaultConstraints() const
{
    return m_defaultConstraints;
}

void PageScaleConstraintsSet::updatePageDefinedConstraints(const ViewportDescription& description, Length legacyFallbackWidth)
{
    m_pageDefinedConstraints = description.resolve(FloatSize(m_icbSize), legacyFallbackWidth);

    m_constraintsDirty = true;
}

void PageScaleConstraintsSet::clearPageDefinedConstraints()
{
    m_pageDefinedConstraints = PageScaleConstraints();
    m_constraintsDirty = true;
}

void PageScaleConstraintsSet::setUserAgentConstraints(const PageScaleConstraints& userAgentConstraints)
{
    m_userAgentConstraints = userAgentConstraints;
    m_constraintsDirty = true;
}

void PageScaleConstraintsSet::setFullscreenConstraints(const PageScaleConstraints& fullscreenConstraints)
{
    m_fullscreenConstraints = fullscreenConstraints;
    m_constraintsDirty = true;
}

PageScaleConstraints PageScaleConstraintsSet::computeConstraintsStack() const
{
    PageScaleConstraints constraints = defaultConstraints();
    constraints.overrideWith(m_pageDefinedConstraints);
    constraints.overrideWith(m_userAgentConstraints);
    constraints.overrideWith(m_fullscreenConstraints);
    return constraints;
}

void PageScaleConstraintsSet::computeFinalConstraints()
{
    m_finalConstraints = computeConstraintsStack();

    m_constraintsDirty = false;
}

void PageScaleConstraintsSet::adjustFinalConstraintsToContentsSize(IntSize contentsSize, int nonOverlayScrollbarWidth, bool shrinksViewportContentToFit)
{
    if (shrinksViewportContentToFit)
        m_finalConstraints.fitToContentsWidth(contentsSize.width(), m_icbSize.width() - nonOverlayScrollbarWidth);

    m_finalConstraints.resolveAutoInitialScale();
}

void PageScaleConstraintsSet::setNeedsReset(bool needsReset)
{
    m_needsReset = needsReset;
    if (needsReset)
        m_constraintsDirty = true;
}

void PageScaleConstraintsSet::didChangeContentsSize(IntSize contentsSize, float pageScaleFactor)
{
    // If a large fixed-width element expanded the size of the document late in
    // loading and our initial scale is not set (or set to be less than the last
    // minimum scale), reset the page scale factor to the new initial scale.
    if (contentsSize.width() > m_lastContentsWidth
        && pageScaleFactor == finalConstraints().minimumScale
        && computeConstraintsStack().initialScale < finalConstraints().minimumScale)
        setNeedsReset(true);

    m_constraintsDirty = true;
    m_lastContentsWidth = contentsSize.width();
}

static float computeDeprecatedTargetDensityDPIFactor(const ViewportDescription& description, float deviceScaleFactor)
{
    if (description.deprecatedTargetDensityDPI == ViewportDescription::ValueDeviceDPI)
        return 1.0f / deviceScaleFactor;

    float targetDPI = -1.0f;
    if (description.deprecatedTargetDensityDPI == ViewportDescription::ValueLowDPI)
        targetDPI = 120.0f;
    else if (description.deprecatedTargetDensityDPI == ViewportDescription::ValueMediumDPI)
        targetDPI = 160.0f;
    else if (description.deprecatedTargetDensityDPI == ViewportDescription::ValueHighDPI)
        targetDPI = 240.0f;
    else if (description.deprecatedTargetDensityDPI != ViewportDescription::ValueAuto)
        targetDPI = description.deprecatedTargetDensityDPI;
    return targetDPI > 0 ? 160.0f / targetDPI : 1.0f;
}

static float getLayoutWidthForNonWideViewport(const FloatSize& deviceSize, float initialScale)
{
    return initialScale == -1 ? deviceSize.width() : deviceSize.width() / initialScale;
}

static float computeHeightByAspectRatio(float width, const FloatSize& deviceSize)
{
    return width * (deviceSize.height() / deviceSize.width());
}

void PageScaleConstraintsSet::didChangeInitialContainingBlockSize(const IntSize& size)
{
    if (m_icbSize == size)
        return;

    m_icbSize = size;
    m_constraintsDirty = true;
}

IntSize PageScaleConstraintsSet::layoutSize() const
{
    return flooredIntSize(computeConstraintsStack().layoutSize);
}

void PageScaleConstraintsSet::adjustForAndroidWebViewQuirks(const ViewportDescription& description, int layoutFallbackWidth, float deviceScaleFactor, bool supportTargetDensityDPI, bool wideViewportQuirkEnabled, bool useWideViewport, bool loadWithOverviewMode, bool nonUserScalableQuirkEnabled)
{
    if (!supportTargetDensityDPI && !wideViewportQuirkEnabled && loadWithOverviewMode && !nonUserScalableQuirkEnabled)
        return;

    const float oldInitialScale = m_pageDefinedConstraints.initialScale;
    if (!loadWithOverviewMode) {
        bool resetInitialScale = false;
        if (description.zoom == -1) {
            if (description.maxWidth.isAuto() || description.maxWidth.type() == ExtendToZoom)
                resetInitialScale = true;
            if (useWideViewport || description.maxWidth.type() == DeviceWidth)
                resetInitialScale = true;
        }
        if (resetInitialScale)
            m_pageDefinedConstraints.initialScale = 1.0f;
    }

    float adjustedLayoutSizeWidth = m_pageDefinedConstraints.layoutSize.width();
    float adjustedLayoutSizeHeight = m_pageDefinedConstraints.layoutSize.height();
    float targetDensityDPIFactor = 1.0f;

    if (supportTargetDensityDPI) {
        targetDensityDPIFactor = computeDeprecatedTargetDensityDPIFactor(description, deviceScaleFactor);
        if (m_pageDefinedConstraints.initialScale != -1)
            m_pageDefinedConstraints.initialScale *= targetDensityDPIFactor;
        if (m_pageDefinedConstraints.minimumScale != -1)
            m_pageDefinedConstraints.minimumScale *= targetDensityDPIFactor;
        if (m_pageDefinedConstraints.maximumScale != -1)
            m_pageDefinedConstraints.maximumScale *= targetDensityDPIFactor;
        if (wideViewportQuirkEnabled && (!useWideViewport || description.maxWidth.type() == DeviceWidth)) {
            adjustedLayoutSizeWidth /= targetDensityDPIFactor;
            adjustedLayoutSizeHeight /= targetDensityDPIFactor;
        }
    }

    if (wideViewportQuirkEnabled) {
        if (useWideViewport && (description.maxWidth.isAuto() || description.maxWidth.type() == ExtendToZoom) && description.zoom != 1.0f) {
            if (layoutFallbackWidth)
                adjustedLayoutSizeWidth = layoutFallbackWidth;
            adjustedLayoutSizeHeight = computeHeightByAspectRatio(adjustedLayoutSizeWidth, FloatSize(m_icbSize));
        } else if (!useWideViewport) {
            const float nonWideScale = description.zoom < 1 && description.maxWidth.type() != DeviceWidth && description.maxWidth.type() != DeviceHeight ? -1 : oldInitialScale;
            adjustedLayoutSizeWidth = getLayoutWidthForNonWideViewport(FloatSize(m_icbSize), nonWideScale) / targetDensityDPIFactor;
            float newInitialScale = targetDensityDPIFactor;
            if (m_userAgentConstraints.initialScale != -1 && (description.maxWidth.type() == DeviceWidth || ((description.maxWidth.isAuto() || description.maxWidth.type() == ExtendToZoom) && description.zoom == -1))) {
                adjustedLayoutSizeWidth /= m_userAgentConstraints.initialScale;
                newInitialScale = m_userAgentConstraints.initialScale;
            }
            adjustedLayoutSizeHeight = computeHeightByAspectRatio(adjustedLayoutSizeWidth, FloatSize(m_icbSize));
            if (description.zoom < 1) {
                m_pageDefinedConstraints.initialScale = newInitialScale;
                if (m_pageDefinedConstraints.minimumScale != -1)
                    m_pageDefinedConstraints.minimumScale = std::min<float>(m_pageDefinedConstraints.minimumScale, m_pageDefinedConstraints.initialScale);
                if (m_pageDefinedConstraints.maximumScale != -1)
                    m_pageDefinedConstraints.maximumScale = std::max<float>(m_pageDefinedConstraints.maximumScale, m_pageDefinedConstraints.initialScale);
            }
        }
    }

    if (nonUserScalableQuirkEnabled && !description.userZoom) {
        m_pageDefinedConstraints.initialScale = targetDensityDPIFactor;
        m_pageDefinedConstraints.minimumScale = m_pageDefinedConstraints.initialScale;
        m_pageDefinedConstraints.maximumScale = m_pageDefinedConstraints.initialScale;
        if (description.maxWidth.isAuto() || description.maxWidth.type() == ExtendToZoom || description.maxWidth.type() == DeviceWidth) {
            adjustedLayoutSizeWidth = m_icbSize.width() / targetDensityDPIFactor;
            adjustedLayoutSizeHeight = computeHeightByAspectRatio(adjustedLayoutSizeWidth, FloatSize(m_icbSize));
        }
    }

    m_pageDefinedConstraints.layoutSize.setWidth(adjustedLayoutSizeWidth);
    m_pageDefinedConstraints.layoutSize.setHeight(adjustedLayoutSizeHeight);
}

} // namespace blink
