/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2016 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.
 * 3. 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.
 */

#pragma once

#if ENABLE(MEDIA_STREAM)

#include "RealtimeMediaSourceSupportedConstraints.h"
#include <cstdlib>
#include <wtf/Function.h>
#include <wtf/Vector.h>

namespace WebCore {
    
class MediaConstraint {
public:
    enum class DataType { None, Integer, Double, Boolean, String };

    bool isInt() const { return m_dataType == DataType::Integer; }
    bool isDouble() const { return m_dataType == DataType::Double; }
    bool isBoolean() const { return m_dataType == DataType::Boolean; }
    bool isString() const { return m_dataType == DataType::String; }

    DataType dataType() const { return m_dataType; }
    MediaConstraintType constraintType() const { return m_constraintType; }
    const String& name() const { return m_name; }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        encoder.encodeEnum(m_constraintType);
        encoder << m_name;
        encoder.encodeEnum(m_dataType);
    }

    template <class Decoder> static bool decode(Decoder& decoder, MediaConstraint& constraint)
    {
        if (!decoder.decodeEnum(constraint.m_constraintType))
            return false;

        if (!decoder.decode(constraint.m_name))
            return false;

        if (!decoder.decodeEnum(constraint.m_dataType))
            return false;

        return true;
    }

protected:
    MediaConstraint(const String& name, MediaConstraintType constraintType, DataType dataType)
        : m_name(name)
        , m_constraintType(constraintType)
        , m_dataType(dataType)
    {
    }

    MediaConstraint() = default;
    ~MediaConstraint() = default;

private:
    String m_name;
    MediaConstraintType m_constraintType { MediaConstraintType::Unknown };
    DataType m_dataType { DataType::None };
};

template<class ValueType>
class NumericConstraint : public MediaConstraint {
public:
    void setMin(ValueType value) { m_min = value; }
    void setMax(ValueType value) { m_max = value; }
    void setExact(ValueType value) { m_exact = value; }
    void setIdeal(ValueType value) { m_ideal = value; }

    bool getMin(ValueType& min) const
    {
        if (!m_min)
            return false;

        min = m_min.value();
        return true;
    }

    bool getMax(ValueType& max) const
    {
        if (!m_max)
            return false;

        max = m_max.value();
        return true;
    }

    bool getExact(ValueType& exact) const
    {
        if (!m_exact)
            return false;

        exact = m_exact.value();
        return true;
    }

    bool getIdeal(ValueType& ideal) const
    {
        if (!m_ideal)
            return false;

        ideal = m_ideal.value();
        return true;
    }

    bool nearlyEqual(double a, double b) const
    {
        // Don't require strict equality when comparing constraints, or many floating point constraint values,
        // e.g. "aspectRatio: 1.333", will never match.
        const double epsilon = 0.00001;
        return std::abs(a - b) <= epsilon;
    }

    double fitnessDistance(ValueType rangeMin, ValueType rangeMax) const
    {
        // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
        // 1. If the constraint is not supported by the browser, the fitness distance is 0.
        if (isEmpty())
            return 0;

        // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
        //    dictionary's value for the constraint does not satisfy the constraint, the
        //    fitness distance is positive infinity.
        bool valid = validForRange(rangeMin, rangeMax);
        if (m_exact) {
            if (valid && m_min && m_exact.value() < m_min.value())
                valid = false;
            if (valid && m_max && m_exact.value() > m_max.value())
                valid = false;
            if (!valid)
                return std::numeric_limits<double>::infinity();
        }

        if (m_min) {
            if (valid && m_max && m_min.value() > m_max.value())
                valid = false;
            if (!valid)
                return std::numeric_limits<double>::infinity();
        }

        if (m_max) {
            if (valid && m_min && m_max.value() < m_min.value())
                valid = false;
            if (!valid)
                return std::numeric_limits<double>::infinity();
        }

        // 3. If no ideal value is specified, the fitness distance is 0.
        if (!m_ideal)
            return 0;

        // 4. For all positive numeric non-required constraints (such as height, width, frameRate,
        //    aspectRatio, sampleRate and sampleSize), the fitness distance is the result of the formula
        //
        //         (actual == ideal) ? 0 : |actual - ideal| / max(|actual|,|ideal|)
        ValueType ideal = m_ideal.value();
        if (ideal >= rangeMin && ideal <= rangeMax)
            return 0;

        ideal = ideal > std::max(rangeMin, rangeMax) ? rangeMax : rangeMin;
        return static_cast<double>(std::abs(ideal - m_ideal.value())) / std::max(std::abs(ideal), std::abs(m_ideal.value()));
    }

