/*
 * 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 "src/core/SkPathPriv.h"
#include "src/core/SkRRectPriv.h"

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());

    SkRect rect;
    SkRRect rrect;
    SkPoint pts[2];

    SkPathDirection dir;
    unsigned start;

    if (fPath.isEmpty()) {
        this->setType(Type::kEmpty);
        return false;
    } else if (fPath.isLine(pts)) {
        this->simplifyLine(pts[0], pts[1], flags);
        return false;
    } else if (SkPathPriv::IsRRect(fPath, &rrect, &dir, &start)) {
        this->simplifyRRect(rrect, dir, start, flags);
        return true;
    } else if (SkPathPriv::IsOval(fPath, &rect, &dir, &start)) {
        // Convert to rrect indexing since oval is not represented explicitly
        this->simplifyRRect(SkRRect::MakeOval(rect), dir, start * 2, flags);
        return true;
    } else if (SkPathPriv::IsSimpleRect(fPath, (flags & kSimpleFill_Flag), &rect, &dir, &start)) {
        // 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(rect, dir, start, flags);
        return true;
    } else if (flags & kIgnoreWinding_Flag) {
        // 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.fUseCenter;
    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.fUseCenter) {
                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.fUseCenter)) {
             // 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 && this->dir() == dir && 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.fUseCenter) {
                SkPath arc;
                this->asPath(&arc);
                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.fUseCenter;
        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.fUseCenter, 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.fUseCenter) {
                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;
}

void GrShape::asPath(SkPath* out, bool simpleFill) const {
    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.
        out->reset();
        out->setFillType(kDefaultFillType);
        if (fInverted) {
            out->toggleInverseFillType();
        }
    } // Else when we're already a path, that will assign the fill type directly to 'out'.

    switch (this->type()) {
        case Type::kEmpty:
            return;
        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).
            out->moveTo(fPoint);
            out->lineTo(fPoint);
            return;
        case Type::kRect:
            out->addRect(fRect, this->dir(), this->startIndex());
            return;
        case Type::kRRect:
            out->addRRect(fRRect, this->dir(), this->startIndex());
            return;
        case Type::kPath:
            *out = fPath;
            return;
        case Type::kArc:
            SkPathPriv::CreateDrawArcPath(out, fArc.fOval, fArc.fStartAngle, fArc.fSweepAngle,
                                          fArc.fUseCenter, simpleFill);
            // CreateDrawArcPath resets the output path and configures its fill type, so we just
            // have to ensure invertedness is correct.
            if (fInverted) {
                out->toggleInverseFillType();
            }
            return;
        case Type::kLine:
            out->moveTo(fLine.fP1);
            out->lineTo(fLine.fP2);
            return;
    }
    SkUNREACHABLE;
}
