/*
 * 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 "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkMatrix.h"
#include "SkColor.h"
#include "SkTDArray.h"
#include "SkRandom.h"
#include "SkRRect.h"

enum RandomAddPath {
    kMoveToPath,
    kRMoveToPath,
    kLineToPath,
    kRLineToPath,
    kQuadToPath,
    kRQuadToPath,
    kConicToPath,
    kRConicToPath,
    kCubicToPath,
    kRCubicToPath,
    kArcToPath,
    kArcTo2Path,
    kClosePath,
    kAddArc,
    kAddRoundRect1,
    kAddRoundRect2,
    kAddRRect,
    kAddPoly,
    kAddPath1,
    kAddPath2,
    kAddPath3,
    kReverseAddPath,
};

const int kRandomAddPath_Last = kReverseAddPath;

const char* gRandomAddPathNames[] = {
    "kMoveToPath",
    "kRMoveToPath",
    "kLineToPath",
    "kRLineToPath",
    "kQuadToPath",
    "kRQuadToPath",
    "kConicToPath",
    "kRConicToPath",
    "kCubicToPath",
    "kRCubicToPath",
    "kArcToPath",
    "kArcTo2Path",
    "kClosePath",
    "kAddArc",
    "kAddRoundRect1",
    "kAddRoundRect2",
    "kAddRRect",
    "kAddPoly",
    "kAddPath1",
    "kAddPath2",
    "kAddPath3",
    "kReverseAddPath",
};

enum RandomSetRRect {
    kSetEmpty,
    kSetRect,
    kSetOval,
    kSetRectXY,
    kSetNinePatch,
    kSetRectRadii,
};

const char* gRandomSetRRectNames[] = {
    "kSetEmpty",
    "kSetRect",
    "kSetOval",
    "kSetRectXY",
    "kSetNinePatch",
    "kSetRectRadii",
};

int kRandomSetRRect_Last = kSetRectRadii;

enum RandomSetMatrix {
    kSetIdentity,
    kSetTranslate,
    kSetTranslateX,
    kSetTranslateY,
    kSetScale,
    kSetScaleTranslate,
    kSetScaleX,
    kSetScaleY,
    kSetSkew,
    kSetSkewTranslate,
    kSetSkewX,
    kSetSkewY,
    kSetRotate,
    kSetRotateTranslate,
    kSetPerspectiveX,
    kSetPerspectiveY,
    kSetAll,
};

int kRandomSetMatrix_Last = kSetAll;

const char* gRandomSetMatrixNames[] = {
    "kSetIdentity",
    "kSetTranslate",
    "kSetTranslateX",
    "kSetTranslateY",
    "kSetScale",
    "kSetScaleTranslate",
    "kSetScaleX",
    "kSetScaleY",
    "kSetSkew",
    "kSetSkewTranslate",
    "kSetSkewX",
    "kSetSkewY",
    "kSetRotate",
    "kSetRotateTranslate",
    "kSetPerspectiveX",
    "kSetPerspectiveY",
    "kSetAll",
};

class FuzzPath {
public:
    FuzzPath()
        : fFloatMin(0)
        , fFloatMax(800)
        , fAddCount(0)
        , fPrintName(false)
        , fStrokeOnly(false)
        , fValidate(false)
    {
        fTab = "                                                                                  ";
    }
    void randomize() {
        fPathDepth = 0;
        fPathDepthLimit = fRand.nextRangeU(1, 2);
        fPathContourCount = fRand.nextRangeU(1, 4);
        fPathSegmentLimit = fRand.nextRangeU(1, 8);
        fClip = makePath();
        SkASSERT(!fPathDepth);
        fMatrix = makeMatrix();
        fPaint = makePaint();
        fPathDepthLimit = fRand.nextRangeU(1, 3);
        fPathContourCount = fRand.nextRangeU(1, 6);
        fPathSegmentLimit = fRand.nextRangeU(1, 16);
        fPath = makePath();
        SkASSERT(!fPathDepth);
    }

    const SkPath& getClip() const {
        return fClip;
    }

    const SkMatrix& getMatrix() const {
        return fMatrix;
    }

    const SkPaint& getPaint() const {
        return fPaint;
    }

    const SkPath& getPath() const {
        return fPath;
    }

    void setSeed(int seed) {
        fRand.setSeed(seed);
    }

    void setStrokeOnly() {
        fStrokeOnly = true;
    }

private:

SkPath::AddPathMode makeAddPathMode() {
    return (SkPath::AddPathMode) fRand.nextRangeU(SkPath::kAppend_AddPathMode,
        SkPath::kExtend_AddPathMode);
}

RandomAddPath makeAddPathType() {
    return (RandomAddPath) fRand.nextRangeU(0, kRandomAddPath_Last);
}

SkScalar makeAngle() {
    SkScalar angle;
    angle = fRand.nextF();
    return angle;
}

bool makeBool() {
    return fRand.nextBool();
}

SkPath::Direction makeDirection() {
    return (SkPath::Direction) fRand.nextRangeU(SkPath::kCW_Direction, SkPath::kCCW_Direction);
}

SkMatrix makeMatrix() {
    SkMatrix matrix;
    matrix.reset();
    RandomSetMatrix setMatrix = (RandomSetMatrix) fRand.nextRangeU(0, kRandomSetMatrix_Last);
    if (fPrintName) {
        SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetMatrixNames[setMatrix]);
    }
    switch (setMatrix) {
        case kSetIdentity:
            break;
        case kSetTranslateX:
            matrix.setTranslateX(makeScalar());
            break;
        case kSetTranslateY:
            matrix.setTranslateY(makeScalar());
            break;
        case kSetTranslate:
            matrix.setTranslate(makeScalar(), makeScalar());
            break;
        case kSetScaleX:
            matrix.setScaleX(makeScalar());
            break;
        case kSetScaleY:
            matrix.setScaleY(makeScalar());
            break;
        case kSetScale:
            matrix.setScale(makeScalar(), makeScalar());
            break;
        case kSetScaleTranslate:
            matrix.setScale(makeScalar(), makeScalar(), makeScalar(), makeScalar());
            break;
        case kSetSkewX:
            matrix.setSkewX(makeScalar());
            break;
        case kSetSkewY:
            matrix.setSkewY(makeScalar());
            break;
        case kSetSkew:
            matrix.setSkew(makeScalar(), makeScalar());
            break;
        case kSetSkewTranslate:
            matrix.setSkew(makeScalar(), makeScalar(), makeScalar(), makeScalar());
            break;
        case kSetRotate:
            matrix.setRotate(makeScalar());
            break;
        case kSetRotateTranslate:
            matrix.setRotate(makeScalar(), makeScalar(), makeScalar());
            break;
        case kSetPerspectiveX:
            matrix.setPerspX(makeScalar());
            break;
        case kSetPerspectiveY:
            matrix.setPerspY(makeScalar());
            break;
        case kSetAll:
            matrix.setAll(makeScalar(), makeScalar(), makeScalar(),
                          makeScalar(), makeScalar(), makeScalar(),
                          makeScalar(), makeScalar(), makeScalar());
            break;
    }
    return matrix;
}

SkPaint makePaint() {
    SkPaint paint;
    bool antiAlias = fRand.nextBool();
    paint.setAntiAlias(antiAlias);
    SkPaint::Style style = fStrokeOnly ? SkPaint::kStroke_Style :
        (SkPaint::Style) fRand.nextRangeU(SkPaint::kFill_Style, SkPaint::kStrokeAndFill_Style);
    paint.setStyle(style);
    SkColor color = (SkColor) fRand.nextU();
    paint.setColor(color);
    SkScalar width = fRand.nextRangeF(0, 10);
    paint.setStrokeWidth(width);
    SkScalar miter = makeScalar();
    paint.setStrokeMiter(miter);
    SkPaint::Cap cap = (SkPaint::Cap) fRand.nextRangeU(SkPaint::kButt_Cap, SkPaint::kSquare_Cap);
    paint.setStrokeCap(cap);
    SkPaint::Join join = (SkPaint::Join) fRand.nextRangeU(SkPaint::kMiter_Join,
        SkPaint::kBevel_Join);
    paint.setStrokeJoin(join);
    return paint;
}

SkPoint makePoint() {
    SkPoint result;
    makeScalarArray(2, &result.fX);
    return result;
}

void makePointArray(size_t arrayCount, SkPoint* points) {
    for (size_t index = 0; index < arrayCount; ++index) {
        points[index] = makePoint();
    }
}

void makePointArray(SkTDArray<SkPoint>* points) {
    size_t arrayCount = fRand.nextRangeU(1, 10);
    for (size_t index = 0; index < arrayCount; ++index) {
        *points->append() = makePoint();
    }
}

SkRect makeRect() {
    SkRect result;
    makeScalarArray(4, &result.fLeft);
    return result;
}

SkRRect makeRRect() {
    SkRRect rrect;
    RandomSetRRect rrectType = makeSetRRectType();
    if (fPrintName) {
        SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetRRectNames[rrectType]);
    }
    switch (rrectType) {
        case kSetEmpty:
            rrect.setEmpty();
            break;
        case kSetRect: {
            SkRect rect = makeRect();
            rrect.setRect(rect);
            } break;
        case kSetOval: {
            SkRect oval = makeRect();
            rrect.setOval(oval);
            } break;
        case kSetRectXY: {
            SkRect rect = makeRect();
            SkScalar xRad = makeScalar();
            SkScalar yRad = makeScalar();
            rrect.setRectXY(rect, xRad, yRad);
            } break;
        case kSetNinePatch: {
            SkRect rect = makeRect();
            SkScalar leftRad = makeScalar();
            SkScalar topRad = makeScalar();
            SkScalar rightRad = makeScalar();
            SkScalar bottomRad = makeScalar();
            rrect.setNinePatch(rect, leftRad, topRad, rightRad, bottomRad);
            SkDebugf("");  // keep locals in scope
            } break;
        case kSetRectRadii: {
            SkRect rect = makeRect();
            SkVector radii[4];
            makeVectorArray(SK_ARRAY_COUNT(radii), radii);
            rrect.setRectRadii(rect, radii);
            } break;
    }
    return rrect;
}

SkPath makePath() {
    SkPath path;
    for (uint32_t cIndex = 0; cIndex < fPathContourCount; ++cIndex) {
        uint32_t segments = makeSegmentCount();
        for (uint32_t sIndex = 0; sIndex < segments; ++sIndex) {
            RandomAddPath addPathType = makeAddPathType();
            ++fAddCount;
            if (fPrintName) {
                SkDebugf("%.*s%s\n", fPathDepth * 3, fTab,
                        gRandomAddPathNames[addPathType]);
            }
            switch (addPathType) {
                case kAddArc: {
                    SkRect oval = makeRect();
                    SkScalar startAngle = makeAngle();
                    SkScalar sweepAngle = makeAngle();
                    path.addArc(oval, startAngle, sweepAngle);
                    validate(path);
                    } break;
                case kAddRoundRect1: {
                    SkRect rect = makeRect();
                    SkScalar rx = makeScalar(), ry = makeScalar();
                    SkPath::Direction dir = makeDirection();
                    path.addRoundRect(rect, rx, ry, dir);
                    validate(path);
                    } break;
                case kAddRoundRect2: {
                    SkRect rect = makeRect();
                    SkScalar radii[8];
                    makeScalarArray(SK_ARRAY_COUNT(radii), radii);
                    SkPath::Direction dir = makeDirection();
                    path.addRoundRect(rect, radii, dir);
                    validate(path);
                    } break;
                case kAddRRect: {
                    SkRRect rrect = makeRRect();
                    SkPath::Direction dir = makeDirection();
                    path.addRRect(rrect, dir);
                    validate(path);
                    } break;
                case kAddPoly: {
                    SkTDArray<SkPoint> points;
                    makePointArray(&points);
                    bool close = makeBool();
                    path.addPoly(&points[0], points.count(), close);
                    validate(path);
                    } break;
                case kAddPath1:
                    if (fPathDepth < fPathDepthLimit) {
                        ++fPathDepth;
                        SkPath src = makePath();
                        validate(src);
                        SkScalar dx = makeScalar();
                        SkScalar dy = makeScalar();
                        SkPath::AddPathMode mode = makeAddPathMode();
                        path.addPath(src, dx, dy, mode);
                        --fPathDepth;
                        validate(path);
                    }
                    break;
                case kAddPath2:
                    if (fPathDepth < fPathDepthLimit) {
                        ++fPathDepth;
                        SkPath src = makePath();
                        validate(src);
                        SkPath::AddPathMode mode = makeAddPathMode();
                        path.addPath(src, mode);
                        --fPathDepth;
                        validate(path);
                    }
                    break;
                case kAddPath3:
                    if (fPathDepth < fPathDepthLimit) {
                        ++fPathDepth;
                        SkPath src = makePath();
                        validate(src);
                        SkMatrix matrix = makeMatrix();
                        SkPath::AddPathMode mode = makeAddPathMode();
                        path.addPath(src, matrix, mode);
                        --fPathDepth;
                        validate(path);
                    }
                    break;
                case kReverseAddPath:
                    if (fPathDepth < fPathDepthLimit) {
                        ++fPathDepth;
                        SkPath src = makePath();
                        validate(src);
                        path.reverseAddPath(src);
                        --fPathDepth;
                        validate(path);
                    }
                    break;
                case kMoveToPath: {
                    SkScalar x = makeScalar();
                    SkScalar y = makeScalar();
                    path.moveTo(x, y);
                    validate(path);
                    } break;
                case kRMoveToPath: {
                    SkScalar x = makeScalar();
                    SkScalar y = makeScalar();
                    path.rMoveTo(x, y);
                    validate(path);
                    } break;
                case kLineToPath: {
                    SkScalar x = makeScalar();
                    SkScalar y = makeScalar();
                    path.lineTo(x, y);
                    validate(path);
                    } break;
                case kRLineToPath: {
                    SkScalar x = makeScalar();
                    SkScalar y = makeScalar();
                    path.rLineTo(x, y);
                    validate(path);
                    } break;
                case kQuadToPath: {
                    SkPoint pt[2];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    path.quadTo(pt[0], pt[1]);
                    validate(path);
                    } break;
                case kRQuadToPath: {
                    SkPoint pt[2];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    path.rQuadTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY);
                    validate(path);
                    } break;
                case kConicToPath: {
                    SkPoint pt[2];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    SkScalar weight = makeScalar();
                    path.conicTo(pt[0], pt[1], weight);
                    validate(path);
                    } break;
                case kRConicToPath: {
                    SkPoint pt[2];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    SkScalar weight = makeScalar();
                    path.rConicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, weight);
                    validate(path);
                    } break;
                case kCubicToPath: {
                    SkPoint pt[3];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    path.cubicTo(pt[0], pt[1], pt[2]);
                    validate(path);
                    } break;
                case kRCubicToPath: {
                    SkPoint pt[3];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    path.rCubicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, pt[2].fX, pt[2].fY);
                    validate(path);
                    } break;
                case kArcToPath: {
                    SkPoint pt[2];
                    makePointArray(SK_ARRAY_COUNT(pt), pt);
                    SkScalar radius = makeScalar();
                    path.arcTo(pt[0], pt[1], radius);
                    validate(path);
                    } break;
                case kArcTo2Path: {
                    SkRect oval = makeRect();
                    SkScalar startAngle = makeAngle();
                    SkScalar sweepAngle = makeAngle();
                    bool forceMoveTo = makeBool();
                    path.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
                    validate(path);
                    } break;
                case kClosePath:
                    path.close();
                    validate(path);
                    break;
            }
        }
    }
    return path;
}

uint32_t makeSegmentCount() {
    return fRand.nextRangeU(1, fPathSegmentLimit);
}

RandomSetRRect makeSetRRectType() {
    return (RandomSetRRect) fRand.nextRangeU(0, kRandomSetRRect_Last);
}

SkScalar makeScalar() {
    SkScalar scalar;
    scalar = fRand.nextRangeF(fFloatMin, fFloatMax);
    return scalar;
}

void makeScalarArray(size_t arrayCount, SkScalar* array) {
    for (size_t index = 0; index < arrayCount; ++index) {
        array[index] = makeScalar();
    }
}

void makeVectorArray(size_t arrayCount, SkVector* array) {
    for (size_t index = 0; index < arrayCount; ++index) {
        array[index] = makeVector();
    }
}

SkVector makeVector() {
    SkVector result;
    makeScalarArray(2, &result.fX);
    return result;
}

void validate(const SkPath& path) {
    if (fValidate) {
        // FIXME: this could probably assert on path.isValid() instead
        SkDEBUGCODE(path.validateRef());
    }
}

SkRandom fRand;
SkMatrix fMatrix;
SkPath fClip;
SkPaint fPaint;
SkPath fPath;
SkScalar fFloatMin;
SkScalar fFloatMax;
uint32_t fPathContourCount;
int fPathDepth;
int fPathDepthLimit;
uint32_t fPathSegmentLimit;
int fAddCount;
bool fPrintName;
bool fStrokeOnly;
bool fValidate;
const char* fTab;
};

static bool contains_only_moveTo(const SkPath& path) {
    int verbCount = path.countVerbs();
    if (verbCount == 0) {
        return true;
    }
    SkTDArray<uint8_t> verbs;
    verbs.setCount(verbCount);
    SkDEBUGCODE(int getVerbResult = ) path.getVerbs(verbs.begin(), verbCount);
    SkASSERT(getVerbResult == verbCount);
    for (int index = 0; index < verbCount; ++index) {
        if (verbs[index] != SkPath::kMove_Verb) {
            return false;
        }
    }
    return true;
}

#include "SkGraphics.h"
#include "SkSurface.h"
#include "SkTaskGroup.h"
#include "SkTDArray.h"

static void path_fuzz_stroker(SkBitmap* bitmap, int seed) {
    SkTaskGroup().batch(100, [&](int i) {
        int localSeed = seed + i;

        FuzzPath fuzzPath;
        fuzzPath.setStrokeOnly();
        fuzzPath.setSeed(localSeed);
        fuzzPath.randomize();
        const SkPath& path = fuzzPath.getPath();
        const SkPaint& paint = fuzzPath.getPaint();
        const SkImageInfo& info = bitmap->info();
        std::unique_ptr<SkCanvas> canvas(
            SkCanvas::MakeRasterDirect(info, bitmap->getPixels(), bitmap->rowBytes()));
        int w = info.width() / 4;
        int h = info.height() / 4;
        int x = localSeed / 4 % 4;
        int y = localSeed % 4;
        SkRect clipBounds = SkRect::MakeXYWH(SkIntToScalar(x) * w, SkIntToScalar(y) * h,
            SkIntToScalar(w), SkIntToScalar(h));
        canvas->save();
            canvas->clipRect(clipBounds);
            canvas->translate(SkIntToScalar(x) * w, SkIntToScalar(y) * h);
            canvas->drawPath(path, paint);
        canvas->restore();
    });
}

class PathFuzzView : public SampleView {
public:
    PathFuzzView()
        : fOneDraw(false)
    {
    }
protected:
    // overrides from SkEventSink
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "PathFuzzer");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void onOnceBeforeDraw() override {
        fIndex = 0;
        SkImageInfo info(SkImageInfo::MakeN32Premul(SkScalarRoundToInt(width()),
                SkScalarRoundToInt(height())));
        offscreen.allocPixels(info);
        path_fuzz_stroker(&offscreen, fIndex);
    }

    void onDrawContent(SkCanvas* canvas) override {
        if (fOneDraw) {
            fuzzPath.randomize();
            const SkPath& path = fuzzPath.getPath();
            const SkPaint& paint = fuzzPath.getPaint();
            const SkPath& clip = fuzzPath.getClip();
            const SkMatrix& matrix = fuzzPath.getMatrix();
            if (!contains_only_moveTo(clip)) {
                canvas->clipPath(clip);
            }
            canvas->setMatrix(matrix);
            canvas->drawPath(path, paint);
        } else {
            path_fuzz_stroker(&offscreen, fIndex += 100);
            canvas->drawBitmap(offscreen, 0, 0);
        }
    }

private:
    int fIndex;
    SkBitmap offscreen;
    FuzzPath fuzzPath;
    bool fOneDraw;
    typedef SkView INHERITED;
};

static SkView* MyFactory() { return new PathFuzzView; }
static SkViewRegister reg(MyFactory);
