/*
 * 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 "samplecode/Sample.h"

#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/ops/QuadPerEdgeAA.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/effects/SkDashPathEffect.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/SkTPin.h"

using VertexSpec = skgpu::v1::QuadPerEdgeAA::VertexSpec;
using ColorType = skgpu::v1::QuadPerEdgeAA::ColorType;
using Subset = skgpu::v1::QuadPerEdgeAA::Subset;
using IndexBufferOption = skgpu::v1::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(const bool edgeAA[4], const SkPoint corners[4],
                                  const SkPoint& point) {
    SkPath shape;
    shape.addPoly(corners, 4, true);
    SkPath pixel;
    pixel.addRect(SkRect::MakeXYWH(point.fX - 0.5f, point.fY - 0.5f, 1.f, 1.f));

    SkPath intersection;
    if (!Op(shape, pixel, kIntersect_SkPathOp, &intersection) || intersection.isEmpty()) {
        return 0.f;
    }

    // Calculate area of the convex polygon
    SkScalar area = 0.f;
    for (int i = 0; i < intersection.countPoints(); ++i) {
        SkPoint p0 = intersection.getPoint(i);
        SkPoint p1 = intersection.getPoint((i + 1) % intersection.countPoints());
        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(const bool edgeAA[4], const SkPoint corners[4],
                                       const SkPoint outsetLines[8], const SkPoint insetLines[8],
                                       const SkPoint& point) {
    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 : outsetLines;

    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 DegenerateQuadSample : public Sample {
public:
    DegenerateQuadSample(const SkRect& rect)
            : fOuterRect(rect)
            , fCoverageMode(CoverageMode::kArea) {
        fOuterRect.toQuad(fCorners);
        for (int i = 0; i < 4; ++i) {
            fEdgeAA[i] = true;
        }
    }

    void onDrawContent(SkCanvas* canvas) override {
        static const SkScalar kDotParams[2] = {1.f / kViewScale, 12.f / kViewScale};
        sk_sp<SkPathEffect> dots = SkDashPathEffect::Make(kDotParams, 2, 0.f);
        static const SkScalar kDashParams[2] = {8.f / kViewScale, 12.f / kViewScale};
        sk_sp<SkPathEffect> dashes = SkDashPathEffect::Make(kDashParams, 2, 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;
                outsetPath.addPoly(gpuOutset, 4, true);
                linePaint.setColor(SK_ColorBLUE);
                canvas->drawPath(outsetPath, linePaint);

                SkPath insetPath;
                insetPath.addPoly(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;
            path.addPoly(fCorners, 4, true);
            linePaint.setColor(SK_ColorBLACK);
            canvas->drawPath(path, linePaint);
        } else {
            // Draw the edges of the true quad as a solid *red* line
            SkPath path;
            path.addPoly(fCorners, 4, 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);
        }
    }

    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override;
    bool onClick(Sample::Click*) override;
    bool onChar(SkUnichar) override;
    SkString name() override { return SkString("DegenerateQuad"); }

private:
    class Click;

    enum class CoverageMode {
        kArea, kEdgeDistance, kGPUMesh
    };

    const SkRect fOuterRect;
    SkPoint fCorners[4]; // TL, TR, BR, BL
    bool fEdgeAA[4]; // T, R, B, L
    CoverageMode fCoverageMode;

    bool isValid() const {
        SkPath path;
        path.addPoly(fCorners, 4, true);
        return path.isConvex();
    }

    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, SkMatrix::I());

        float vertices[56]; // 2 quads, with x, y, coverage, and geometry domain (7 floats x 8 vert)
        skgpu::v1::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]};
    }

    using INHERITED = Sample;
};

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

    void doClick(SkPoint points[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));
    }
};

Sample::Click* DegenerateQuadSample::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 DegenerateQuadSample::onClick(Sample::Click* click) {
    Click* myClick = (Click*) click;
    myClick->doClick(fCorners);
    return true;
}

bool DegenerateQuadSample::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_SAMPLE(return new DegenerateQuadSample(SkRect::MakeWH(4.f, 4.f));)
