/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/ganesh/geometry/GrShape.h"

#include "include/core/SkArc.h"
#include "include/core/SkScalar.h"
#include "src/core/SkPathPriv.h"
#include "src/core/SkRRectPriv.h"

#include <algorithm>

GrShape& GrShape::operator=(const GrShape& shape) {
    switch (shape.type()) {
        case Type::kEmpty:
            this->reset();
            break;
        case Type::kPoint:
            this->setPoint(shape.fPoint);
            break;
        case Type::kRect:
            this->setRect(shape.fRect);
            break;
        case Type::kRRect:
            this->setRRect(shape.fRRect);
            break;
        case Type::kPath:
            this->setPath(shape.fPath);
            break;
        case Type::kArc:
            this->setArc(shape.fArc);
            break;
        case Type::kLine:
            this->setLine(shape.fLine);
            break;
    }

    fStart = shape.fStart;
    fCW = shape.fCW;
    fInverted = shape.fInverted;

    return *this;
}

uint32_t GrShape::stateKey() const {
    // Use the path's full fill type instead of just whether or not it's inverted.
    uint32_t key = this->isPath() ? static_cast<uint32_t>(fPath.getFillType())
                                  : (fInverted ? 1 : 0);
    key |= ((uint32_t) fType) << 2; // fill type was 2 bits
    key |= fStart             << 5; // type was 3 bits, total 5 bits so far
    key |= (fCW ? 1 : 0)      << 8; // start was 3 bits, total 8 bits so far
    return key;
}

bool GrShape::simplifyPath(unsigned flags) {
    SkASSERT(this->isPath());

    SkPoint pts[2];

    if (fPath.isEmpty()) {
        this->setType(Type::kEmpty);
        return false;
    }
    if (fPath.isLine(pts)) {
        this->simplifyLine(pts[0], pts[1], flags);
        return false;
    }
    if (auto info = SkPathPriv::IsRRect(fPath)) {
        this->simplifyRRect(info->fRRect, info->fDirection, info->fStartIndex, flags);
        return true;
    }
    if (auto info = SkPathPriv::IsOval(fPath)) {
        // Convert to rrect indexing since oval is not represented explicitly
        this->simplifyRRect(SkRRect::MakeOval(info->fBounds),
                            info->fDirection, info->fStartIndex * 2, flags);
        return true;
    }
    if (auto info = SkPathPriv::IsSimpleRect(fPath, (flags & kSimpleFill_Flag))) {
        // When there is a path effect we restrict rect detection to the narrower API that
        // gives us the starting position. Otherwise, we will retry with the more aggressive
        // isRect().
        this->simplifyRect(info->fRect, info->fDirection, info->fStartIndex, flags);
        return true;
    }
    if (flags & kIgnoreWinding_Flag) {
        SkRect rect;
        // Attempt isRect() since we don't have to preserve any winding info
        bool closed;
        if (fPath.isRect(&rect, &closed) && (closed || (flags & kSimpleFill_Flag))) {
            this->simplifyRect(rect, kDefaultDir, kDefaultStart, flags);
            return true;
        }
    }
    // No further simplification for a path. For performance reasons, we don't query the path to
    // determine it was closed, as whether or not it was closed when it remains a path type is not
    // important for styling.
    return false;
}

