/*
    Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    Copyright (C) 2006, 2008, 2014 Apple Inc. All rights reserved.
    Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com)
    Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#pragma once

#include "AnimationUtilities.h"
#include <string.h>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
#include <wtf/Forward.h>
#include <wtf/UniqueArray.h>

namespace WTF {
class TextStream;
}

namespace WebCore {

enum class LengthType : uint8_t {
    Auto,
    Relative,
    Percent,
    Fixed,
    Intrinsic,
    MinIntrinsic,
    MinContent,
    MaxContent,
    FillAvailable,
    FitContent,
    Calculated,
    Undefined
};

enum class ValueRange : uint8_t {
    All,
    NonNegative
};

struct BlendingContext;
class CalculationValue;

struct Length {
    WTF_MAKE_FAST_ALLOCATED;
public:
    Length(LengthType = LengthType::Auto);

    Length(int value, LengthType, bool hasQuirk = false);
    Length(LayoutUnit value, LengthType, bool hasQuirk = false);
    Length(float value, LengthType, bool hasQuirk = false);
    Length(double value, LengthType, bool hasQuirk = false);

    WEBCORE_EXPORT explicit Length(Ref<CalculationValue>&&);

    Length(const Length&);
    Length(Length&&);
    Length& operator=(const Length&);
    Length& operator=(Length&&);

    ~Length();

    void setValue(LengthType, int value);
    void setValue(LengthType, float value);
    void setValue(LengthType, LayoutUnit value);
    Length& operator*=(float);

    bool operator==(const Length&) const;
    bool operator!=(const Length&) const;

    float value() const;
    int intValue() const;
    float percent() const;
    CalculationValue& calculationValue() const;

    LengthType type() const;

    bool isAuto() const;
    bool isCalculated() const;
    bool isFixed() const;
    bool isMaxContent() const;
    bool isMinContent() const;
    bool isPercent() const;
    bool isRelative() const;
    bool isUndefined() const;
    bool isFillAvailable() const;
    bool isFitContent() const;
    bool isMinIntrinsic() const;

    bool hasQuirk() const;
    void setHasQuirk(bool);

    // FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated Length
    // always contains a percentage, and without a maxValue passed to these functions
    // it's impossible to determine the sign or zero-ness. The following three functions
    // act as if all calculated values are positive.
    bool isZero() const;
    bool isPositive() const;
    bool isNegative() const;

    bool isFloat() const;

    bool isPercentOrCalculated() const; // Returns true for both Percent and Calculated.

    bool isIntrinsic() const;
    bool isIntrinsicOrAuto() const;
    bool isSpecified() const;
    bool isSpecifiedOrIntrinsic() const;

    float nonNanCalculatedValue(float maxValue) const;

    bool isLegacyIntrinsic() const;

private:
    bool isCalculatedEqual(const Length&) const;

    void initialize(const Length&);
    void initialize(Length&&);

    WEBCORE_EXPORT void ref() const;
    WEBCORE_EXPORT void deref() const;
    
    union {
        int m_intValue { 0 };
        float m_floatValue;
        unsigned m_calculationValueHandle;
    };
    LengthType m_type;
    bool m_hasQuirk { false };
    bool m_isFloat { false };
};

// Blend two lengths to produce a new length that is in between them. Used for animation.
Length blend(const Length& from, const Length& to, const BlendingContext&);
Length blend(const Length& from, const Length& to, const BlendingContext&, ValueRange);

UniqueArray<Length> newCoordsArray(const String&, int& length);
UniqueArray<Length> newLengthArray(const String&, int& length);

inline Length::Length(LengthType type)
    : m_type(type)
{
    ASSERT(type != LengthType::Calculated);
}

inline Length::Length(int value, LengthType type, bool hasQuirk)
    : m_intValue(value)
    , m_type(type)
    , m_hasQuirk(hasQuirk)
{
    ASSERT(type != LengthType::Calculated);
}

inline Length::Length(LayoutUnit value, LengthType type, bool hasQuirk)
    : m_floatValue(value.toFloat())
    , m_type(type)
    , m_hasQuirk(hasQuirk)
    , m_isFloat(true)
{
    ASSERT(type != LengthType::Calculated);
}

inline Length::Length(float value, LengthType type, bool hasQuirk)
    : m_floatValue(value)
    , m_type(type)
    , m_hasQuirk(hasQuirk)
    , m_isFloat(true)
{
    ASSERT(type != LengthType::Calculated);
}

inline Length::Length(double value, LengthType type, bool hasQuirk)
    : m_floatValue(static_cast<float>(value))
    , m_type(type)
    , m_hasQuirk(hasQuirk)
    , m_isFloat(true)
{
    ASSERT(type != LengthType::Calculated);
}

inline Length::Length(const Length& other)
{
    initialize(other);
}

inline Length::Length(Length&& other)
{
    initialize(WTFMove(other));
}

inline Length& Length::operator=(const Length& other)
{
    if (this == &other)
        return *this;

    if (isCalculated())
        deref();

    initialize(other);
    return *this;
}

inline Length& Length::operator=(Length&& other)
{
    if (this == &other)
        return *this;

    if (isCalculated())
        deref();

    initialize(WTFMove(other));
    return *this;
}

inline void Length::initialize(const Length& other)
{
    m_type = other.m_type;
    m_hasQuirk = other.m_hasQuirk;

    switch (m_type) {
    case LengthType::Auto:
    case LengthType::Undefined:
        m_intValue = 0;
        break;
    case LengthType::Fixed:
    case LengthType::Relative:
    case LengthType::Intrinsic:
    case LengthType::MinIntrinsic:
    case LengthType::MinContent:
    case LengthType::MaxContent:
    case LengthType::FillAvailable:
    case LengthType::FitContent:
    case LengthType::Percent:
        m_isFloat = other.m_isFloat;
        if (m_isFloat)
            m_floatValue = other.m_floatValue;
        else
            m_intValue = other.m_intValue;
        break;
    case LengthType::Calculated:
        m_calculationValueHandle = other.m_calculationValueHandle;
        ref();
        break;
    }
}

inline void Length::initialize(Length&& other)
{
    m_type = other.m_type;
    m_hasQuirk = other.m_hasQuirk;

    switch (m_type) {
    case LengthType::Auto:
    case LengthType::Undefined:
        m_intValue = 0;
        break;
    case LengthType::Fixed:
    case LengthType::Relative:
    case LengthType::Intrinsic:
    case LengthType::MinIntrinsic:
    case LengthType::MinContent:
    case LengthType::MaxContent:
    case LengthType::FillAvailable:
    case LengthType::FitContent:
    case LengthType::Percent:
        m_isFloat = other.m_isFloat;
        if (m_isFloat)
            m_floatValue = other.m_floatValue;
        else
            m_intValue = other.m_intValue;
        break;
    case LengthType::Calculated:
        m_calculationValueHandle = std::exchange(other.m_calculationValueHandle, 0);
        break;
    }

    other.m_type = LengthType::Auto;
}

inline Length::~Length()
{
    if (isCalculated())
        deref();
}

inline bool Length::operator==(const Length& other) const
{
    // FIXME: This might be too long to be inline.
    if (type() != other.type() || hasQuirk() != other.hasQuirk())
        return false;
    if (isUndefined())
        return true;
    if (isCalculated())
        return isCalculatedEqual(other);
    return value() == other.value();
}

inline bool Length::operator!=(const Length& other) const
{
    return !(*this == other);
}

inline Length& Length::operator*=(float value)
{
    ASSERT(!isCalculated());
    if (isCalculated())
        return *this;

    if (m_isFloat)
        m_floatValue *= value;
    else
        m_intValue *= value;

    return *this;
}

inline float Length::value() const
{
    ASSERT(!isUndefined());
    ASSERT(!isCalculated());
    return m_isFloat ? m_floatValue : m_intValue;
}

inline int Length::intValue() const
{
    ASSERT(!isUndefined());
    ASSERT(!isCalculated());
    // FIXME: Makes no sense to return 0 here but not in the value() function above.
    if (isCalculated())
        return 0;
    return m_isFloat ? static_cast<int>(m_floatValue) : m_intValue;
}

inline float Length::percent() const
{
    ASSERT(isPercent());
    return value();
}

inline LengthType Length::type() const
{
    return static_cast<LengthType>(m_type);
}

inline bool Length::hasQuirk() const
{
    return m_hasQuirk;
}

inline bool Length::isFloat() const
{
    return m_isFloat;
}

inline void Length::setHasQuirk(bool hasQuirk)
{
    m_hasQuirk = hasQuirk;
}

inline void Length::setValue(LengthType type, int value)
{
    ASSERT(m_type != LengthType::Calculated);
    ASSERT(type != LengthType::Calculated);
    m_type = type;
    m_intValue = value;
    m_isFloat = false;
}

inline void Length::setValue(LengthType type, float value)
{
    ASSERT(m_type != LengthType::Calculated);
    ASSERT(type != LengthType::Calculated);
    m_type = type;
    m_floatValue = value;
    m_isFloat = true;
}

inline void Length::setValue(LengthType type, LayoutUnit value)
{
    ASSERT(m_type != LengthType::Calculated);
    ASSERT(type != LengthType::Calculated);
    m_type = type;
    m_floatValue = value;
    m_isFloat = true;
}

inline bool Length::isAuto() const
{
    return type() == LengthType::Auto;
}

inline bool Length::isFixed() const
{
    return type() == LengthType::Fixed;
}

inline bool Length::isMaxContent() const
{
    return type() == LengthType::MaxContent;
}

inline bool Length::isMinContent() const
{
    return type() == LengthType::MinContent;
}

inline bool Length::isNegative() const
{
    if (isUndefined() || isCalculated())
        return false;
    return m_isFloat ? (m_floatValue < 0) : (m_intValue < 0);
}

inline bool Length::isPercent() const
{
    return type() == LengthType::Percent;
}

inline bool Length::isRelative() const
{
    return type() == LengthType::Relative;
}

inline bool Length::isUndefined() const
{
    return type() == LengthType::Undefined;
}

inline bool Length::isPercentOrCalculated() const
{
    return isPercent() || isCalculated();
}

inline bool Length::isPositive() const
{
    if (isUndefined())
        return false;
    if (isCalculated())
        return true;
    return m_isFloat ? (m_floatValue > 0) : (m_intValue > 0);
}

inline bool Length::isZero() const
{
    ASSERT(!isUndefined());
    if (isCalculated() || isAuto())
        return false;
    return m_isFloat ? !m_floatValue : !m_intValue;
}

inline bool Length::isCalculated() const
{
    return type() == LengthType::Calculated;
}

inline bool Length::isLegacyIntrinsic() const
{
    return type() == LengthType::Intrinsic || type() == LengthType::MinIntrinsic;
}

inline bool Length::isIntrinsic() const
{
    // FIXME: This is misleadingly named. One would expect this function does "return type() == LengthType::Intrinsic;".
    return type() == LengthType::MinContent || type() == LengthType::MaxContent || type() == LengthType::FillAvailable || type() == LengthType::FitContent;
}

inline bool Length::isIntrinsicOrAuto() const
{
    return isAuto() || isIntrinsic() || isLegacyIntrinsic();
}

inline bool Length::isSpecified() const
{
    return isFixed() || isPercentOrCalculated();
}

inline bool Length::isSpecifiedOrIntrinsic() const
{
    return isSpecified() || isIntrinsic();
}

inline bool Length::isFillAvailable() const
{
    return type() == LengthType::FillAvailable;
}

inline bool Length::isFitContent() const
{
    return type() == LengthType::FitContent;
}

inline bool Length::isMinIntrinsic() const
{
    return type() == LengthType::MinIntrinsic;
}

Length convertTo100PercentMinusLength(const Length&);

WTF::TextStream& operator<<(WTF::TextStream&, Length);

} // namespace WebCore
