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

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "src/core/SkPathPriv.h"

#include <memory>

static void create_ngon(int n, SkPoint* pts, SkScalar width, SkScalar height) {
    float angleStep = 360.0f / n, angle = 0.0f;
    if ((n % 2) == 1) {
        angle = angleStep/2.0f;
    }

    for (int i = 0; i < n; ++i) {
        pts[i].fX = -SkScalarSin(SkDegreesToRadians(angle)) * width;
        pts[i].fY =  SkScalarCos(SkDegreesToRadians(angle)) * height;
        angle += angleStep;
    }
}

namespace ConvexLineOnlyData {
// narrow rect
const SkPoint gPoints0[] = {
    { -1.5f, -50.0f },
    { 1.5f, -50.0f },
    { 1.5f,  50.0f },
    { -1.5f,  50.0f }
};
// narrow rect on an angle
const SkPoint gPoints1[] = {
    { -50.0f, -49.0f },
    { -49.0f, -50.0f },
    { 50.0f,  49.0f },
    { 49.0f,  50.0f }
};
// trap - narrow on top - wide on bottom
const SkPoint gPoints2[] = {
    { -10.0f, -50.0f },
    { 10.0f, -50.0f },
    { 50.0f,  50.0f },
    { -50.0f,  50.0f }
};
// wide skewed rect
const SkPoint gPoints3[] = {
    { -50.0f, -50.0f },
    { 0.0f, -50.0f },
    { 50.0f,  50.0f },
    { 0.0f,  50.0f }
};
// thin rect with colinear-ish lines
const SkPoint gPoints4[] = {
    { -6.0f, -50.0f },
    { 4.0f, -50.0f },
    { 5.0f, -25.0f },  // remove if collinear diagonal points are not concave
    { 6.0f,   0.0f },
    { 5.0f,  25.0f },  // remove if collinear diagonal points are not concave
    { 4.0f,  50.0f },
    { -4.0f,  50.0f }
};
// degenerate
const SkPoint gPoints5[] = {
    { -0.025f, -0.025f },
    { 0.025f, -0.025f },
    { 0.025f,  0.025f },
    { -0.025f,  0.025f }
};
// Triangle in which the first point should fuse with last
const SkPoint gPoints6[] = {
    { -20.0f, -13.0f },
    { -20.0f, -13.05f },
    { 20.0f, -13.0f },
    { 20.0f,  27.0f }
};
// thin rect with colinear lines
const SkPoint gPoints7[] = {
    { -10.0f, -50.0f },
    { 10.0f, -50.0f },
    { 10.0f, -25.0f },
    { 10.0f,   0.0f },
    { 10.0f,  25.0f },
    { 10.0f,  50.0f },
    { -10.0f,  50.0f }
};
// capped teardrop
const SkPoint gPoints8[] = {
    { 50.00f,  50.00f },
    { 0.00f,  50.00f },
    { -15.45f,  47.55f },
    { -29.39f,  40.45f },
    { -40.45f,  29.39f },
    { -47.55f,  15.45f },
    { -50.00f,   0.00f },
    { -47.55f, -15.45f },
    { -40.45f, -29.39f },
    { -29.39f, -40.45f },
    { -15.45f, -47.55f },
    { 0.00f, -50.00f },
    { 50.00f, -50.00f }
};
// teardrop
const SkPoint gPoints9[] = {
    { 4.39f,  40.45f },
    { -9.55f,  47.55f },
    { -25.00f,  50.00f },
    { -40.45f,  47.55f },
    { -54.39f,  40.45f },
    { -65.45f,  29.39f },
    { -72.55f,  15.45f },
    { -75.00f,   0.00f },
    { -72.55f, -15.45f },
    { -65.45f, -29.39f },
    { -54.39f, -40.45f },
    { -40.45f, -47.55f },
    { -25.0f,  -50.0f },
    { -9.55f, -47.55f },
    { 4.39f, -40.45f },
    { 75.00f,   0.00f }
};
// clipped triangle
const SkPoint gPoints10[] = {
    { -10.0f, -50.0f },
    { 10.0f, -50.0f },
    { 50.0f,  31.0f },
    { 40.0f,  50.0f },
    { -40.0f,  50.0f },
    { -50.0f,  31.0f },
};

const SkPoint* gPoints[] = {
    gPoints0, gPoints1, gPoints2, gPoints3, gPoints4, gPoints5, gPoints6,
    gPoints7, gPoints8, gPoints9, gPoints10,
};

const size_t gSizes[] = {
    SK_ARRAY_COUNT(gPoints0),
    SK_ARRAY_COUNT(gPoints1),
    SK_ARRAY_COUNT(gPoints2),
    SK_ARRAY_COUNT(gPoints3),
    SK_ARRAY_COUNT(gPoints4),
    SK_ARRAY_COUNT(gPoints5),
    SK_ARRAY_COUNT(gPoints6),
    SK_ARRAY_COUNT(gPoints7),
    SK_ARRAY_COUNT(gPoints8),
    SK_ARRAY_COUNT(gPoints9),
    SK_ARRAY_COUNT(gPoints10),
};
static_assert(SK_ARRAY_COUNT(gSizes) == SK_ARRAY_COUNT(gPoints), "array_mismatch");
}  // namespace ConvexLineOnlyData