bool GrShape::simplifyArc(unsigned flags) {
    SkASSERT(this->isArc());

    // Arcs can simplify to rrects, lines, points, or empty; regardless of what it simplifies to
    // it was closed if went through the center point.
    bool wasClosed = fArc.isWedge();
    if (fArc.fOval.isEmpty() || !fArc.fSweepAngle) {
        if (flags & kSimpleFill_Flag) {
            // Go straight to empty, since the other degenerate shapes all have 0 area anyway.
            this->setType(Type::kEmpty);
        } else if (!fArc.fSweepAngle) {
            SkPoint center = {fArc.fOval.centerX(), fArc.fOval.centerY()};
            SkScalar startRad = SkDegreesToRadians(fArc.fStartAngle);
            SkPoint start = {center.fX + 0.5f * fArc.fOval.width() * SkScalarCos(startRad),
                                center.fY + 0.5f * fArc.fOval.height() * SkScalarSin(startRad)};
            // Either just the starting point, or a line from the center to the start
            if (fArc.isWedge()) {
                this->simplifyLine(center, start, flags);
             } else {
                this->simplifyPoint(start, flags);
             }
        } else {
            // TODO: Theoretically, we could analyze the arc projected into the empty bounds to
            // determine a line, but that is somewhat complex for little value (since the arc
            // can backtrack on itself if the sweep angle is large enough).
            this->setType(Type::kEmpty);
        }
    } else {
        if ((flags & kSimpleFill_Flag) ||
            ((flags & kIgnoreWinding_Flag) && !fArc.isWedge())) {
            // Eligible to turn into an oval if it sweeps a full circle
            if (fArc.fSweepAngle <= -360.f || fArc.fSweepAngle >= 360.f) {
                this->simplifyRRect(SkRRect::MakeOval(fArc.fOval),
                                    kDefaultDir, kDefaultStart, flags);
                return true;
            }
        }

        if (flags & kMakeCanonical_Flag) {
            // Map start to 0 to 360, sweep is always positive
            if (fArc.fSweepAngle < 0) {
                fArc.fStartAngle = fArc.fStartAngle + fArc.fSweepAngle;
                fArc.fSweepAngle = -fArc.fSweepAngle;
            }

            if (fArc.fStartAngle < 0 || fArc.fStartAngle >= 360.f) {
                fArc.fStartAngle = SkScalarMod(fArc.fStartAngle, 360.f);
            }
        }
    }

    return wasClosed;
}

void GrShape::simplifyRRect(const SkRRect& rrect, SkPathDirection dir, unsigned start,
                            unsigned flags) {
    if (rrect.isEmpty() || rrect.isRect()) {
        // Change index from rrect to rect
        start = ((start + 1) / 2) % 4;
        this->simplifyRect(rrect.rect(), dir, start, flags);
    } else if (!this->isRRect()) {
        this->setType(Type::kRRect);
        fRRect = rrect;
        this->setPathWindingParams(dir, start);
        // A round rect is already canonical, so there's nothing more to do
    } else {
        // If starting as a round rect, the provided rrect/winding params should be already set
        SkASSERT(fRRect == rrect && this->dir() == dir && this->startIndex() == start);
    }
}

void GrShape::simplifyRect(const SkRect& rect, SkPathDirection dir, unsigned start,
                           unsigned flags) {
    if (!rect.width() || !rect.height()) {
        if (flags & kSimpleFill_Flag) {
            // A zero area, filled shape so go straight to empty
            this->setType(Type::kEmpty);
        } else if (!rect.width() ^ !rect.height()) {
            // A line, choose the first point that best matches the starting index
            SkPoint p1 = {rect.fLeft, rect.fTop};
            SkPoint p2 = {rect.fRight, rect.fBottom};
            if (start >= 2 && !(flags & kIgnoreWinding_Flag)) {
                using std::swap;
                swap(p1, p2);
            }
            this->simplifyLine(p1, p2, flags);
        } else {
            // A point (all edges are equal, so start+dir doesn't affect choice)
            this->simplifyPoint({rect.fLeft, rect.fTop}, flags);
        }
    } else {
        if (!this->isRect()) {
            this->setType(Type::kRect);
            fRect = rect;
            this->setPathWindingParams(dir, start);
        } else {
            // If starting as a rect, the provided rect/winding params should already be set
            SkASSERT(fRect == rect);
            SkASSERT(this->dir() == dir);
            SkASSERT(this->startIndex() == start);
        }
        if (flags & kMakeCanonical_Flag) {
            fRect.sort();
        }
    }
}

void GrShape::simplifyLine(const SkPoint& p1, const SkPoint& p2, unsigned flags) {
    if (flags & kSimpleFill_Flag) {
        this->setType(Type::kEmpty);
    } else if (p1 == p2) {
        this->simplifyPoint(p1, false);
    } else {
        if (!this->isLine()) {
            this->setType(Type::kLine);
            fLine.fP1 = p1;
            fLine.fP2 = p2;
        } else {
            // If starting as a line, the provided points should already be set
            SkASSERT(fLine.fP1 == p1 && fLine.fP2 == p2);
        }
        if (flags & kMakeCanonical_Flag) {
             // Sort the end points
             if (fLine.fP2.fY < fLine.fP1.fY ||
                 (fLine.fP2.fY == fLine.fP1.fY && fLine.fP2.fX < fLine.fP1.fX)) {
                using std::swap;
                swap(fLine.fP1, fLine.fP2);
            }
        }
    }
}

