/*
 * 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) {
        SkDEBUGCODE(path.experimentalValidateRef());
    }
}

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();
        SkCanvas* canvas(
            SkCanvas::NewRasterDirect(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);
        }
        this->inval(nullptr);
    }

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

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