/*
 * CSS Media Query
 *
 * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * Copyright (C) 2013 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 THE AUTHOR ``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 COMPUTER, INC. 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 "config.h"
#include "MediaQueryExp.h"

#include "CSSAspectRatioValue.h"
#include "CSSParser.h"
#include "CSSPrimitiveValue.h"
#include "CSSValueList.h"
#include <wtf/text/StringBuilder.h>

namespace WebCore {

static inline bool featureWithCSSValueID(const AtomicString& mediaFeature, const CSSParserValue* value)
{
    if (!value->id)
        return false;

    return mediaFeature == MediaFeatureNames::orientationMediaFeature
#if ENABLE(VIEW_MODE_CSS_MEDIA)
        || mediaFeature == MediaFeatureNames::view_modeMediaFeature
#endif // ENABLE(VIEW_MODE_CSS_MEDIA)
        || mediaFeature == MediaFeatureNames::pointerMediaFeature;
}

static inline bool featureWithValidPositiveLenghtOrNumber(const AtomicString& mediaFeature, const CSSParserValue* value)
{
    if (!(((value->unit >= CSSPrimitiveValue::CSS_EMS && value->unit <= CSSPrimitiveValue::CSS_PC) || value->unit == CSSPrimitiveValue::CSS_REMS) || value->unit == CSSPrimitiveValue::CSS_NUMBER) || value->fValue < 0)
        return false;

    return mediaFeature == MediaFeatureNames::heightMediaFeature
        || mediaFeature == MediaFeatureNames::max_heightMediaFeature
        || mediaFeature == MediaFeatureNames::min_heightMediaFeature
        || mediaFeature == MediaFeatureNames::widthMediaFeature
        || mediaFeature == MediaFeatureNames::max_widthMediaFeature
        || mediaFeature == MediaFeatureNames::min_widthMediaFeature
        || mediaFeature == MediaFeatureNames::device_heightMediaFeature
        || mediaFeature == MediaFeatureNames::max_device_heightMediaFeature
        || mediaFeature == MediaFeatureNames::min_device_heightMediaFeature
        || mediaFeature == MediaFeatureNames::device_widthMediaFeature
        || mediaFeature == MediaFeatureNames::max_device_widthMediaFeature
        || mediaFeature == MediaFeatureNames::min_device_widthMediaFeature;
}

static inline bool featureWithValidDensity(const AtomicString& mediaFeature, const CSSParserValue* value)
{
    if ((value->unit != CSSPrimitiveValue::CSS_DPPX && value->unit != CSSPrimitiveValue::CSS_DPI && value->unit != CSSPrimitiveValue::CSS_DPCM) || value->fValue <= 0)
        return false;

    return mediaFeature == MediaFeatureNames::resolutionMediaFeature
        || mediaFeature == MediaFeatureNames::max_resolutionMediaFeature
        || mediaFeature == MediaFeatureNames::min_resolutionMediaFeature;
}

static inline bool featureWithPositiveInteger(const AtomicString& mediaFeature, const CSSParserValue* value)
{
    if (!value->isInt || value->fValue < 0)
        return false;

    return mediaFeature == MediaFeatureNames::colorMediaFeature
        || mediaFeature == MediaFeatureNames::max_colorMediaFeature
        || mediaFeature == MediaFeatureNames::min_colorMediaFeature
        || mediaFeature == MediaFeatureNames::color_indexMediaFeature
        || mediaFeature == MediaFeatureNames::max_color_indexMediaFeature
        || mediaFeature == MediaFeatureNames::min_color_indexMediaFeature
        || mediaFeature == MediaFeatureNames::min_monochromeMediaFeature
        || mediaFeature == MediaFeatureNames::max_monochromeMediaFeature;
}

static inline bool featureWithPositiveNumber(const AtomicString& mediaFeature, const CSSParserValue* value)
{
    if (value->unit != CSSPrimitiveValue::CSS_NUMBER || value->fValue < 0)
        return false;

    return mediaFeature == MediaFeatureNames::transform_2dMediaFeature
        || mediaFeature == MediaFeatureNames::transform_3dMediaFeature
        || mediaFeature == MediaFeatureNames::transitionMediaFeature
        || mediaFeature == MediaFeatureNames::animationMediaFeature
        || mediaFeature == MediaFeatureNames::device_pixel_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::max_device_pixel_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::min_device_pixel_ratioMediaFeature;
}

static inline bool featureWithZeroOrOne(const AtomicString& mediaFeature, const CSSParserValue* value)
{
    if (!value->isInt || !(value->fValue == 1 || !value->fValue))
        return false;

    return mediaFeature == MediaFeatureNames::gridMediaFeature
        || mediaFeature == MediaFeatureNames::hoverMediaFeature;
}

static inline bool featureWithAspectRatio(const AtomicString& mediaFeature)
{
    return mediaFeature == MediaFeatureNames::aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::device_aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::min_aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::max_aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::min_device_aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::max_device_aspect_ratioMediaFeature;
}

static inline bool featureWithoutValue(const AtomicString& mediaFeature)
{
    // Media features that are prefixed by min/max cannot be used without a value.
    return mediaFeature == MediaFeatureNames::monochromeMediaFeature
        || mediaFeature == MediaFeatureNames::colorMediaFeature
        || mediaFeature == MediaFeatureNames::color_indexMediaFeature
        || mediaFeature == MediaFeatureNames::gridMediaFeature
        || mediaFeature == MediaFeatureNames::heightMediaFeature
        || mediaFeature == MediaFeatureNames::widthMediaFeature
        || mediaFeature == MediaFeatureNames::device_heightMediaFeature
        || mediaFeature == MediaFeatureNames::device_widthMediaFeature
        || mediaFeature == MediaFeatureNames::orientationMediaFeature
        || mediaFeature == MediaFeatureNames::aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::device_aspect_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::hoverMediaFeature
        || mediaFeature == MediaFeatureNames::transform_2dMediaFeature
        || mediaFeature == MediaFeatureNames::transform_3dMediaFeature
        || mediaFeature == MediaFeatureNames::transitionMediaFeature
        || mediaFeature == MediaFeatureNames::animationMediaFeature
#if ENABLE(VIEW_MODE_CSS_MEDIA)
        || mediaFeature == MediaFeatureNames::view_modeMediaFeature
#endif // ENABLE(VIEW_MODE_CSS_MEDIA)
        || mediaFeature == MediaFeatureNames::pointerMediaFeature
        || mediaFeature == MediaFeatureNames::device_pixel_ratioMediaFeature
        || mediaFeature == MediaFeatureNames::resolutionMediaFeature;
}

inline MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList)
    : m_mediaFeature(mediaFeature)
    , m_value(0)
    , m_isValid(false)
{
    // Initialize media query expression that must have 1 or more values.
    if (valueList) {
        if (valueList->size() == 1) {
            CSSParserValue* value = valueList->current();

            // Media features that use CSSValueIDs.
            if (featureWithCSSValueID(mediaFeature, value))
                m_value = CSSPrimitiveValue::createIdentifier(value->id);

            // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm.
            else if (featureWithValidDensity(mediaFeature, value))
                m_value = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);

            // Media features that must have non-negative <lenght> or number value.
            else if (featureWithValidPositiveLenghtOrNumber(mediaFeature, value))
                m_value = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);

            // Media features that must have non-negative integer value.
            else if (featureWithPositiveInteger(mediaFeature, value))
                m_value = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);

            // Media features that must have non-negative number value.
            else if (featureWithPositiveNumber(mediaFeature, value))
                m_value = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);

            // Media features that must have (0|1) value.
            else if (featureWithZeroOrOne(mediaFeature, value))
                m_value = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);

            m_isValid = m_value;
        } else if (valueList->size() == 3 && featureWithAspectRatio(mediaFeature)) {
            // Create list of values.
            // Currently accepts only <integer>/<integer>.
            // Applicable to device-aspect-ratio and aspec-ratio.
            bool isValid = true;
            float numeratorValue = 0;
            float denominatorValue = 0;

            // The aspect-ratio must be <integer> (whitespace)? / (whitespace)? <integer>.
            for (unsigned i = 0; i < 3; ++i, valueList->next()) {
                const CSSParserValue* value = valueList->current();
                if (i != 1 && value->unit == CSSPrimitiveValue::CSS_NUMBER && value->fValue > 0 && value->isInt) {
                    if (!i)
                        numeratorValue = value->fValue;
                    else
                        denominatorValue = value->fValue;
                } else if (i == 1 && value->unit == CSSParserValue::Operator && value->iValue == '/')
                    continue;
                else {
                    isValid = false;
                    break;
                }
            }

            if (isValid)
                m_value = CSSAspectRatioValue::create(numeratorValue, denominatorValue);

            m_isValid = m_value;
        }
    } else if (featureWithoutValue(mediaFeature))
        m_isValid = true;
}

PassOwnPtr<MediaQueryExp> MediaQueryExp::create(const AtomicString& mediaFeature, CSSParserValueList* values)
{
    return adoptPtr(new MediaQueryExp(mediaFeature, values));
}

MediaQueryExp::~MediaQueryExp()
{
}

String MediaQueryExp::serialize() const
{
    if (!m_serializationCache.isNull())
        return m_serializationCache;

    StringBuilder result;
    result.append("(");
    result.append(m_mediaFeature.lower());
    if (m_value) {
        result.append(": ");
        result.append(m_value->cssText());
    }
    result.append(")");

    const_cast<MediaQueryExp*>(this)->m_serializationCache = result.toString();
    return m_serializationCache;
}

} // namespace