    bool validForRange(ValueType rangeMin, ValueType rangeMax) const
    {
        if (isEmpty())
            return false;

        if (m_exact) {
            const ValueType exact = m_exact.value();
            if (exact < rangeMin && !nearlyEqual(exact, rangeMin))
                return false;
            if (exact > rangeMax && !nearlyEqual(exact, rangeMax))
                return false;
        }

        if (m_min) {
            const ValueType constraintMin = m_min.value();
            if (constraintMin > rangeMax && !nearlyEqual(constraintMin, rangeMax))
                return false;
        }

        if (m_max) {
            const ValueType constraintMax = m_max.value();
            if (constraintMax < rangeMin && !nearlyEqual(constraintMax, rangeMin))
                return false;
        }

        return true;
    }

    ValueType find(const WTF::Function<bool(ValueType)>& function) const
    {
        if (m_min && function(m_min.value()))
            return m_min.value();

        if (m_max && function(m_max.value()))
            return m_max.value();

        if (m_exact && function(m_exact.value()))
            return m_exact.value();

        if (m_ideal && function(m_ideal.value()))
            return m_ideal.value();

        return 0;
    }

    ValueType valueForCapabilityRange(ValueType current, ValueType capabilityMin, ValueType capabilityMax) const
    {
        ValueType value;
        ValueType min = capabilityMin;
        ValueType max = capabilityMax;

        if (m_exact) {
            ASSERT(validForRange(capabilityMin, capabilityMax));
            return m_exact.value();
        }

        if (m_min) {
            value = m_min.value();
            ASSERT(validForRange(value, capabilityMax));
            if (value > min)
                min = value;

            // If there is no ideal, don't change if minimum is smaller than current.
            if (!m_ideal && value < current)
                value = current;
        }

        if (m_max) {
            value = m_max.value();
            ASSERT(validForRange(capabilityMin, value));
            if (value < max)
                max = value;
        }

        if (m_ideal)
            value = std::max(min, std::min(max, m_ideal.value()));

        return value;
    }

    bool isEmpty() const { return !m_min && !m_max && !m_exact && !m_ideal; }
    bool isMandatory() const { return m_min || m_max || m_exact; }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        MediaConstraint::encode(encoder);

        encoder << m_min;
        encoder << m_max;
        encoder << m_exact;
        encoder << m_ideal;
    }

    template <class Decoder> static bool decode(Decoder& decoder, NumericConstraint& constraint)
    {
        if (!MediaConstraint::decode(decoder, constraint))
            return false;

        if (!decoder.decode(constraint.m_min))
            return false;
        if (!decoder.decode(constraint.m_max))
            return false;
        if (!decoder.decode(constraint.m_exact))
            return false;
        if (!decoder.decode(constraint.m_ideal))
            return false;
    
        return true;
    }

protected:
    NumericConstraint(const String& name, MediaConstraintType type, DataType dataType)
        : MediaConstraint(name, type, dataType)
    {
    }

    NumericConstraint() = default;

    void innerMerge(const NumericConstraint& other)
    {
        if (other.isEmpty())
            return;

        ValueType value;
        if (other.getExact(value))
            m_exact = value;

        if (other.getMin(value))
            m_min = value;

        if (other.getMax(value))
            m_max = value;

        // https://w3c.github.io/mediacapture-main/#constrainable-interface
        // When processing advanced constraints:
        //   ... the User Agent must attempt to apply, individually, any 'ideal' constraints or
        //   a constraint given as a bare value for the property. Of these properties, it must
        //   satisfy the largest number that it can, in any order.
        if (other.getIdeal(value)) {
            if (!m_ideal || value > m_ideal.value())
                m_ideal = value;
        }
    }

    std::optional<ValueType> m_min;
    std::optional<ValueType> m_max;
    std::optional<ValueType> m_exact;
    std::optional<ValueType> m_ideal;
};

class IntConstraint final : public NumericConstraint<int> {
public:
    IntConstraint(const String& name, MediaConstraintType type)
        : NumericConstraint<int>(name, type, DataType::Integer)
    {
    }

    IntConstraint() = default;

    void merge(const MediaConstraint& other)
    {
        ASSERT(other.isInt());
        NumericConstraint::innerMerge(downcast<const IntConstraint>(other));
    }
};

class DoubleConstraint final : public NumericConstraint<double> {
public:
    DoubleConstraint(const String& name, MediaConstraintType type)
        : NumericConstraint<double>(name, type, DataType::Double)
    {
    }

    DoubleConstraint() = default;

    void merge(const MediaConstraint& other)
    {
        ASSERT(other.isDouble());
        NumericConstraint::innerMerge(downcast<DoubleConstraint>(other));
    }
};