namespace skiagm {

// This GM is intended to exercise Ganesh's handling of convex line-only
// paths
class ConvexLineOnlyPathsGM : public GM {
public:
    ConvexLineOnlyPathsGM(bool doStrokeAndFill) : fDoStrokeAndFill(doStrokeAndFill) {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    SkString onShortName() override {
        if (fDoStrokeAndFill) {
            return SkString("convex-lineonly-paths-stroke-and-fill");
        }
        return SkString("convex-lineonly-paths");
    }
    SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); }
    bool runAsBench() const override { return true; }

    static SkPath GetPath(int index, SkPathDirection dir) {
        std::unique_ptr<SkPoint[]> data(nullptr);
        const SkPoint* points;
        int numPts;
        if (index < (int) SK_ARRAY_COUNT(ConvexLineOnlyData::gPoints)) {
            // manually specified
            points = ConvexLineOnlyData::gPoints[index];
            numPts = (int)ConvexLineOnlyData::gSizes[index];
        } else {
            // procedurally generated
            SkScalar width = kMaxPathHeight/2;
            SkScalar height = kMaxPathHeight/2;
            switch (index-SK_ARRAY_COUNT(ConvexLineOnlyData::gPoints)) {
            case 0:
                numPts = 3;
                break;
            case 1:
                numPts = 4;
                break;
            case 2:
                numPts = 5;
                break;
            case 3:             // squashed pentagon
                numPts = 5;
                width = kMaxPathHeight/5;
                break;
            case 4:
                numPts = 6;
                break;
            case 5:
                numPts = 8;
                break;
            case 6:              // squashed octogon
                numPts = 8;
                width = kMaxPathHeight/5;
                break;
            case 7:
                numPts = 20;
                break;
            case 8:
                numPts = 100;
                break;
            default:
                numPts = 3;
                break;
            }

            data = std::make_unique<SkPoint[]>(numPts);

            create_ngon(numPts, data.get(), width, height);
            points = data.get();
        }

        SkPath path;

        if (SkPathDirection::kCW == dir) {
            path.moveTo(points[0]);
            for (int i = 1; i < numPts; ++i) {
                path.lineTo(points[i]);
            }
        } else {
            path.moveTo(points[numPts-1]);
            for (int i = numPts-2; i >= 0; --i) {
                path.lineTo(points[i]);
            }
        }

        path.close();
#ifdef SK_DEBUG
        // Each path this method returns should be convex, only composed of
        // lines, wound the right direction, and short enough to fit in one
        // of the GMs rows.
        SkASSERT(path.isConvex());
        SkASSERT(SkPath::kLine_SegmentMask == path.getSegmentMasks());
        SkPathPriv::FirstDirection actualDir;
        SkASSERT(SkPathPriv::CheapComputeFirstDirection(path, &actualDir));
        SkASSERT(SkPathPriv::AsFirstDirection(dir) == actualDir);
        SkRect bounds = path.getBounds();
        SkASSERT(SkScalarNearlyEqual(bounds.centerX(), 0.0f));
        SkASSERT(bounds.height() <= kMaxPathHeight);
#endif
        return path;
    }

    // Draw a single path several times, shrinking it, flipping its direction
    // and changing its start vertex each time.
    void drawPath(SkCanvas* canvas, int index, SkPoint* offset) {

        SkPoint center;
        {
            SkPath path = GetPath(index, SkPathDirection::kCW);
            if (offset->fX+path.getBounds().width() > kGMWidth) {
                offset->fX = 0;
                offset->fY += kMaxPathHeight;
                if (fDoStrokeAndFill) {
                    offset->fX += kStrokeWidth / 2.0f;
                    offset->fY += kStrokeWidth / 2.0f;
                }
            }
            center = { offset->fX + SkScalarHalf(path.getBounds().width()), offset->fY};
            offset->fX += path.getBounds().width();
            if (fDoStrokeAndFill) {
                offset->fX += kStrokeWidth;
            }
        }

        const SkColor colors[2] = { SK_ColorBLACK, SK_ColorWHITE };
        const SkPathDirection dirs[2] = { SkPathDirection::kCW, SkPathDirection::kCCW };
        const float scales[] = { 1.0f, 0.75f, 0.5f, 0.25f, 0.1f, 0.01f, 0.001f };
        const SkPaint::Join joins[3] = { SkPaint::kRound_Join,
                                         SkPaint::kBevel_Join,
                                         SkPaint::kMiter_Join };

        SkPaint paint;
        paint.setAntiAlias(true);

        for (size_t i = 0; i < SK_ARRAY_COUNT(scales); ++i) {
            SkPath path = GetPath(index, dirs[i%2]);
            if (fDoStrokeAndFill) {
                paint.setStyle(SkPaint::kStrokeAndFill_Style);
                paint.setStrokeJoin(joins[i%3]);
                paint.setStrokeWidth(SkIntToScalar(kStrokeWidth));
            }

            canvas->save();
                canvas->translate(center.fX, center.fY);
                canvas->scale(scales[i], scales[i]);
                paint.setColor(colors[i%2]);
                canvas->drawPath(path, paint);
            canvas->restore();
        }
    }

