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

#include "include/core/SkTypes.h"

#if defined(SK_GANESH)
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathEffect.h"
#include "include/effects/SkDashPathEffect.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/base/SkTPin.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/ops/QuadPerEdgeAA.h"
#include "tools/viewer/ClickHandlerSlide.h"

using VertexSpec = skgpu::ganesh::QuadPerEdgeAA::VertexSpec;
using ColorType = skgpu::ganesh::QuadPerEdgeAA::ColorType;
using Subset = skgpu::ganesh::QuadPerEdgeAA::Subset;
using IndexBufferOption = skgpu::ganesh::QuadPerEdgeAA::IndexBufferOption;

// Draw a line through the two points, outset by a fixed length in screen space
static void draw_extended_line(SkCanvas* canvas, const SkPaint& paint,
                               const SkPoint& p0, const SkPoint& p1) {
    SkVector v = p1 - p0;
    v.setLength(v.length() + 3.f);
    canvas->drawLine(p1 - v, p0 + v, paint);

    // Draw normal vector too
    SkPaint normalPaint = paint;
    normalPaint.setPathEffect(nullptr);
    normalPaint.setStrokeWidth(paint.getStrokeWidth() / 4.f);

    SkVector n = {v.fY, -v.fX};
    n.setLength(.25f);
    SkPoint m = (p0 + p1) * 0.5f;
    canvas->drawLine(m, m + n, normalPaint);
}

static void make_aa_line(const SkPoint& p0, const SkPoint& p1, bool aaOn,
                         bool outset, SkPoint line[2]) {
    SkVector n = {0.f, 0.f};
    if (aaOn) {
        SkVector v = p1 - p0;
        n = outset ? SkVector::Make(v.fY, -v.fX) : SkVector::Make(-v.fY, v.fX);
        n.setLength(0.5f);
    }

    line[0] = p0 + n;
    line[1] = p1 + n;
}

// To the line through l0-l1, not capped at the end points of the segment
static SkScalar signed_distance(const SkPoint& p, const SkPoint& l0, const SkPoint& l1) {
    SkVector v = l1 - l0;
    v.normalize();
    SkVector n = {v.fY, -v.fX};
    SkScalar c = -n.dot(l0);
    return n.dot(p) + c;
}

static SkScalar get_area_coverage(SkSpan<const bool> edgeAA, SkSpan<const SkPoint> corners, SkPoint point) {
    SkASSERT(corners.size() == 4);
    SkASSERT(edgeAA.size() == 4);

    SkPath shape = SkPath::Polygon(corners, true);
    SkPath pixel = SkPath::Rect(SkRect::MakeXYWH(point.fX - 0.5f, point.fY - 0.5f, 1.f, 1.f));

    auto intersection = Op(shape, pixel, kIntersect_SkPathOp);
    if (!intersection.has_value() || intersection->isEmpty()) {
        return 0.f;
    }

    // Calculate area of the convex polygon
    SkSpan<const SkPoint> pts = intersection->points();
    SkScalar area = 0.f;
    for (size_t i = 0; i < pts.size(); ++i) {
        SkPoint p0 = pts[i];
        SkPoint p1 = pts[(i + 1) % pts.size()];
        SkScalar det = p0.fX * p1.fY - p1.fX * p0.fY;
        area += det;
    }

    // Scale by 1/2, then take abs value (this area formula is signed based on point winding, but
    // since it's convex, just make it positive).
    area = SkScalarAbs(0.5f * area);

    // Now account for the edge AA. If the pixel center is outside of a non-AA edge, turn of its
    // coverage. If the pixel only intersects non-AA edges, then set coverage to 1.
    bool needsNonAA = false;
    SkScalar edgeD[4];
    for (int i = 0; i < 4; ++i) {
        SkPoint e0 = corners[i];
        SkPoint e1 = corners[(i + 1) % 4];
        edgeD[i] = -signed_distance(point, e0, e1);
        if (!edgeAA[i]) {
            if (edgeD[i] < -1e-4f) {
                return 0.f; // Outside of non-AA line
            }
            needsNonAA = true;
        }
    }
    // Otherwise inside the shape, so check if any AA edge exerts influence over nonAA
    if (needsNonAA) {
        for (int i = 0; i < 4; i++) {
            if (edgeAA[i] && edgeD[i] < 0.5f) {
                needsNonAA = false;
                break;
            }
        }
    }
    return needsNonAA ? 1.f : area;
}