class BooleanConstraint final : public MediaConstraint {
public:
    BooleanConstraint(const String& name, MediaConstraintType type)
        : MediaConstraint(name, type, DataType::Boolean)
    {
    }

    BooleanConstraint() = default;

    void setExact(bool value) { m_exact = value; }
    void setIdeal(bool value) { m_ideal = value; }

    bool getExact(bool& exact) const
    {
        if (!m_exact)
            return false;

        exact = m_exact.value();
        return true;
    }

    bool getIdeal(bool& ideal) const
    {
        if (!m_ideal)
            return false;

        ideal = m_ideal.value();
        return true;
    }

    double fitnessDistance(bool value) const
    {
        // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
        // 1. If the constraint is not supported by the browser, the fitness distance is 0.
        if (isEmpty())
            return 0;

        // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
        //    dictionary's value for the constraint does not satisfy the constraint, the
        //    fitness distance is positive infinity.
        if (m_exact && value != m_exact.value())
            return std::numeric_limits<double>::infinity();

        // 3. If no ideal value is specified, the fitness distance is 0.
        if (!m_ideal || m_ideal.value() == value)
            return 0;

        // 5. For all string and enum non-required constraints (deviceId, groupId, facingMode,
        // echoCancellation), the fitness distance is the result of the formula
        //        (actual == ideal) ? 0 : 1
        return 1;
    }

    void merge(const MediaConstraint& other)
    {
        ASSERT(other.isBoolean());
        const BooleanConstraint& typedOther = downcast<BooleanConstraint>(other);

        if (typedOther.isEmpty())
            return;

        bool value;
        if (typedOther.getExact(value))
            m_exact = value;

        if (typedOther.getIdeal(value)) {
            if (!m_ideal || (value && !m_ideal.value()))
                m_ideal = value;
        }
    }

    bool isEmpty() const { return !m_exact && !m_ideal; };
    bool isMandatory() const { return bool(m_exact); }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        MediaConstraint::encode(encoder);
        encoder << m_exact;
        encoder << m_ideal;
    }

    template <class Decoder> static bool decode(Decoder& decoder, BooleanConstraint& constraint)
    {
        if (!MediaConstraint::decode(decoder, constraint))
            return false;

        if (!decoder.decode(constraint.m_exact))
            return false;
        if (!decoder.decode(constraint.m_ideal))
            return false;

        return true;
    }

private:
    std::optional<bool> m_exact;
    std::optional<bool> m_ideal;
};

class StringConstraint : public MediaConstraint {
public:
    StringConstraint(const String& name, MediaConstraintType type)
        : MediaConstraint(name, type, DataType::String)
    {
    }

    StringConstraint() = default;

    void setExact(const String& value)
    {
        m_exact.clear();
        m_exact.append(value);
    }

    void appendExact(const String& value)
    {
        m_exact.append(value);
    }

    void setIdeal(const String& value)
    {
        m_ideal.clear();
        m_ideal.append(value);
    }

    void appendIdeal(const String& value)
    {
        m_ideal.append(value);
    }

    bool getExact(Vector<String>& exact) const
    {
        if (!m_exact.isEmpty())
            return false;

        exact = m_exact;
        return true;
    }

    bool getIdeal(Vector<String>& ideal) const
    {
        if (!m_ideal.isEmpty())
            return false;

        ideal = m_ideal;
        return true;
    }

    double fitnessDistance(const String&) const;
    double fitnessDistance(const Vector<String>&) const;

    const String& find(const WTF::Function<bool(const String&)>&) const;

    bool isEmpty() const { return m_exact.isEmpty() && m_ideal.isEmpty(); }
    bool isMandatory() const { return !m_exact.isEmpty(); }
    WEBCORE_EXPORT void merge(const MediaConstraint&);

    template <class Encoder> void encode(Encoder& encoder) const
    {
        MediaConstraint::encode(encoder);

        encoder << m_exact;
        encoder << m_ideal;
    }

    template <class Decoder> static bool decode(Decoder& decoder, StringConstraint& constraint)
    {
        if (!MediaConstraint::decode(decoder, constraint))
            return false;

        if (!decoder.decode(constraint.m_exact))
            return false;
        if (!decoder.decode(constraint.m_ideal))
            return false;

        return true;
    }

private:
    Vector<String> m_exact;
    Vector<String> m_ideal;
};

class UnknownConstraint final : public MediaConstraint {
public:
    UnknownConstraint(const String& name, MediaConstraintType type)
        : MediaConstraint(name, type, DataType::None)
    {
    }

private:
    bool isEmpty() const { return true; }
    bool isMandatory() const { return false; }
    void merge(const MediaConstraint&) { }
};

