/*
 * Copyright 2011 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/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkContourMeasure.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPath.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/core/SkStream.h"
#include "include/core/SkTime.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkVertices.h"
#include "include/effects/SkGradientShader.h"
#include "include/effects/SkOpPathEffect.h"
#include "include/private/SkTDArray.h"
#include "include/utils/SkRandom.h"
#include "samplecode/DecodeFile.h"
#include "samplecode/Sample.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkOSFile.h"
#include "src/utils/SkUTF.h"
#include "tools/Resources.h"
#include "tools/timer/TimeUtils.h"

namespace {
static sk_sp<SkShader> make_shader0(SkIPoint* size) {
    SkBitmap bm;
    decode_file(GetResourceAsData("images/dog.jpg"), &bm);
    *size = SkIPoint{bm.width(), bm.height()};
    return bm.makeShader(SkSamplingOptions(SkFilterMode::kLinear,
                                           SkMipmapMode::kNone));
}

static sk_sp<SkShader> make_shader1(const SkIPoint& size) {
    SkPoint pts[] = { { 0, 0, },
                      { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
    SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
    return SkGradientShader::MakeLinear(pts, colors, nullptr,
                    SK_ARRAY_COUNT(colors), SkTileMode::kMirror);
}

class Patch {
public:
    Patch() { sk_bzero(fPts, sizeof(fPts)); }
    ~Patch() {}

    void setPatch(const SkPoint pts[12]) {
        memcpy(fPts, pts, 12 * sizeof(SkPoint));
        fPts[12] = pts[0];  // the last shall be first
    }
    void setBounds(int w, int h) { fW = w; fH = h; }

    void draw(SkCanvas*, const SkPaint&, int segsU, int segsV,
              bool doTextures, bool doColors);

private:
    SkPoint fPts[13];
    int     fW, fH;
};

static void eval_patch_edge(const SkPoint cubic[], SkPoint samples[], int segs) {
    SkScalar t = 0;
    SkScalar dt = SK_Scalar1 / segs;

    samples[0] = cubic[0];
    for (int i = 1; i < segs; i++) {
        t += dt;
        SkEvalCubicAt(cubic, t, &samples[i], nullptr, nullptr);
    }
}

static void eval_sheet(const SkPoint edge[], int nu, int nv, int iu, int iv,
                       SkPoint* pt) {
    const int TL = 0;
    const int TR = nu;
    const int BR = TR + nv;
    const int BL = BR + nu;

    SkScalar u = SkIntToScalar(iu) / nu;
    SkScalar v = SkIntToScalar(iv) / nv;

    SkScalar uv = u * v;
    SkScalar Uv = (1 - u) * v;
    SkScalar uV = u * (1 - v);
    SkScalar UV = (1 - u) * (1 - v);

    SkScalar x0 = UV * edge[TL].fX + uV * edge[TR].fX + Uv * edge[BL].fX + uv * edge[BR].fX;
    SkScalar y0 = UV * edge[TL].fY + uV * edge[TR].fY + Uv * edge[BL].fY + uv * edge[BR].fY;

    SkScalar x = (1 - v) * edge[TL+iu].fX + u * edge[TR+iv].fX +
                 v * edge[BR+nu-iu].fX + (1 - u) * edge[BL+nv-iv].fX - x0;
    SkScalar y = (1 - v) * edge[TL+iu].fY + u * edge[TR+iv].fY +
                 v * edge[BR+nu-iu].fY + (1 - u) * edge[BL+nv-iv].fY - y0;
    pt->set(x, y);
}

static SkColor make_color(SkScalar s, SkScalar t) {
    return SkColorSetARGB(0xFF, SkUnitScalarClampToByte(s), SkUnitScalarClampToByte(t), 0);
}

void Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
                 bool doTextures, bool doColors) {
    if (nu < 1 || nv < 1) {
        return;
    }

    int i, npts = (nu + nv) * 2;
    SkAutoSTMalloc<16, SkPoint> storage(npts + 1);
    SkPoint* edge0 = storage.get();
    SkPoint* edge1 = edge0 + nu;
    SkPoint* edge2 = edge1 + nv;
    SkPoint* edge3 = edge2 + nu;

    // evaluate the edge points
    eval_patch_edge(fPts + 0, edge0, nu);
    eval_patch_edge(fPts + 3, edge1, nv);
    eval_patch_edge(fPts + 6, edge2, nu);
    eval_patch_edge(fPts + 9, edge3, nv);
    edge3[nv] = edge0[0];   // the last shall be first

    for (i = 0; i < npts; i++) {
//        canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint);
    }

    int row, vertCount = (nu + 1) * (nv + 1);
    SkAutoTMalloc<SkPoint>  vertStorage(vertCount);
    SkPoint* verts = vertStorage.get();

    // first row
    memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint));
    // rows
    SkPoint* r = verts;
    for (row = 1; row < nv; row++) {
        r += nu + 1;
        r[0] = edge3[nv - row];
        for (int col = 1; col < nu; col++) {
            eval_sheet(edge0, nu, nv, col, row, &r[col]);
        }
        r[nu] = edge1[row];
    }
    // last row
    SkPoint* last = verts + nv * (nu + 1);
    for (i = 0; i <= nu; i++) {
        last[i] = edge2[nu - i];
    }

//    canvas->drawPoints(verts, vertCount, paint);

    int stripCount = (nu + 1) * 2;
    SkAutoTMalloc<SkPoint>  stripStorage(stripCount * 2);
    SkAutoTMalloc<SkColor>  colorStorage(stripCount);
    SkPoint* strip = stripStorage.get();
    SkPoint* tex = strip + stripCount;
    SkColor* colors = colorStorage.get();
    SkScalar t = 0;
    const SkScalar ds = SK_Scalar1 * fW / nu;
    const SkScalar dt = SK_Scalar1 * fH / nv;
    r = verts;
    for (row = 0; row < nv; row++) {
        SkPoint* upper = r;
        SkPoint* lower = r + nu + 1;
        r = lower;
        SkScalar s = 0;
        for (i = 0; i <= nu; i++)  {
            strip[i*2 + 0] = *upper++;
            strip[i*2 + 1] = *lower++;
            tex[i*2 + 0].set(s, t);
            tex[i*2 + 1].set(s, t + dt);
            colors[i*2 + 0] = make_color(s/fW, t/fH);
            colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH);
            s += ds;
        }
        t += dt;
        canvas->drawVertices(SkVertices::MakeCopy(SkVertices::kTriangleStrip_VertexMode, stripCount,
                                                  strip, doTextures ? tex : nullptr,
                                                  doColors ? colors : nullptr),
                             SkBlendMode::kModulate, paint);
    }
}

static void drawpatches(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
                        Patch* patch) {
    SkAutoCanvasRestore ar(canvas, true);

    patch->draw(canvas, paint, nu, nv, false, false);
    canvas->translate(SkIntToScalar(180), 0);
    patch->draw(canvas, paint, nu, nv, true, false);
    canvas->translate(SkIntToScalar(180), 0);
    patch->draw(canvas, paint, nu, nv, false, true);
    canvas->translate(SkIntToScalar(180), 0);
    patch->draw(canvas, paint, nu, nv, true, true);
}

static constexpr SkScalar DX = 20;
static constexpr SkScalar DY = 0;
static constexpr SkScalar kS = 50;
static constexpr SkScalar kT = 40;

struct PatchView : public Sample {
    sk_sp<SkShader> fShader0;
    sk_sp<SkShader> fShader1;
    SkScalar fAngle = 0;
    SkIPoint fSize0 = {0, 0},
             fSize1 = {0, 0};
    SkPoint  fPts[12] = {
        {kS * 0, kT * 1},
        {kS * 1, kT * 1},
        {kS * 2, kT * 1},
        {kS * 3, kT * 1},
        {kS * 3, kT * 2},
        {kS * 3, kT * 3},
        {kS * 3, kT * 4},
        {kS * 2, kT * 4},
        {kS * 1, kT * 4},
        {kS * 0, kT * 4},
        {kS * 0, kT * 3},
        {kS * 0, kT * 2},
    };

    void onOnceBeforeDraw() override {
        fShader0 = make_shader0(&fSize0);
        fSize1 = fSize0;
        if (fSize0.fX == 0 || fSize0.fY == 0) {
            fSize1.set(2, 2);
        }
        fShader1 = make_shader1(fSize1);
        this->setBGColor(SK_ColorGRAY);
    }

    SkString name() override { return SkString("Patch"); }

    void onDrawContent(SkCanvas* canvas) override {
        const int nu = 10;
        const int nv = 10;

        SkPaint paint;
        paint.setDither(true);

        canvas->translate(DX, DY);

        Patch   patch;

        paint.setShader(fShader0);
        if (fSize0.fX == 0) {
            fSize0.fX = 1;
        }
        if (fSize0.fY == 0) {
            fSize0.fY = 1;
        }
        patch.setBounds(fSize0.fX, fSize0.fY);

        patch.setPatch(fPts);
        drawpatches(canvas, paint, nu, nv, &patch);

        paint.setShader(nullptr);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(SkIntToScalar(5));
        canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(fPts), fPts, paint);

        canvas->translate(0, SkIntToScalar(300));

        paint.setAntiAlias(false);
        paint.setShader(fShader1);
        {
            SkMatrix m;
            m.setSkew(1, 0);
            paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
        }
        {
            SkMatrix m;
            m.setRotate(fAngle);
            paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
        }
        patch.setBounds(fSize1.fX, fSize1.fY);
        drawpatches(canvas, paint, nu, nv, &patch);
    }

    bool onAnimate(double nanos) override {
        fAngle = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
        return true;
    }

    class PtClick : public Click {
    public:
        int fIndex;
        PtClick(int index) : fIndex(index) {}
    };

    static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
        return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
    }

    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        x -= DX;
        y -= DY;
        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
            if (hittest(fPts[i], x, y)) {
                return new PtClick((int)i);
            }
        }
        return nullptr;
    }

    bool onClick(Click* click) override {
        fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX - DX, click->fCurr.fY - DY);
        return true;
    }

private:
    using INHERITED = Sample;
};
}  // namespace
DEF_SAMPLE( return new PatchView(); )

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

namespace {
static sk_sp<SkVertices> make_verts(const SkPath& path, SkScalar width) {
    auto meas = SkContourMeasureIter(path, false).next();
    if (!meas) {
        return nullptr;
    }

    const SkPoint src[2] = {
        { 0, -width/2 }, { 0, width/2 },
    };
    SkTDArray<SkPoint> pts;

    const SkScalar step = 2;
    for (SkScalar distance = 0; distance < meas->length(); distance += step) {
        SkMatrix mx;
        if (!meas->getMatrix(distance, &mx)) {
            continue;
        }
        SkPoint* dst = pts.append(2);
        mx.mapPoints(dst, src, 2);
    }

    int vertCount = pts.count();
    int indexCount = 0; // no texture
    unsigned flags = SkVertices::kHasColors_BuilderFlag;
    SkVertices::Builder builder(SkVertices::kTriangleStrip_VertexMode,
                                vertCount, indexCount, flags);
    memcpy(builder.positions(), pts.begin(), vertCount * sizeof(SkPoint));
    SkRandom rand;
    for (int i = 0; i < vertCount; ++i) {
        builder.colors()[i] = rand.nextU() | 0xFF000000;
    }
    SkDebugf("vert count = %d\n", vertCount);

    return builder.detach();
}

class PseudoInkView : public Sample {
    enum { N = 100 };
    SkPath            fPath;
    sk_sp<SkVertices> fVertices[N];
    SkPaint           fSkeletonP, fStrokeP, fVertsP;
    bool              fDirty = true;

public:
    PseudoInkView() {
        fSkeletonP.setStyle(SkPaint::kStroke_Style);
        fSkeletonP.setAntiAlias(true);

        fStrokeP.setStyle(SkPaint::kStroke_Style);
        fStrokeP.setStrokeWidth(30);
        fStrokeP.setColor(0x44888888);
    }

protected:
    SkString name() override { return SkString("PseudoInk"); }

    bool onAnimate(double nanos) override { return true; }

    void onDrawContent(SkCanvas* canvas) override {
        if (fDirty) {
            for (int i = 0; i < N; ++i) {
                fVertices[i] = make_verts(fPath, 30);
            }
            fDirty = false;
        }
        for (int i = 0; i < N; ++i) {
            canvas->drawVertices(fVertices[i], SkBlendMode::kSrc, fVertsP);
            canvas->translate(1, 1);
        }
//        canvas->drawPath(fPath, fStrokeP);
 //       canvas->drawPath(fPath, fSkeletonP);
    }

    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        Click* click = new Click();
        fPath.reset();
        fPath.moveTo(x, y);
        return click;
    }

    bool onClick(Click* click) override {
        switch (click->fState) {
            case skui::InputState::kMove:
                fPath.lineTo(click->fCurr);
                fDirty = true;
                break;
            default:
                break;
        }
        return true;
    }

private:
    using INHERITED = Sample;
};
}  // namespace
DEF_SAMPLE( return new PseudoInkView(); )

namespace {
// Show stroking options using patheffects (and pathops)
// and why strokeandfill is a hacks
class ManyStrokesView : public Sample {
    SkPath              fPath;
    sk_sp<SkPathEffect> fPE[6];

public:
    ManyStrokesView() {
        fPE[0] = SkStrokePathEffect::Make(20, SkPaint::kRound_Join, SkPaint::kRound_Cap);

        auto p0 = SkStrokePathEffect::Make(25, SkPaint::kRound_Join, SkPaint::kRound_Cap);
        auto p1 = SkStrokePathEffect::Make(20, SkPaint::kRound_Join, SkPaint::kRound_Cap);
        fPE[1] = SkMergePathEffect::Make(p0, p1, SkPathOp::kDifference_SkPathOp);

        fPE[2] = SkMergePathEffect::Make(nullptr, p1, SkPathOp::kDifference_SkPathOp);
        fPE[3] = SkMergePathEffect::Make(nullptr, p1, SkPathOp::kUnion_SkPathOp);
        fPE[4] = SkMergePathEffect::Make(p0, nullptr, SkPathOp::kDifference_SkPathOp);
        fPE[5] = SkMergePathEffect::Make(p0, nullptr, SkPathOp::kIntersect_SkPathOp);
    }

protected:
    SkString name() override { return SkString("ManyStrokes"); }

    bool onAnimate(double nanos) override { return true; }

    void dodraw(SkCanvas* canvas, sk_sp<SkPathEffect> pe, SkScalar x, SkScalar y,
                const SkPaint* ptr = nullptr) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setPathEffect(pe);
        canvas->save();
        canvas->translate(x, y);
        canvas->drawPath(fPath, ptr ? *ptr : paint);

        paint.setPathEffect(nullptr);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setColor(SK_ColorGREEN);
        canvas->drawPath(fPath, paint);

        canvas->restore();
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkPaint p;
        p.setColor(0);
        this->dodraw(canvas, nullptr, 0, 0, &p);

        this->dodraw(canvas, fPE[0], 300, 0);
        this->dodraw(canvas, fPE[1], 0, 300);
        this->dodraw(canvas, fPE[2], 300, 300);
        this->dodraw(canvas, fPE[3], 600, 300);
        this->dodraw(canvas, fPE[4], 900, 0);
        this->dodraw(canvas, fPE[5], 900, 300);

        p.setColor(SK_ColorBLACK);
        p.setStyle(SkPaint::kStrokeAndFill_Style);
        p.setStrokeJoin(SkPaint::kRound_Join);
        p.setStrokeCap(SkPaint::kRound_Cap);
        p.setStrokeWidth(20);
        this->dodraw(canvas, nullptr, 600, 0, &p);
    }

    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        Click* click = new Click();
        fPath.reset();
        fPath.moveTo(x, y);
        return click;
    }

    bool onClick(Click* click) override {
        switch (click->fState) {
            case skui::InputState::kMove:
                fPath.lineTo(click->fCurr);
                break;
            default:
                break;
        }
        return true;
    }

private:
    using INHERITED = Sample;
};
}  // namespace
DEF_SAMPLE( return new ManyStrokesView(); )