// FIXME take into account max coverage properly,
static SkScalar get_edge_dist_coverage(SkSpan<const bool> edgeAA, SkSpan<const SkPoint> corners,
                                       SkSpan<const SkPoint> outsetLines,
                                       SkSpan<const SkPoint> insetLines,
                                       SkPoint point) {
    SkASSERT(edgeAA.size() == 4);
    SkASSERT(corners.size() == 4);
    SkASSERT(outsetLines.size() == 8);
    SkASSERT(insetLines.size() == 8);

    bool flip = false;
    // If the quad has been inverted, the original corners will not all be on the negative side of
    // every outset line. When that happens, calculate coverage using the "inset" lines and flip
    // the signed distance
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            SkScalar d = signed_distance(corners[i], outsetLines[j * 2], outsetLines[j * 2 + 1]);
            if (d > 1e-4f) {
                flip = true;
                break;
            }
        }
        if (flip) {
            break;
        }
    }

    const SkPoint* lines = flip ? insetLines.data() : outsetLines.data();

    SkScalar minCoverage = 1.f;
    for (int i = 0; i < 4; ++i) {
        // Multiply by negative 1 so that outside points have negative distances
        SkScalar d = (flip ? 1 : -1) * signed_distance(point, lines[i * 2], lines[i * 2 + 1]);
        if (!edgeAA[i] && d >= -1e-4f) {
            d = 1.f;
        }
        if (d < minCoverage) {
            minCoverage = d;
            if (minCoverage < 0.f) {
                break; // Outside the shape
            }
        }
    }
    return minCoverage < 0.f ? 0.f : minCoverage;
}

static bool inside_triangle(const SkPoint& point, const SkPoint& t0, const SkPoint& t1,
                            const SkPoint& t2, SkScalar bary[3]) {
    // Check sign of t0 to (t1,t2). If it is positive, that means the normals point into the
    // triangle otherwise the normals point outside the triangle so update edge distances as
    // necessary
    bool flip = signed_distance(t0, t1, t2) < 0.f;

    SkScalar d0 = (flip ? -1 : 1) * signed_distance(point, t0, t1);
    SkScalar d1 = (flip ? -1 : 1) * signed_distance(point, t1, t2);
    SkScalar d2 = (flip ? -1 : 1) * signed_distance(point, t2, t0);
    // Be a little forgiving
    if (d0 < -1e-4f || d1 < -1e-4f || d2 < -1e-4f) {
        return false;
    }

    // Inside, so calculate barycentric coords from the sideline distances
    SkScalar d01 = (t0 - t1).length();
    SkScalar d12 = (t1 - t2).length();
    SkScalar d20 = (t2 - t0).length();

    if (SkScalarNearlyZero(d12) || SkScalarNearlyZero(d20) || SkScalarNearlyZero(d01)) {
        // Empty degenerate triangle
        return false;
    }

    // Coordinates for a vertex use distances to the opposite edge
    bary[0] = d1 * d12;
    bary[1] = d2 * d20;
    bary[2] = d0 * d01;
    // And normalize
    SkScalar sum = bary[0] + bary[1] + bary[2];
    bary[0] /= sum;
    bary[1] /= sum;
    bary[2] /= sum;

    return true;
}

static SkScalar get_framed_coverage(const SkPoint outer[4], const SkScalar outerCoverages[4],
                                    const SkPoint inner[4], const SkScalar innerCoverages[4],
                                    const SkRect& geomDomain, const SkPoint& point) {
    // Triangles are ordered clock wise. Indices >= 4 refer to inner[i - 4]. Otherwise its outer[i].
    static const int kFrameTris[] = {
        0, 1, 4,   4, 1, 5,
        1, 2, 5,   5, 2, 6,
        2, 3, 6,   6, 3, 7,
        3, 0, 7,   7, 0, 4,
        4, 5, 7,   7, 5, 6
    };
    static const int kNumTris = 10;

    SkScalar bary[3];
    for (int i = 0; i < kNumTris; ++i) {
        int i0 = kFrameTris[i * 3];
        int i1 = kFrameTris[i * 3 + 1];
        int i2 = kFrameTris[i * 3 + 2];

        SkPoint t0 = i0 >= 4 ? inner[i0 - 4] : outer[i0];
        SkPoint t1 = i1 >= 4 ? inner[i1 - 4] : outer[i1];
        SkPoint t2 = i2 >= 4 ? inner[i2 - 4] : outer[i2];
        if (inside_triangle(point, t0, t1, t2, bary)) {
            // Calculate coverage by barycentric interpolation of coverages
            SkScalar c0 = i0 >= 4 ? innerCoverages[i0 - 4] : outerCoverages[i0];
            SkScalar c1 = i1 >= 4 ? innerCoverages[i1 - 4] : outerCoverages[i1];
            SkScalar c2 = i2 >= 4 ? innerCoverages[i2 - 4] : outerCoverages[i2];

            SkScalar coverage = bary[0] * c0 + bary[1] * c1 + bary[2] * c2;
            if (coverage < 0.5f) {
                // Check distances to domain
                SkScalar l = SkTPin(point.fX - geomDomain.fLeft, 0.f, 1.f);
                SkScalar t = SkTPin(point.fY - geomDomain.fTop, 0.f, 1.f);
                SkScalar r = SkTPin(geomDomain.fRight - point.fX, 0.f, 1.f);
                SkScalar b = SkTPin(geomDomain.fBottom - point.fY, 0.f, 1.f);
                coverage = std::min(coverage, l * t * r * b);
            }
            return coverage;
        }
    }
    // Not inside any triangle
    return 0.f;
}

