/*
 * Copyright (C) 2003-2020 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Rob Buis <buis@kde.org>
 * Copyright (C) 2007-2008 Torch Mobile, Inc.
 *
 * 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. ``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
 * 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 "FloatRect.h"
#include "InlinePathData.h"
#include "WindRule.h"
#include <wtf/EnumTraits.h>
#include <wtf/FastMalloc.h>
#include <wtf/Function.h>
#include <wtf/Forward.h>

#if USE(CG)

#include <wtf/RetainPtr.h>
#include <CoreGraphics/CGPath.h>
typedef struct CGPath PlatformPath;

#elif USE(DIRECT2D)
#include "COMPtr.h"

interface ID2D1Geometry;
interface ID2D1GeometryGroup;
interface ID2D1PathGeometry;
interface ID2D1GeometrySink;

typedef ID2D1GeometryGroup PlatformPath;

namespace WebCore {
class PlatformContextDirect2D;
}

#elif USE(CAIRO)
#include "RefPtrCairo.h"

#else

typedef void PlatformPath;

#endif

#if !USE(CAIRO)
typedef PlatformPath* PlatformPathPtr;

#if USE(CG)
using PlatformPathStorageType = RetainPtr<CGMutablePathRef>;
#elif USE(DIRECT2D)
using PlatformPathStorageType = COMPtr<ID2D1GeometryGroup>;
#else
using PlatformPathStorageType = PlatformPathPtr;
#endif
#endif

namespace WTF {
class TextStream;
}

namespace WebCore {

class AffineTransform;
class FloatPoint;
class FloatRoundedRect;
class FloatSize;
class GraphicsContext;
class PathTraversalState;
class RoundedRect;

// The points in the structure are the same as those that would be used with the
// add... method. For example, a line returns the endpoint, while a cubic returns
// two tangent points and the endpoint.
struct PathElement {
    enum class Type : uint8_t {
        MoveToPoint, // The points member will contain 1 value.
        AddLineToPoint, // The points member will contain 1 value.
        AddQuadCurveToPoint, // The points member will contain 2 values.
        AddCurveToPoint, // The points member will contain 3 values.
        CloseSubpath // The points member will contain no values.
    };

    FloatPoint points[3];
    Type type;
};

using PathApplierFunction = WTF::Function<void(const PathElement&)>;

class Path {
    WTF_MAKE_FAST_ALLOCATED;
public:
    WEBCORE_EXPORT Path();
#if USE(CG)
    Path(RetainPtr<CGMutablePathRef>&&);
#endif
#if USE(CAIRO)
    explicit Path(RefPtr<cairo_t>&&);
#endif
    WEBCORE_EXPORT ~Path();

    WEBCORE_EXPORT Path(const Path&);
    WEBCORE_EXPORT Path(Path&&);
    WEBCORE_EXPORT Path& operator=(const Path&);
    WEBCORE_EXPORT Path& operator=(Path&&);

#if ENABLE(INLINE_PATH_DATA)
    static Path from(const InlinePathData& inlineData)
    {
        Path path;
        path.m_inlineData = inlineData;
        return path;
    }
#endif

    static Path polygonPathFromPoints(const Vector<FloatPoint>&);

    bool contains(const FloatPoint&, WindRule = WindRule::NonZero) const;
    bool strokeContains(const FloatPoint&, const WTF::Function<void(GraphicsContext&)>& strokeStyleApplier) const;

    // fastBoundingRect() should equal or contain boundingRect(); boundingRect()
    // should perfectly bound the points within the path.
    FloatRect boundingRect() const;
    WEBCORE_EXPORT FloatRect fastBoundingRect() const;
    FloatRect strokeBoundingRect(const WTF::Function<void(GraphicsContext&)>& strokeStyleApplier = { }) const;

    WEBCORE_EXPORT size_t elementCount() const;
    float length() const;
    PathTraversalState traversalStateAtLength(float length) const;
    FloatPoint pointAtLength(float length) const;

    WEBCORE_EXPORT void clear();
    WEBCORE_EXPORT bool isNull() const;
    bool isEmpty() const;
    // Gets the current point of the current path, which is conceptually the final point reached by the path so far.
    // Note the Path can be empty (isEmpty() == true) and still have a current point.
    // FIXME: The above comment might need to be updated; on all supported platforms, the result of hasCurrentPoint() is identical
    // to !isEmpty().
    bool hasCurrentPoint() const;
    FloatPoint currentPoint() const;

    WEBCORE_EXPORT void moveTo(const FloatPoint&);
    WEBCORE_EXPORT void addLineTo(const FloatPoint&);
    WEBCORE_EXPORT void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint);
    WEBCORE_EXPORT void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);
    void addArcTo(const FloatPoint&, const FloatPoint&, float radius);
    WEBCORE_EXPORT void closeSubpath();

    void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
    WEBCORE_EXPORT void addRect(const FloatRect&);
    void addEllipse(FloatPoint, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise);
    void addEllipse(const FloatRect&);

    enum class RoundedRectStrategy : uint8_t {
        PreferNative,
        PreferBezier
    };

    WEBCORE_EXPORT void addRoundedRect(const FloatRect&, const FloatSize& roundingRadii, RoundedRectStrategy = RoundedRectStrategy::PreferNative);
    WEBCORE_EXPORT void addRoundedRect(const FloatRoundedRect&, RoundedRectStrategy = RoundedRectStrategy::PreferNative);
    void addRoundedRect(const RoundedRect&);

    void addPath(const Path&, const AffineTransform&);

    void translate(const FloatSize&);

    // To keep Path() cheap, it does not allocate a PlatformPath immediately
    // meaning Path::platformPath() can return null.
#if USE(DIRECT2D)
    FloatRect fastBoundingRectForStroke(const PlatformContextDirect2D&) const;
    PlatformPathPtr platformPath() const { return m_path.get(); }
#elif USE(CG)
    WEBCORE_EXPORT PlatformPathPtr platformPath() const;
#elif USE(CAIRO)
    cairo_t* cairoPath() const { return m_path.get(); }
#else
    PlatformPathPtr platformPath() const { return m_path; }
#endif

#if !USE(CAIRO)
    // ensurePlatformPath() will allocate a PlatformPath if it has not yet been and will never return null.
    WEBCORE_EXPORT PlatformPathPtr ensurePlatformPath();
#endif

    WEBCORE_EXPORT void apply(const PathApplierFunction&) const;
    void transform(const AffineTransform&);

    static float circleControlPoint()
    {
        // Approximation of control point positions on a bezier to simulate a quarter of a circle.
        // This is 1-kappa, where kappa = 4 * (sqrt(2) - 1) / 3
        return 0.447715;
    }

    void addBeziersForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);

#if USE(CG) || USE(DIRECT2D)
    void platformAddPathForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
#endif

#if USE(DIRECT2D)
    void appendGeometry(ID2D1Geometry*);
    void createGeometryWithFillMode(WindRule, COMPtr<ID2D1GeometryGroup>&) const;

    void openFigureAtCurrentPointIfNecessary();
    void closeAnyOpenGeometries(unsigned figureEndStyle) const;
    void clearGeometries();
#endif

#ifndef NDEBUG
    void dump() const;
#endif

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<Path> decode(Decoder&);

#if ENABLE(INLINE_PATH_DATA)
    template<typename DataType> const DataType& inlineData() const;
    InlinePathData inlineData() const { return m_inlineData; }
    template<typename DataType> bool hasInlineData() const;
    bool hasInlineData() const;
#endif

private:
#if ENABLE(INLINE_PATH_DATA)
    template<typename DataType> DataType& inlineData();
    std::optional<FloatRect> fastBoundingRectFromInlineData() const;
    std::optional<FloatRect> boundingRectFromInlineData() const;
#endif

    void moveToSlowCase(const FloatPoint&);
    void addLineToSlowCase(const FloatPoint&);
    void addArcSlowCase(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
    void addQuadCurveToSlowCase(const FloatPoint& controlPoint, const FloatPoint& endPoint);
    void addBezierCurveToSlowCase(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);

    FloatRect boundingRectSlowCase() const;
    FloatRect fastBoundingRectSlowCase() const;
    bool isEmptySlowCase() const;
    FloatPoint currentPointSlowCase() const;
    size_t elementCountSlowCase() const;
    void applySlowCase(const PathApplierFunction&) const;

#if USE(CG)
    void createCGPath() const;
    void swap(Path&);
#endif

#if USE(CAIRO)
    cairo_t* ensureCairoPath();
    void appendElement(PathElement::Type, Vector<FloatPoint, 3>&&);
#endif

#if USE(CAIRO)
    RefPtr<cairo_t> m_path;
#else
    mutable PlatformPathStorageType m_path;
#endif

#if USE(DIRECT2D)
    Vector<ID2D1Geometry*> m_geometries;
    mutable COMPtr<ID2D1GeometrySink> m_activePath;
    mutable bool m_figureIsOpened { false };
#endif

#if ENABLE(INLINE_PATH_DATA)
    InlinePathData m_inlineData;
#endif
#if USE(CG)
    mutable bool m_copyPathBeforeMutation { false };
#endif
#if USE(CAIRO)
    std::optional<Vector<PathElement>> m_elements;
#endif
};

WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const Path&);

template<class Encoder> void Path::encode(Encoder& encoder) const
{
#if ENABLE(INLINE_PATH_DATA)
    bool hasInlineData = this->hasInlineData();
    encoder << hasInlineData;
    if (hasInlineData) {
        encoder << m_inlineData;
        return;
    }
#endif

    encoder << static_cast<uint64_t>(elementCount());

    apply([&](auto& element) {
        encoder << element.type;

        switch (element.type) {
        case PathElement::Type::MoveToPoint:
            encoder << element.points[0];
            break;
        case PathElement::Type::AddLineToPoint:
            encoder << element.points[0];
            break;
        case PathElement::Type::AddQuadCurveToPoint:
            encoder << element.points[0];
            encoder << element.points[1];
            break;
        case PathElement::Type::AddCurveToPoint:
            encoder << element.points[0];
            encoder << element.points[1];
            encoder << element.points[2];
            break;
        case PathElement::Type::CloseSubpath:
            break;
        }
    });
}

template<class Decoder> std::optional<Path> Path::decode(Decoder& decoder)
{
    Path path;

#if ENABLE(INLINE_PATH_DATA)
    bool hasInlineData;
    if (!decoder.decode(hasInlineData))
        return std::nullopt;

    if (hasInlineData) {
        if (!decoder.decode(path.m_inlineData))
            return std::nullopt;

        return path;
    }
#endif

    uint64_t numPoints;
    if (!decoder.decode(numPoints))
        return std::nullopt;

    path.clear();

    for (uint64_t i = 0; i < numPoints; ++i) {
        PathElement::Type elementType;
        if (!decoder.decode(elementType))
            return std::nullopt;

        switch (elementType) {
        case PathElement::Type::MoveToPoint: {
            FloatPoint point;
            if (!decoder.decode(point))
                return std::nullopt;
            path.moveTo(point);
            break;
        }
        case PathElement::Type::AddLineToPoint: {
            FloatPoint point;
            if (!decoder.decode(point))
                return std::nullopt;
            path.addLineTo(point);
            break;
        }
        case PathElement::Type::AddQuadCurveToPoint: {
            FloatPoint controlPoint;
            if (!decoder.decode(controlPoint))
                return std::nullopt;

            FloatPoint endPoint;
            if (!decoder.decode(endPoint))
                return std::nullopt;

            path.addQuadCurveTo(controlPoint, endPoint);
            break;
        }
        case PathElement::Type::AddCurveToPoint: {
            FloatPoint controlPoint1;
            if (!decoder.decode(controlPoint1))
                return std::nullopt;

            FloatPoint controlPoint2;
            if (!decoder.decode(controlPoint2))
                return std::nullopt;

            FloatPoint endPoint;
            if (!decoder.decode(endPoint))
                return std::nullopt;

            path.addBezierCurveTo(controlPoint1, controlPoint2, endPoint);
            break;
        }
        case PathElement::Type::CloseSubpath:
            path.closeSubpath();
            break;
        }
    }

    return path;
}

#if ENABLE(INLINE_PATH_DATA)

template <typename DataType> inline bool Path::hasInlineData() const
{
    return std::holds_alternative<DataType>(m_inlineData);
}

template<typename DataType> inline const DataType& Path::inlineData() const
{
    return std::get<DataType>(m_inlineData);
}

template<typename DataType> inline DataType& Path::inlineData()
{
    return std::get<DataType>(m_inlineData);
}

inline bool Path::hasInlineData() const
{
    return !hasInlineData<std::monostate>();
}

#endif

} // namespace WebCore

namespace WTF {

template<> struct EnumTraits<WebCore::PathElement::Type> {
    using values = EnumValues<
        WebCore::PathElement::Type,
        WebCore::PathElement::Type::MoveToPoint,
        WebCore::PathElement::Type::AddLineToPoint,
        WebCore::PathElement::Type::AddQuadCurveToPoint,
        WebCore::PathElement::Type::AddCurveToPoint,
        WebCore::PathElement::Type::CloseSubpath
    >;
};

} // namespace WTF