    void onDraw(SkCanvas* canvas) override {
        // the right edge of the last drawn path
        SkPoint offset = { 0, SkScalarHalf(kMaxPathHeight) };
        if (fDoStrokeAndFill) {
            offset.fX += kStrokeWidth / 2.0f;
            offset.fY += kStrokeWidth / 2.0f;
        }

        for (int i = 0; i < kNumPaths; ++i) {
            this->drawPath(canvas, i, &offset);
        }

        {
            // Repro for crbug.com/472723 (Missing AA on portions of graphic with GPU rasterization)

            SkPaint p;
            p.setAntiAlias(true);
            if (fDoStrokeAndFill) {
                p.setStyle(SkPaint::kStrokeAndFill_Style);
                p.setStrokeJoin(SkPaint::kMiter_Join);
                p.setStrokeWidth(SkIntToScalar(kStrokeWidth));
            }

            SkPath p1;
            p1.moveTo(60.8522949f, 364.671021f);
            p1.lineTo(59.4380493f, 364.671021f);
            p1.lineTo(385.414276f, 690.647217f);
            p1.lineTo(386.121399f, 689.940125f);
            canvas->save();
            canvas->translate(356.0f, 50.0f);
            canvas->drawPath(p1, p);
            canvas->restore();

            // Repro for crbug.com/869172 (SVG path incorrectly simplified when using GPU
            // Rasterization). This will only draw anything in the stroke-and-fill version.
            SkPath p2;
            p2.moveTo(10.f, 0.f);
            p2.lineTo(38.f, 0.f);
            p2.lineTo(66.f, 0.f);
            p2.lineTo(94.f, 0.f);
            p2.lineTo(122.f, 0.f);
            p2.lineTo(150.f, 0.f);
            p2.lineTo(150.f, 0.f);
            p2.lineTo(122.f, 0.f);
            p2.lineTo(94.f, 0.f);
            p2.lineTo(66.f, 0.f);
            p2.lineTo(38.f, 0.f);
            p2.lineTo(10.f, 0.f);
            p2.close();
            canvas->save();
            canvas->translate(0.0f, 500.0f);
            canvas->drawPath(p2, p);
            canvas->restore();

            // Repro for crbug.com/856137. This path previously caused GrAAConvexTessellator to turn
            // inset rings into outsets when adjacent bisector angles converged outside the previous
            // ring due to accumulated error.
            SkPath p3;
            p3.setFillType(SkPathFillType::kEvenOdd);
            p3.moveTo(1184.96f, 982.557f);
            p3.lineTo(1183.71f, 982.865f);
            p3.lineTo(1180.99f, 982.734f);
            p3.lineTo(1178.5f, 981.541f);
            p3.lineTo(1176.35f, 979.367f);
            p3.lineTo(1178.94f, 938.854f);
            p3.lineTo(1181.35f, 936.038f);
            p3.lineTo(1183.96f, 934.117f);
            p3.lineTo(1186.67f, 933.195f);
            p3.lineTo(1189.36f, 933.342f);
            p3.lineTo(1191.58f, 934.38f);
            p3.close();
            canvas->save();
            SkMatrix m;
            m.setAll(0.0893210843f, 0, 79.1197586f, 0, 0.0893210843f, 300, 0, 0, 1);
            canvas->concat(m);
            canvas->drawPath(p3, p);
            canvas->restore();
        }
    }

private:
    static constexpr int kStrokeWidth   = 10;
    static constexpr int kNumPaths      = 20;
    static constexpr int kMaxPathHeight = 100;
    static constexpr int kGMWidth       = 512;
    static constexpr int kGMHeight      = 512;

    bool fDoStrokeAndFill;

    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new ConvexLineOnlyPathsGM(false);)
DEF_GM(return new ConvexLineOnlyPathsGM(true);)
}  // namespace skiagm