static constexpr SkScalar kViewScale = 100.f;
static constexpr SkScalar kViewOffset = 200.f;

class DegenerateQuadSlide : public ClickHandlerSlide {
public:
    DegenerateQuadSlide(const SkRect& rect)
            : fOuterRect(rect)
            , fCoverageMode(CoverageMode::kArea) {
        fCorners = fOuterRect.toQuad();
        for (int i = 0; i < 4; ++i) {
            fEdgeAA[i] = true;
        }
        fName = "DegenerateQuad";
    }

    void draw(SkCanvas* canvas) override {
        static const SkScalar kDotParams[2] = {1.f / kViewScale, 12.f / kViewScale};
        sk_sp<SkPathEffect> dots = SkDashPathEffect::Make(kDotParams, 0.f);
        static const SkScalar kDashParams[2] = {8.f / kViewScale, 12.f / kViewScale};
        sk_sp<SkPathEffect> dashes = SkDashPathEffect::Make(kDashParams, 0.f);

        SkPaint circlePaint;
        circlePaint.setAntiAlias(true);

        SkPaint linePaint;
        linePaint.setAntiAlias(true);
        linePaint.setStyle(SkPaint::kStroke_Style);
        linePaint.setStrokeWidth(4.f / kViewScale);
        linePaint.setStrokeJoin(SkPaint::kRound_Join);
        linePaint.setStrokeCap(SkPaint::kRound_Cap);

        canvas->translate(kViewOffset, kViewOffset);
        canvas->scale(kViewScale, kViewScale);

        // Draw the outer rectangle as a dotted line
        linePaint.setPathEffect(dots);
        canvas->drawRect(fOuterRect, linePaint);

        bool valid = this->isValid();

        if (valid) {
            SkPoint outsets[8];
            SkPoint insets[8];
            // Calculate inset and outset lines for edge-distance visualization
            for (int i = 0; i < 4; ++i) {
                make_aa_line(fCorners[i], fCorners[(i + 1) % 4], fEdgeAA[i], true, outsets + i * 2);
                make_aa_line(fCorners[i], fCorners[(i + 1) % 4], fEdgeAA[i], false, insets + i * 2);
            }

            // Calculate inner and outer meshes for GPU visualization
            SkPoint gpuOutset[4];
            SkScalar gpuOutsetCoverage[4];
            SkPoint gpuInset[4];
            SkScalar gpuInsetCoverage[4];
            SkRect gpuDomain;
            this->getTessellatedPoints(gpuInset, gpuInsetCoverage, gpuOutset, gpuOutsetCoverage,
                                       &gpuDomain);

            // Visualize the coverage values across the clamping rectangle, but test pixels outside
            // of the "outer" rect since some quad edges can be outset extra far.
            SkPaint pixelPaint;
            pixelPaint.setAntiAlias(true);
            SkRect covRect = fOuterRect.makeOutset(2.f, 2.f);
            for (SkScalar py = covRect.fTop; py < covRect.fBottom; py += 1.f) {
                for (SkScalar px = covRect.fLeft; px < covRect.fRight; px += 1.f) {
                    // px and py are the top-left corner of the current pixel, so get center's
                    // coordinate
                    SkPoint pixelCenter = {px + 0.5f, py + 0.5f};
                    SkScalar coverage;
                    if (fCoverageMode == CoverageMode::kArea) {
                        coverage = get_area_coverage(fEdgeAA, fCorners, pixelCenter);
                    } else if (fCoverageMode == CoverageMode::kEdgeDistance) {
                        coverage = get_edge_dist_coverage(fEdgeAA, fCorners, outsets, insets,
                                                          pixelCenter);
                    } else {
                        SkASSERT(fCoverageMode == CoverageMode::kGPUMesh);
                        coverage = get_framed_coverage(gpuOutset, gpuOutsetCoverage,
                                                       gpuInset, gpuInsetCoverage, gpuDomain,
                                                       pixelCenter);
                    }

                    SkRect pixelRect = SkRect::MakeXYWH(px, py, 1.f, 1.f);
                    pixelRect.inset(0.1f, 0.1f);

                    SkScalar a = 1.f - 0.5f * coverage;
                    pixelPaint.setColor4f({a, a, a, 1.f}, nullptr);
                    canvas->drawRect(pixelRect, pixelPaint);

                    pixelPaint.setColor(coverage > 0.f ? SK_ColorGREEN : SK_ColorRED);
                    pixelRect.inset(0.38f, 0.38f);
                    canvas->drawRect(pixelRect, pixelPaint);
                }
            }

            linePaint.setPathEffect(dashes);
            // Draw the inset/outset "infinite" lines
            if (fCoverageMode == CoverageMode::kEdgeDistance) {
                for (int i = 0; i < 4; ++i) {
                    if (fEdgeAA[i]) {
                        linePaint.setColor(SK_ColorBLUE);
                        draw_extended_line(canvas, linePaint, outsets[i * 2], outsets[i * 2 + 1]);
                        linePaint.setColor(SK_ColorGREEN);
                        draw_extended_line(canvas, linePaint, insets[i * 2], insets[i * 2 + 1]);
                    } else {
                        // Both outset and inset are the same line, so only draw one in cyan
                        linePaint.setColor(SK_ColorCYAN);
                        draw_extended_line(canvas, linePaint, outsets[i * 2], outsets[i * 2 + 1]);
                    }
                }
            }

            linePaint.setPathEffect(nullptr);
            // What is tessellated using GrQuadPerEdgeAA
            if (fCoverageMode == CoverageMode::kGPUMesh) {
                SkPath outsetPath = SkPath::Polygon({gpuOutset, 4}, true);
                linePaint.setColor(SK_ColorBLUE);
                canvas->drawPath(outsetPath, linePaint);

                SkPath insetPath = SkPath::Polygon({gpuInset, 4}, true);
                linePaint.setColor(SK_ColorGREEN);
                canvas->drawPath(insetPath, linePaint);

                SkPaint domainPaint = linePaint;
                domainPaint.setStrokeWidth(2.f / kViewScale);
                domainPaint.setPathEffect(dashes);
                domainPaint.setColor(SK_ColorMAGENTA);
                canvas->drawRect(gpuDomain, domainPaint);
            }

            // Draw the edges of the true quad as a solid line
            SkPath path = SkPath::Polygon(fCorners, true);
            linePaint.setColor(SK_ColorBLACK);
            canvas->drawPath(path, linePaint);
        } else {
            // Draw the edges of the true quad as a solid *red* line
            SkPath path = SkPath::Polygon(fCorners, true);
            linePaint.setColor(SK_ColorRED);
            linePaint.setPathEffect(nullptr);
            canvas->drawPath(path, linePaint);
        }

        // Draw the four clickable corners as circles
        circlePaint.setColor(valid ? SK_ColorBLACK : SK_ColorRED);
        for (int i = 0; i < 4; ++i) {
            canvas->drawCircle(fCorners[i], 5.f / kViewScale, circlePaint);
        }
    }

