/*
 * Copyright (C) 2012 Intel Corporation. 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 THE COPYRIGHT HOLDER “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 HOLDER 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 "ViewportStyleResolver.h"

#if ENABLE(CSS_DEVICE_ADAPTATION)

#include "CSSValueKeywords.h"
#include "Document.h"
#include "NodeRenderStyle.h"
#include "StyleProperties.h"
#include "StyleRule.h"
#include "ViewportArguments.h"

namespace WebCore {

ViewportStyleResolver::ViewportStyleResolver(Document* document)
    : m_document(document ? makeWeakPtr(*document) : nullptr)
{
    ASSERT(m_document);
}

ViewportStyleResolver::~ViewportStyleResolver() = default;

void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule)
{
    StyleProperties& propertySet = viewportRule->mutableProperties();

    unsigned propertyCount = propertySet.propertyCount();
    if (!propertyCount)
        return;

    if (!m_propertySet) {
        m_propertySet = propertySet.mutableCopy();
        return;
    }

    m_propertySet->mergeAndOverrideOnConflict(propertySet);
}

void ViewportStyleResolver::clearDocument()
{
    m_document = nullptr;
}

void ViewportStyleResolver::resolve()
{
    if (!m_document || !m_propertySet)
        return;

    ViewportArguments arguments(ViewportArguments::CSSDeviceAdaptation);

    arguments.userZoom = getViewportArgumentValue(CSSPropertyUserZoom);
    arguments.zoom = getViewportArgumentValue(CSSPropertyZoom);
    arguments.minZoom = getViewportArgumentValue(CSSPropertyMinZoom);
    arguments.maxZoom = getViewportArgumentValue(CSSPropertyMaxZoom);
    arguments.minWidth = getViewportArgumentValue(CSSPropertyMinWidth);
    arguments.maxWidth = getViewportArgumentValue(CSSPropertyMaxWidth);
    arguments.minHeight = getViewportArgumentValue(CSSPropertyMinHeight);
    arguments.maxHeight = getViewportArgumentValue(CSSPropertyMaxHeight);
    arguments.orientation = getViewportArgumentValue(CSSPropertyOrientation);

    m_document->setViewportArguments(arguments);
    m_document->updateViewportArguments();

    m_propertySet = nullptr;
}

float ViewportStyleResolver::getViewportArgumentValue(CSSPropertyID id) const
{
    float defaultValue = ViewportArguments::ValueAuto;

    // UserZoom default value is CSSValueZoom, which maps to true, meaning that
    // yes, it is user scalable. When the value is set to CSSValueFixed, we
    // return false.
    if (id == CSSPropertyUserZoom)
        defaultValue = 1;

    RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
    if (!is<CSSPrimitiveValue>(value))
        return defaultValue;

    CSSPrimitiveValue& primitiveValue = downcast<CSSPrimitiveValue>(*value);

    if (primitiveValue.isNumber() || primitiveValue.isPx())
        return primitiveValue.floatValue();

    if (primitiveValue.isFontRelativeLength())
        return primitiveValue.floatValue() * m_document->documentElement()->renderStyle()->fontDescription().computedSize();

    if (primitiveValue.isPercentage()) {
        float percentValue = primitiveValue.floatValue() / 100.0f;
        switch (id) {
        case CSSPropertyMaxHeight:
        case CSSPropertyMinHeight:
            ASSERT(m_document->initialViewportSize().height() > 0);
            return percentValue * m_document->initialViewportSize().height();
        case CSSPropertyMaxWidth:
        case CSSPropertyMinWidth:
            ASSERT(m_document->initialViewportSize().width() > 0);
            return percentValue * m_document->initialViewportSize().width();
        case CSSPropertyMaxZoom:
        case CSSPropertyMinZoom:
        case CSSPropertyZoom:
            return percentValue;
        default:
            ASSERT_NOT_REACHED();
            break;
        }
    }

    switch (primitiveValue.valueID()) {
    case CSSValueAuto:
        return defaultValue;
    case CSSValueDeviceHeight:
        return ViewportArguments::ValueDeviceHeight;
    case CSSValueDeviceWidth:
        return ViewportArguments::ValueDeviceWidth;
    case CSSValueLandscape:
        return ViewportArguments::ValueLandscape;
    case CSSValuePortrait:
        return ViewportArguments::ValuePortrait;
    case CSSValueZoom:
        return defaultValue;
    case CSSValueFixed:
        return 0;
    default:
        return defaultValue;
    }
}

} // namespace WebCore

#endif // ENABLE(CSS_DEVICE_ADAPTATION)