void GrShape::simplifyPoint(const SkPoint& point, unsigned flags) {
    if (flags & kSimpleFill_Flag) {
        this->setType(Type::kEmpty);
    } else if (!this->isPoint()) {
        this->setType(Type::kPoint);
        fPoint = point;
    } else {
        // If starting as a point, the provided position should already be set
        SkASSERT(point == fPoint);
    }
}

bool GrShape::simplify(unsigned flags) {
    // Verify that winding parameters are valid for the current type.
    SkASSERT((fType == Type::kRect || fType == Type::kRRect) ||
             (this->dir() == kDefaultDir && this->startIndex() == kDefaultStart));

    // The type specific functions automatically fall through to the simpler shapes, so
    // we only need to start in the right place.
    bool wasClosed = false;
    switch (fType) {
        case Type::kEmpty:
            // do nothing
            break;
        case Type::kPoint:
            this->simplifyPoint(fPoint, flags);
            break;
        case Type::kLine:
            this->simplifyLine(fLine.fP1, fLine.fP2, flags);
            break;
        case Type::kRect:
            this->simplifyRect(fRect, this->dir(), this->startIndex(), flags);
            wasClosed = true;
            break;
        case Type::kRRect:
            this->simplifyRRect(fRRect, this->dir(), this->startIndex(), flags);
            wasClosed = true;
            break;
        case Type::kPath:
            wasClosed = this->simplifyPath(flags);
            break;
        case Type::kArc:
            wasClosed = this->simplifyArc(flags);
            break;

        default:
            SkUNREACHABLE;
    }

    if (((flags & kIgnoreWinding_Flag) || (fType != Type::kRect && fType != Type::kRRect))) {
        // Reset winding parameters if we don't need them anymore
        this->setPathWindingParams(kDefaultDir, kDefaultStart);
    }

    return wasClosed;
}

bool GrShape::conservativeContains(const SkRect& rect) const {
    switch (this->type()) {
        case Type::kEmpty:
        case Type::kPoint: // fall through since a point has 0 area
        case Type::kLine:  // fall through, "" (currently choosing not to test if 'rect' == line)
            return false;
        case Type::kRect:
            return fRect.contains(rect);
        case Type::kRRect:
            return fRRect.contains(rect);
        case Type::kPath:
            return fPath.conservativelyContainsRect(rect);
        case Type::kArc:
            if (fArc.fType == SkArc::Type::kWedge) {
                SkPath arc = this->asPath();
                return arc.conservativelyContainsRect(rect);
            } else {
                return false;
            }
    }
    SkUNREACHABLE;
}

bool GrShape::conservativeContains(const SkPoint& point) const {
    switch (this->type()) {
        case Type::kEmpty:
        case Type::kPoint: // fall through, currently choosing not to test if shape == point
        case Type::kLine:  // fall through, ""
        case Type::kArc:
            return false;
        case Type::kRect:
            return fRect.contains(point.fX, point.fY);
        case Type::kRRect:
            return SkRRectPriv::ContainsPoint(fRRect, point);
        case Type::kPath:
            return fPath.contains(point.fX, point.fY);
    }
    SkUNREACHABLE;
}

bool GrShape::closed() const {
    switch (this->type()) {
        case Type::kEmpty: // fall through
        case Type::kRect:  // fall through
        case Type::kRRect:
            return true;
        case Type::kPath:
            // SkPath doesn't keep track of the closed status of each contour.
            return SkPathPriv::IsClosedSingleContour(fPath);
        case Type::kArc:
            return fArc.fType == SkArc::Type::kWedge;
        case Type::kPoint: // fall through
        case Type::kLine:
            return false;
    }
    SkUNREACHABLE;
}