    bool onChar(SkUnichar) override;


protected:
    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
    bool onClick(Click*) override;

private:
    class Click;

    enum class CoverageMode {
        kArea, kEdgeDistance, kGPUMesh
    };

    const SkRect fOuterRect;
    std::array<SkPoint, 4> fCorners; // in toQuad() order TL, TR, BR, BL
    bool fEdgeAA[4]; // T, R, B, L
    CoverageMode fCoverageMode;

    bool isValid() const {
        SkPath path = SkPath::Polygon(fCorners, true);
        return path.isConvex(); // todo: should we expose this as a helper (sans Path object)
    }

    void getTessellatedPoints(SkPoint inset[4], SkScalar insetCoverage[4], SkPoint outset[4],
                              SkScalar outsetCoverage[4], SkRect* domain) const {
        // Fixed vertex spec for extracting the picture frame geometry
        static const VertexSpec kSpec =
            {GrQuad::Type::kGeneral, ColorType::kNone,
             GrQuad::Type::kAxisAligned, false, Subset::kNo,
             GrAAType::kCoverage, false, IndexBufferOption::kPictureFramed};
        static const GrQuad kIgnored(SkRect::MakeEmpty());

        GrQuadAAFlags flags = GrQuadAAFlags::kNone;
        flags |= fEdgeAA[0] ? GrQuadAAFlags::kTop : GrQuadAAFlags::kNone;
        flags |= fEdgeAA[1] ? GrQuadAAFlags::kRight : GrQuadAAFlags::kNone;
        flags |= fEdgeAA[2] ? GrQuadAAFlags::kBottom : GrQuadAAFlags::kNone;
        flags |= fEdgeAA[3] ? GrQuadAAFlags::kLeft : GrQuadAAFlags::kNone;

        GrQuad quad = GrQuad::MakeFromSkQuad(fCorners.data(), SkMatrix::I());

        float vertices[56]; // 2 quads, with x, y, coverage, and geometry domain (7 floats x 8 vert)
        skgpu::ganesh::QuadPerEdgeAA::Tessellator tessellator(kSpec, (char*)vertices);
        tessellator.append(&quad, nullptr, {1.f, 1.f, 1.f, 1.f},
                           SkRect::MakeEmpty(), flags);

        // The first quad in vertices is the inset, then the outset, but they
        // are ordered TL, BL, TR, BR so un-interleave coverage and re-arrange
        inset[0] = {vertices[0], vertices[1]}; // TL
        insetCoverage[0] = vertices[2];
        inset[3] = {vertices[7], vertices[8]}; // BL
        insetCoverage[3] = vertices[9];
        inset[1] = {vertices[14], vertices[15]}; // TR
        insetCoverage[1] = vertices[16];
        inset[2] = {vertices[21], vertices[22]}; // BR
        insetCoverage[2] = vertices[23];

        outset[0] = {vertices[28], vertices[29]}; // TL
        outsetCoverage[0] = vertices[30];
        outset[3] = {vertices[35], vertices[36]}; // BL
        outsetCoverage[3] = vertices[37];
        outset[1] = {vertices[42], vertices[43]}; // TR
        outsetCoverage[1] = vertices[44];
        outset[2] = {vertices[49], vertices[50]}; // BR
        outsetCoverage[2] = vertices[51];

        *domain = {vertices[52], vertices[53], vertices[54], vertices[55]};
    }
};