class MediaTrackConstraintSetMap {
public:
    WEBCORE_EXPORT void forEach(WTF::Function<void(const MediaConstraint&)>&&) const;
    void filter(const WTF::Function<bool(const MediaConstraint&)>&) const;
    bool isEmpty() const;
    WEBCORE_EXPORT size_t size() const;

    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<IntConstraint>&&);
    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<DoubleConstraint>&&);
    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<BooleanConstraint>&&);
    WEBCORE_EXPORT void set(MediaConstraintType, std::optional<StringConstraint>&&);

    std::optional<IntConstraint> width() const { return m_width; }
    std::optional<IntConstraint> height() const { return m_height; }
    std::optional<IntConstraint> sampleRate() const { return m_sampleRate; }
    std::optional<IntConstraint> sampleSize() const { return m_sampleSize; }

    std::optional<DoubleConstraint> aspectRatio() const { return m_aspectRatio; }
    std::optional<DoubleConstraint> frameRate() const { return m_frameRate; }
    std::optional<DoubleConstraint> volume() const { return m_volume; }

    std::optional<BooleanConstraint> echoCancellation() const { return m_echoCancellation; }
    std::optional<BooleanConstraint> displaySurface() const { return m_displaySurface; }
    std::optional<BooleanConstraint> logicalSurface() const { return m_logicalSurface; }

    std::optional<StringConstraint> facingMode() const { return m_facingMode; }
    std::optional<StringConstraint> deviceId() const { return m_deviceId; }
    std::optional<StringConstraint> groupId() const { return m_groupId; }

    template <class Encoder> void encode(Encoder& encoder) const
    {
        encoder << m_width;
        encoder << m_height;
        encoder << m_sampleRate;
        encoder << m_sampleSize;

        encoder << m_aspectRatio;
        encoder << m_frameRate;
        encoder << m_volume;

        encoder << m_echoCancellation;
        encoder << m_displaySurface;
        encoder << m_logicalSurface;

        encoder << m_facingMode;
        encoder << m_deviceId;
        encoder << m_groupId;
    }

    template <class Decoder> static std::optional<MediaTrackConstraintSetMap> decode(Decoder& decoder)
    {
        MediaTrackConstraintSetMap map;
        if (!decoder.decode(map.m_width))
            return std::nullopt;
        if (!decoder.decode(map.m_height))
            return std::nullopt;
        if (!decoder.decode(map.m_sampleRate))
            return std::nullopt;
        if (!decoder.decode(map.m_sampleSize))
            return std::nullopt;

        if (!decoder.decode(map.m_aspectRatio))
            return std::nullopt;
        if (!decoder.decode(map.m_frameRate))
            return std::nullopt;
        if (!decoder.decode(map.m_volume))
            return std::nullopt;

        if (!decoder.decode(map.m_echoCancellation))
            return std::nullopt;
        if (!decoder.decode(map.m_displaySurface))
            return std::nullopt;
        if (!decoder.decode(map.m_logicalSurface))
            return std::nullopt;

        if (!decoder.decode(map.m_facingMode))
            return std::nullopt;
        if (!decoder.decode(map.m_deviceId))
            return std::nullopt;
        if (!decoder.decode(map.m_groupId))
            return std::nullopt;

        return WTFMove(map);
    }

private:
    std::optional<IntConstraint> m_width;
    std::optional<IntConstraint> m_height;
    std::optional<IntConstraint> m_sampleRate;
    std::optional<IntConstraint> m_sampleSize;

    std::optional<DoubleConstraint> m_aspectRatio;
    std::optional<DoubleConstraint> m_frameRate;
    std::optional<DoubleConstraint> m_volume;

    std::optional<BooleanConstraint> m_echoCancellation;
    std::optional<BooleanConstraint> m_displaySurface;
    std::optional<BooleanConstraint> m_logicalSurface;

    std::optional<StringConstraint> m_facingMode;
    std::optional<StringConstraint> m_deviceId;
    std::optional<StringConstraint> m_groupId;
};

class FlattenedConstraint {
public:

    void set(const MediaConstraint&);
    void merge(const MediaConstraint&);
    void append(const MediaConstraint&);
    const MediaConstraint* find(MediaConstraintType) const;
    bool isEmpty() const { return m_variants.isEmpty(); }

    class iterator {
    public:
        iterator(const FlattenedConstraint* constraint, size_t index)
            : m_constraint(constraint)
            , m_index(index)
#ifndef NDEBUG
            , m_generation(constraint->m_generation)
#endif
        {
        }