bool GrShape::convex(bool simpleFill) const {
    switch (this->type()) {
        case Type::kEmpty: // fall through
        case Type::kRect:  // fall through
        case Type::kRRect:
            return true;
        case Type::kPath:
            // SkPath.isConvex() really means "is this path convex were it to be closed".
            // Convex paths may only have one contour hence isLastContourClosed() is sufficient.
            return (simpleFill || fPath.isLastContourClosed()) && fPath.isConvex();
        case Type::kArc:
            return SkPathPriv::DrawArcIsConvex(fArc.fSweepAngle, fArc.fType, simpleFill);
        case Type::kPoint: // fall through
        case Type::kLine:
            return false;
    }
    SkUNREACHABLE;
}

SkRect GrShape::bounds() const {
    // Bounds where left == bottom or top == right can indicate a line or point shape. We return
    // inverted bounds for a truly empty shape.
    static constexpr SkRect kInverted = SkRect::MakeLTRB(1, 1, -1, -1);
    switch (this->type()) {
        case Type::kEmpty:
            return kInverted;
        case Type::kPoint:
            return {fPoint.fX, fPoint.fY, fPoint.fX, fPoint.fY};
        case Type::kRect:
            return fRect.makeSorted();
        case Type::kRRect:
            return fRRect.getBounds();
        case Type::kPath:
            return fPath.getBounds();
        case Type::kArc:
            return fArc.fOval;
        case Type::kLine: {
            SkRect b = SkRect::MakeLTRB(fLine.fP1.fX, fLine.fP1.fY,
                                        fLine.fP2.fX, fLine.fP2.fY);
            b.sort();
            return b; }
    }
    SkUNREACHABLE;
}

uint32_t GrShape::segmentMask() const {
    // In order to match what a path would report, this has to inspect the shapes slightly
    // to reflect what they might simplify to.
    switch (this->type()) {
        case Type::kEmpty:
            return 0;
        case Type::kRRect:
            if (fRRect.isEmpty() || fRRect.isRect()) {
                return SkPath::kLine_SegmentMask;
            } else if (fRRect.isOval()) {
                return SkPath::kConic_SegmentMask;
            } else {
                return SkPath::kConic_SegmentMask | SkPath::kLine_SegmentMask;
            }
        case Type::kPath:
            return fPath.getSegmentMasks();
        case Type::kArc:
            if (fArc.fType == SkArc::Type::kWedge) {
                return SkPath::kConic_SegmentMask | SkPath::kLine_SegmentMask;
            } else {
                return SkPath::kConic_SegmentMask;
            }
        case Type::kPoint: // fall through
        case Type::kLine:  // ""
        case Type::kRect:
            return SkPath::kLine_SegmentMask;
    }
    SkUNREACHABLE;
}

SkPath GrShape::asPath(bool simpleFill) const {
    SkPathBuilder builder;
    if (!this->isPath() && !this->isArc()) {
        // When not a path, we need to set fill type on the path to match invertedness.
        // All the non-path geometries produce equivalent shapes with either even-odd or winding
        // so we can use the default fill type.
        builder.setFillType(kDefaultFillType);
        if (fInverted) {
            builder.toggleInverseFillType();
        }
    } // Else when we're already a path, that will assign the fill type directly to 'out'.

    switch (this->type()) {
        case Type::kEmpty:
            break;
        case Type::kPoint:
            // A plain moveTo() or moveTo+close() does not match the expected path for a
            // point that is being dashed (see SkDashPath's handling of zero-length segments).
            builder.moveTo(fPoint);
            builder.lineTo(fPoint);
            break;
        case Type::kRect:
            builder.addRect(fRect, this->dir(), this->startIndex());
            break;
        case Type::kRRect:
            builder.addRRect(fRRect, this->dir(), this->startIndex());
            break;
        case Type::kPath:
            return fPath;
        case Type::kArc: {
            SkPath path = SkPathPriv::CreateDrawArcPath(fArc, simpleFill);
            // CreateDrawArcPath configures its fill type, so we just
            // have to ensure invertedness is correct.
            if (fInverted) {
                path.toggleInverseFillType();
            }
            return path;
        }
        case Type::kLine:
            builder.moveTo(fLine.fP1);
            builder.lineTo(fLine.fP2);
            break;
    }
    return builder.detach();
}