class DegenerateQuadSlide::Click : public ClickHandlerSlide::Click {
public:
    Click(const SkRect& clamp, int index)
            : fOuterRect(clamp)
            , fIndex(index) {}

    void doClick(SkSpan<SkPoint> points) {
        SkASSERT(points.size() == 4);
        if (fIndex >= 0) {
            this->drag(&points[fIndex]);
        } else {
            for (int i = 0; i < 4; ++i) {
                this->drag(&points[i]);
            }
        }
    }

private:
    SkRect fOuterRect;
    int fIndex;

    void drag(SkPoint* point) {
        SkPoint delta = fCurr - fPrev;
        *point += SkPoint::Make(delta.x() / kViewScale, delta.y() / kViewScale);
        point->fX = std::min(fOuterRect.fRight, std::max(point->fX, fOuterRect.fLeft));
        point->fY = std::min(fOuterRect.fBottom, std::max(point->fY, fOuterRect.fTop));
    }
};

ClickHandlerSlide::Click* DegenerateQuadSlide::onFindClickHandler(SkScalar x, SkScalar y,
                                                                  skui::ModifierKey) {
    SkPoint inCTM = SkPoint::Make((x - kViewOffset) / kViewScale, (y - kViewOffset) / kViewScale);
    for (int i = 0; i < 4; ++i) {
        if ((fCorners[i] - inCTM).length() < 10.f / kViewScale) {
            return new Click(fOuterRect, i);
        }
    }
    return new Click(fOuterRect, -1);
}

bool DegenerateQuadSlide::onClick(ClickHandlerSlide::Click* click) {
    Click* myClick = (Click*) click;
    myClick->doClick(fCorners);
    return true;
}

bool DegenerateQuadSlide::onChar(SkUnichar code) {
        switch(code) {
            case '1':
                fEdgeAA[0] = !fEdgeAA[0];
                return true;
            case '2':
                fEdgeAA[1] = !fEdgeAA[1];
                return true;
            case '3':
                fEdgeAA[2] = !fEdgeAA[2];
                return true;
            case '4':
                fEdgeAA[3] = !fEdgeAA[3];
                return true;
            case 'q':
                fCoverageMode = CoverageMode::kArea;
                return true;
            case 'w':
                fCoverageMode = CoverageMode::kEdgeDistance;
                return true;
            case 'e':
                fCoverageMode = CoverageMode::kGPUMesh;
                return true;
        }
        return false;
}

DEF_SLIDE(return new DegenerateQuadSlide(SkRect::MakeWH(4.f, 4.f));)

#endif  // SK_GANESH