        MediaConstraint& operator*() const
        {
            return m_constraint->m_variants.at(m_index).constraint();
        }

        iterator& operator++()
        {
#ifndef NDEBUG
            ASSERT(m_generation == m_constraint->m_generation);
#endif
            m_index++;
            return *this;
        }

        bool operator==(const iterator& other) const { return m_index == other.m_index; }
        bool operator!=(const iterator& other) const { return !(*this == other); }

    private:
        const FlattenedConstraint* m_constraint { nullptr };
        size_t m_index { 0 };
#ifndef NDEBUG
        int m_generation { 0 };
#endif
    };

    const iterator begin() const { return iterator(this, 0); }
    const iterator end() const { return iterator(this, m_variants.size()); }

private:
    class ConstraintHolder {
    public:
        static ConstraintHolder create(const MediaConstraint& value) { return ConstraintHolder(value); }

        ~ConstraintHolder()
        {
            if (m_value.asRaw) {
                switch (dataType()) {
                case MediaConstraint::DataType::Integer:
                    delete m_value.asInteger;
                    break;
                case MediaConstraint::DataType::Double:
                    delete m_value.asDouble;
                    break;
                case MediaConstraint::DataType::Boolean:
                    delete m_value.asBoolean;
                    break;
                case MediaConstraint::DataType::String:
                    delete m_value.asString;
                    break;
                case MediaConstraint::DataType::None:
                    ASSERT_NOT_REACHED();
                    break;
                }
            }
#ifndef NDEBUG
            m_value.asRaw = reinterpret_cast<MediaConstraint*>(0xbbadbeef);
#endif
        }

        ConstraintHolder(ConstraintHolder&& other)
        {
            switch (other.dataType()) {
            case MediaConstraint::DataType::Integer:
                m_value.asInteger = std::exchange(other.m_value.asInteger, nullptr);
                break;
            case MediaConstraint::DataType::Double:
                m_value.asDouble = std::exchange(other.m_value.asDouble, nullptr);
                break;
            case MediaConstraint::DataType::Boolean:
                m_value.asBoolean = std::exchange(other.m_value.asBoolean, nullptr);
                break;
            case MediaConstraint::DataType::String:
                m_value.asString = std::exchange(other.m_value.asString, nullptr);
                break;
            case MediaConstraint::DataType::None:
                ASSERT_NOT_REACHED();
                break;
            }
        }

        MediaConstraint& constraint() const { return *m_value.asRaw; }
        MediaConstraint::DataType dataType() const { return constraint().dataType(); }
        MediaConstraintType constraintType() const { return constraint().constraintType(); }

    private:
        explicit ConstraintHolder(const MediaConstraint& value)
        {
            switch (value.dataType()) {
            case MediaConstraint::DataType::Integer:
                m_value.asInteger = new IntConstraint(downcast<const IntConstraint>(value));
                break;
            case MediaConstraint::DataType::Double:
                m_value.asDouble = new DoubleConstraint(downcast<DoubleConstraint>(value));
                break;
            case MediaConstraint::DataType::Boolean:
                m_value.asBoolean = new BooleanConstraint(downcast<BooleanConstraint>(value));
                break;
            case MediaConstraint::DataType::String:
                m_value.asString = new StringConstraint(downcast<StringConstraint>(value));
                break;
            case MediaConstraint::DataType::None:
                ASSERT_NOT_REACHED();
                break;
            }
        }
        
        union {
            MediaConstraint* asRaw;
            IntConstraint* asInteger;
            DoubleConstraint* asDouble;
            BooleanConstraint* asBoolean;
            StringConstraint* asString;
        } m_value;
    };

    Vector<ConstraintHolder> m_variants;
#ifndef NDEBUG
    int m_generation { 0 };
#endif
};

struct MediaConstraints {
    void setDefaultVideoConstraints();
    bool isConstraintSet(const WTF::Function<bool(const MediaTrackConstraintSetMap&)>&);

    MediaTrackConstraintSetMap mandatoryConstraints;
    Vector<MediaTrackConstraintSetMap> advancedConstraints;
    String deviceIDHashSalt;
    bool isValid { false };
};
    
} // namespace WebCore

#define SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(ConstraintType, predicate) \
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ConstraintType) \
static bool isType(const WebCore::MediaConstraint& constraint) { return constraint.predicate; } \
SPECIALIZE_TYPE_TRAITS_END()

SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(IntConstraint, isInt())
SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(DoubleConstraint, isDouble())
SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(StringConstraint, isString())
SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(BooleanConstraint, isBoolean())

#endif // ENABLE(MEDIA_STREAM)
