/*
 * Copyright (C) 2017 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 APPLE INC. AND ITS 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 APPLE INC. OR ITS 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

#include "TextFlags.h"
#include <algorithm>
#include <tuple>
#include <wtf/Hasher.h>
#include <wtf/text/TextStream.h>

namespace WebCore {

// Unclamped, unchecked, signed fixed-point number representing a value used for font variations.
// Sixteen bits in total, one sign bit, two fractional bits, smallest positive value is 0.25,
// maximum value is 8191.75, and minimum value is -8192.
class FontSelectionValue {
public:
    using BackingType = int16_t;

    FontSelectionValue() = default;

    // Explicit because it won't work correctly for values outside the representable range.
    explicit constexpr FontSelectionValue(int);

    // Explicit because it won't work correctly for values outside the representable range and because precision can be lost.
    explicit constexpr FontSelectionValue(float);

    // Precision can be lost, but value will be clamped to the representable range.
    static constexpr FontSelectionValue clampFloat(float);

    // Since floats have 23 mantissa bits, every value can be represented losslessly.
    constexpr operator float() const;

    static constexpr FontSelectionValue maximumValue();
    static constexpr FontSelectionValue minimumValue();

    friend constexpr FontSelectionValue operator+(FontSelectionValue, FontSelectionValue);
    friend constexpr FontSelectionValue operator-(FontSelectionValue, FontSelectionValue);
    friend constexpr FontSelectionValue operator*(FontSelectionValue, FontSelectionValue);
    friend constexpr FontSelectionValue operator/(FontSelectionValue, FontSelectionValue);
    friend constexpr FontSelectionValue operator-(FontSelectionValue);

    constexpr BackingType rawValue() const { return m_backing; }

    template<class Encoder>
    void encode(Encoder&) const;

    template<class Decoder>
    static std::optional<FontSelectionValue> decode(Decoder&);

private:
    enum class RawTag { RawTag };
    constexpr FontSelectionValue(int, RawTag);

    static constexpr int fractionalEntropy = 4;
    BackingType m_backing { 0 };
};

template<class Encoder>
void FontSelectionValue::encode(Encoder& encoder) const
{
    encoder << m_backing;
}

template<class Decoder>
std::optional<FontSelectionValue> FontSelectionValue::decode(Decoder& decoder)
{
    std::optional<FontSelectionValue::BackingType> backing;
    decoder >> backing;
    if (!backing)
        return std::nullopt;

    FontSelectionValue result;
    result.m_backing = *backing;
    return result;
}

constexpr FontSelectionValue::FontSelectionValue(int x)
    : m_backing(x * fractionalEntropy)
{
    // FIXME: Should we assert the passed in value was in range?
}

constexpr FontSelectionValue::FontSelectionValue(float x)
    : m_backing(x * fractionalEntropy)
{
    // FIXME: Should we assert the passed in value was in range?
}

constexpr FontSelectionValue::operator float() const
{
    return m_backing / static_cast<float>(fractionalEntropy);
}

constexpr FontSelectionValue FontSelectionValue::maximumValue()
{
    return { std::numeric_limits<BackingType>::max(), RawTag::RawTag };
}

constexpr FontSelectionValue FontSelectionValue::minimumValue()
{
    return { std::numeric_limits<BackingType>::min(), RawTag::RawTag };
}

constexpr FontSelectionValue FontSelectionValue::clampFloat(float value)
{
    return FontSelectionValue { std::max<float>(minimumValue(), std::min<float>(value, maximumValue())) };
}

constexpr FontSelectionValue::FontSelectionValue(int rawValue, RawTag)
    : m_backing(rawValue)
{
}

constexpr FontSelectionValue operator+(FontSelectionValue a, FontSelectionValue b)
{
    return { a.m_backing + b.m_backing, FontSelectionValue::RawTag::RawTag };
}

constexpr FontSelectionValue operator-(FontSelectionValue a, FontSelectionValue b)
{
    return { a.m_backing - b.m_backing, FontSelectionValue::RawTag::RawTag };
}

constexpr FontSelectionValue operator*(FontSelectionValue a, FontSelectionValue b)
{
    return { a.m_backing * b.m_backing / FontSelectionValue::fractionalEntropy, FontSelectionValue::RawTag::RawTag };
}

constexpr FontSelectionValue operator/(FontSelectionValue a, FontSelectionValue b)
{
    return { a.m_backing * FontSelectionValue::fractionalEntropy / b.m_backing, FontSelectionValue::RawTag::RawTag };
}

constexpr FontSelectionValue operator-(FontSelectionValue value)
{
    return { -value.m_backing, FontSelectionValue::RawTag::RawTag };
}

constexpr bool operator==(FontSelectionValue a, FontSelectionValue b)
{
    return a.rawValue() == b.rawValue();
}

constexpr bool operator!=(FontSelectionValue a, FontSelectionValue b)
{
    return a.rawValue() != b.rawValue();
}

constexpr bool operator<(FontSelectionValue a, FontSelectionValue b)
{
    return a.rawValue() < b.rawValue();
}

constexpr bool operator<=(FontSelectionValue a, FontSelectionValue b)
{
    return a.rawValue() <= b.rawValue();
}

constexpr bool operator>(FontSelectionValue a, FontSelectionValue b)
{
    return a.rawValue() > b.rawValue();
}

constexpr bool operator>=(FontSelectionValue a, FontSelectionValue b)
{
    return a.rawValue() >= b.rawValue();
}

constexpr FontSelectionValue italicThreshold()
{
    return FontSelectionValue { 20 };
}

constexpr bool isItalic(std::optional<FontSelectionValue> fontWeight)
{
    return fontWeight && fontWeight.value() >= italicThreshold();
}

constexpr FontSelectionValue normalItalicValue()
{
    return FontSelectionValue { 0 };
}

constexpr FontSelectionValue italicValue()
{
    return FontSelectionValue { 20 };
}

constexpr FontSelectionValue boldThreshold()
{
    return FontSelectionValue { 600 };
}

constexpr FontSelectionValue boldWeightValue()
{
    return FontSelectionValue { 700 };
}

constexpr FontSelectionValue normalWeightValue()
{
    return FontSelectionValue { 400 };
}

constexpr FontSelectionValue lightWeightValue()
{
    return FontSelectionValue { 200 };
}

constexpr bool isFontWeightBold(FontSelectionValue fontWeight)
{
    return fontWeight >= boldThreshold();
}

constexpr FontSelectionValue lowerWeightSearchThreshold()
{
    return FontSelectionValue { 400 };
}

constexpr FontSelectionValue upperWeightSearchThreshold()
{
    return FontSelectionValue { 500 };
}

constexpr FontSelectionValue ultraCondensedStretchValue()
{
    return FontSelectionValue { 50 };
}

constexpr FontSelectionValue extraCondensedStretchValue()
{
    return FontSelectionValue { 62.5f };
}

constexpr FontSelectionValue condensedStretchValue()
{
    return FontSelectionValue { 75 };
}

constexpr FontSelectionValue semiCondensedStretchValue()
{
    return FontSelectionValue { 87.5f };
}

constexpr FontSelectionValue normalStretchValue()
{
    return FontSelectionValue { 100 };
}

constexpr FontSelectionValue semiExpandedStretchValue()
{
    return FontSelectionValue { 112.5f };
}

constexpr FontSelectionValue expandedStretchValue()
{
    return FontSelectionValue { 125 };
}

constexpr FontSelectionValue extraExpandedStretchValue()
{
    return FontSelectionValue { 150 };
}

constexpr FontSelectionValue ultraExpandedStretchValue()
{
    return FontSelectionValue { 200 };
}

inline void add(Hasher& hasher, const FontSelectionValue& value)
{
    add(hasher, value.rawValue());
}

// [Inclusive, Inclusive]
struct FontSelectionRange {
    using Value = FontSelectionValue;

    constexpr FontSelectionRange(Value minimum, Value maximum)
        : minimum(minimum)
        , maximum(maximum)
    {
    }

    explicit constexpr FontSelectionRange(Value value)
        : minimum(value)
        , maximum(value)
    {
    }

    constexpr bool operator==(const FontSelectionRange& other) const
    {
        return WTF::tie(minimum, maximum) == WTF::tie(other.minimum, other.maximum);
    }

    constexpr bool isValid() const
    {
        return minimum <= maximum;
    }

    void expand(const FontSelectionRange& other)
    {
        ASSERT(other.isValid());
        if (!isValid())
            *this = other;
        else {
            minimum = std::min(minimum, other.minimum);
            maximum = std::max(maximum, other.maximum);
        }
        ASSERT(isValid());
    }

    constexpr bool includes(Value target) const
    {
        return target >= minimum && target <= maximum;
    }

    template<class Encoder>
    void encode(Encoder&) const;

    template<class Decoder>
    static std::optional<FontSelectionRange> decode(Decoder&);

    Value minimum { 1 };
    Value maximum { 0 };
};

template<class Encoder>
void FontSelectionRange::encode(Encoder& encoder) const
{
    encoder << minimum;
    encoder << maximum;
}

template<class Decoder>
std::optional<FontSelectionRange> FontSelectionRange::decode(Decoder& decoder)
{
    std::optional<FontSelectionRange::Value> minimum;
    decoder >> minimum;
    if (!minimum)
        return std::nullopt;

    std::optional<FontSelectionRange::Value> maximum;
    decoder >> maximum;
    if (!maximum)
        return std::nullopt;

    return {{ *minimum, *maximum }};
}

inline void add(Hasher& hasher, const FontSelectionRange& range)
{
    add(hasher, range.minimum, range.maximum);
}

struct FontSelectionRequest {
    using Value = FontSelectionValue;

    Value weight;
    Value width;

    // FIXME: We are using an optional here to be able to distinguish between an explicit
    // or implicit slope (for "italic" and "oblique") and the "normal" value which has no
    // slope. The "italic" and "oblique" values can be distinguished by looking at the
    // "fontStyleAxis" on the FontDescription. We should come up with a tri-state member
    // so that it's a lot clearer whether we're dealing with a "normal", "italic" or explicit
    // "oblique" font style. See webkit.org/b/187774.
    std::optional<Value> slope;

    std::tuple<Value, Value, std::optional<Value>> tied() const
    {
        return WTF::tie(weight, width, slope);
    }
};

inline TextStream& operator<<(TextStream& ts, const FontSelectionValue& fontSelectionValue)
{
    ts << TextStream::FormatNumberRespectingIntegers(fontSelectionValue.rawValue());
    return ts;
}

inline TextStream& operator<<(TextStream& ts, const std::optional<FontSelectionValue>& optionalFontSelectionValue)
{
    ts << optionalFontSelectionValue.value_or(normalItalicValue());
    return ts;
}

inline bool operator==(const FontSelectionRequest& a, const FontSelectionRequest& b)
{
    return a.tied() == b.tied();
}

inline bool operator!=(const FontSelectionRequest& a, const FontSelectionRequest& b)
{
    return !(a == b);
}

inline void add(Hasher& hasher, const FontSelectionRequest& request)
{
    add(hasher, request.tied());
}

struct FontSelectionCapabilities {
    using Range = FontSelectionRange;

    constexpr std::tuple<Range, Range, Range> tied() const
    {
        return WTF::tie(weight, width, slope);
    }

    void expand(const FontSelectionCapabilities& capabilities)
    {
        weight.expand(capabilities.weight);
        width.expand(capabilities.width);
        slope.expand(capabilities.slope);
    }

    Range weight { normalWeightValue() };
    Range width { normalStretchValue() };
    Range slope { normalItalicValue() };
};

constexpr bool operator==(const FontSelectionCapabilities& a, const FontSelectionCapabilities& b)
{
    return a.tied() == b.tied();
}

constexpr bool operator!=(const FontSelectionCapabilities& a, const FontSelectionCapabilities& b)
{
    return !(a == b);
}

struct FontSelectionSpecifiedCapabilities {
    using Capabilities = FontSelectionCapabilities;
    using Range = FontSelectionRange;
    using OptionalRange = std::optional<Range>;

    constexpr Capabilities computeFontSelectionCapabilities() const
    {
        return { computeWeight(), computeWidth(), computeSlope() };
    }

    constexpr std::tuple<OptionalRange&, OptionalRange&, OptionalRange&> tied()
    {
        return WTF::tie(weight, width, slope);
    }

    constexpr std::tuple<const OptionalRange&, const OptionalRange&, const OptionalRange&> tied() const
    {
        return WTF::tie(weight, width, slope);
    }

    FontSelectionSpecifiedCapabilities& operator=(const Capabilities& other)
    {
        tied() = other.tied();
        return *this;
    }

    constexpr Range computeWeight() const
    {
        return weight.value_or(Range { normalWeightValue() });
    }

    constexpr Range computeWidth() const
    {
        return width.value_or(Range { normalStretchValue() });
    }

    constexpr Range computeSlope() const
    {
        return slope.value_or(Range { normalItalicValue() });
    }

    template<class Encoder>
    void encode(Encoder&) const;

    template<class Decoder>
    static std::optional<FontSelectionSpecifiedCapabilities> decode(Decoder&);

    OptionalRange weight;
    OptionalRange width;
    OptionalRange slope;
};

template<class Encoder>
void FontSelectionSpecifiedCapabilities::encode(Encoder& encoder) const
{
    encoder << weight;
    encoder << width;
    encoder << slope;
}

template<class Decoder>
std::optional<FontSelectionSpecifiedCapabilities> FontSelectionSpecifiedCapabilities::decode(Decoder& decoder)
{
    std::optional<OptionalRange> weight;
    decoder >> weight;
    if (!weight)
        return std::nullopt;

    std::optional<OptionalRange> width;
    decoder >> width;
    if (!width)
        return std::nullopt;

    std::optional<OptionalRange> slope;
    decoder >> slope;
    if (!slope)
        return std::nullopt;

    return {{ *weight, *width, *slope }};
}

constexpr bool operator==(const FontSelectionSpecifiedCapabilities& a, const FontSelectionSpecifiedCapabilities& b)
{
    return a.tied() == b.tied();
}

constexpr bool operator!=(const FontSelectionSpecifiedCapabilities& a, const FontSelectionSpecifiedCapabilities& b)
{
    return !(a == b);
}

class FontSelectionAlgorithm {
public:
    using Capabilities = FontSelectionCapabilities;

    FontSelectionAlgorithm() = delete;
    FontSelectionAlgorithm(FontSelectionRequest, const Vector<Capabilities>&, std::optional<Capabilities> capabilitiesBounds = std::nullopt);

    struct DistanceResult {
        FontSelectionValue distance;
        FontSelectionValue value;
    };
    DistanceResult stretchDistance(Capabilities) const;
    DistanceResult styleDistance(Capabilities) const;
    DistanceResult weightDistance(Capabilities) const;

    size_t indexOfBestCapabilities();

private:
    using DistanceFunction = DistanceResult (FontSelectionAlgorithm::*)(Capabilities) const;
    using CapabilitiesRange = FontSelectionRange Capabilities::*;
    FontSelectionValue bestValue(const bool eliminated[], DistanceFunction) const;
    void filterCapability(bool eliminated[], DistanceFunction, CapabilitiesRange);

    FontSelectionRequest m_request;
    Capabilities m_capabilitiesBounds;
    const Vector<Capabilities>& m_capabilities;
};

}
