/*
 * 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/SkColorPriv.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/utils/SkRandom.h"
#include "samplecode/Sample.h"
#include "src/core/SkClipOpPriv.h"
#include "src/core/SkPathPriv.h"
#include "tools/Resources.h"

constexpr int W = 150;
constexpr int H = 200;

static void show_text(SkCanvas* canvas, bool doAA) {
    SkRandom rand;
    SkPaint paint;
    SkFont font(nullptr, 20);
    font.setEdging(doAA ? SkFont::Edging::kSubpixelAntiAlias : SkFont::Edging::kAlias);

    for (int i = 0; i < 200; ++i) {
        paint.setColor((SK_A32_MASK << SK_A32_SHIFT) | rand.nextU());
        canvas->drawString("Hamburgefons", rand.nextSScalar1() * W, rand.nextSScalar1() * H + 20,
                           font, paint);
    }
}

static void show_fill(SkCanvas* canvas, bool doAA) {
    SkRandom rand;
    SkPaint paint;
    paint.setAntiAlias(doAA);

    for (int i = 0; i < 50; ++i) {
        SkRect r;

        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
        paint.setColor(rand.nextU());
        canvas->drawRect(r, paint);

        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
        paint.setColor(rand.nextU());
        canvas->drawOval(r, paint);
    }
}

static SkScalar randRange(SkRandom& rand, SkScalar min, SkScalar max) {
    SkASSERT(min <= max);
    return min + rand.nextUScalar1() * (max - min);
}

static void show_stroke(SkCanvas* canvas, bool doAA, SkScalar strokeWidth, int n) {
    SkRandom rand;
    SkPaint paint;
    paint.setAntiAlias(doAA);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(strokeWidth);

    for (int i = 0; i < n; ++i) {
        SkRect r;

        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
        paint.setColor(rand.nextU());
        canvas->drawRect(r, paint);

        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
        paint.setColor(rand.nextU());
        canvas->drawOval(r, paint);

        const SkScalar minx = -SkIntToScalar(W)/4;
        const SkScalar maxx = 5*SkIntToScalar(W)/4;
        const SkScalar miny = -SkIntToScalar(H)/4;
        const SkScalar maxy = 5*SkIntToScalar(H)/4;
        paint.setColor(rand.nextU());
        canvas->drawLine(randRange(rand, minx, maxx), randRange(rand, miny, maxy),
                         randRange(rand, minx, maxx), randRange(rand, miny, maxy),
                         paint);
    }
}

static void show_hair(SkCanvas* canvas, bool doAA) {
    show_stroke(canvas, doAA, 0, 150);
}

static void show_thick(SkCanvas* canvas, bool doAA) {
    show_stroke(canvas, doAA, SkIntToScalar(5), 50);
}

typedef void (*CanvasProc)(SkCanvas*, bool);

class ClipView : public Sample {
    SkString name() override { return SkString("Clip"); }

    void onDrawContent(SkCanvas* canvas) override {
        canvas->drawColor(SK_ColorWHITE);
        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));

        static const CanvasProc gProc[] = {
            show_text, show_thick, show_hair, show_fill
        };

        SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
        r.inset(SK_Scalar1 / 4, SK_Scalar1 / 4);
        SkPath clipPath = SkPathBuilder().addRRect(SkRRect::MakeRectXY(r, 20, 20)).detach();

//        clipPath.toggleInverseFillType();

        for (int aa = 0; aa <= 1; ++aa) {
            canvas->save();
            for (size_t i = 0; i < SK_ARRAY_COUNT(gProc); ++i) {
                canvas->save();
                canvas->clipPath(clipPath, kIntersect_SkClipOp, SkToBool(aa));
//                canvas->drawColor(SK_ColorWHITE);
                gProc[i](canvas, SkToBool(aa));
                canvas->restore();
                canvas->translate(W * SK_Scalar1 * 8 / 7, 0);
            }
            canvas->restore();
            canvas->translate(0, H * SK_Scalar1 * 8 / 7);
        }
    }
};

DEF_SAMPLE( return new ClipView(); )

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

struct SkHalfPlane {
    SkScalar fA, fB, fC;

    SkScalar eval(SkScalar x, SkScalar y) const {
        return fA * x + fB * y + fC;
    }
    SkScalar operator()(SkScalar x, SkScalar y) const { return this->eval(x, y); }

    bool twoPts(SkPoint pts[2]) const {
        // normalize plane to help with the perpendicular step, below
        SkScalar len = SkScalarSqrt(fA*fA + fB*fB);
        if (!len) {
            return false;
        }
        SkScalar denom = SkScalarInvert(len);
        SkScalar a = fA * denom;
        SkScalar b = fB * denom;
        SkScalar c = fC * denom;

        // We compute p0 on the half-plane by setting one of the components to 0
        // We compute p1 by stepping from p0 along a perpendicular to the normal
        if (b) {
            pts[0] = { 0, -c / b };
            pts[1] = { b, pts[0].fY - a};
        } else if (a) {
            pts[0] = { -c / a,        0 };
            pts[1] = { pts[0].fX + b, -a };
        } else {
            return false;
        }

        SkASSERT(SkScalarNearlyZero(this->operator()(pts[0].fX, pts[0].fY)));
        SkASSERT(SkScalarNearlyZero(this->operator()(pts[1].fX, pts[1].fY)));
        return true;
    }

    enum Result {
        kAllNegative,
        kAllPositive,
        kMixed
    };
    Result test(const SkRect& bounds) const {
        SkPoint diagMin, diagMax;
        if (fA >= 0) {
            diagMin.fX = bounds.fLeft;
            diagMax.fX = bounds.fRight;
        } else {
            diagMin.fX = bounds.fRight;
            diagMax.fX = bounds.fLeft;
        }
        if (fB >= 0) {
            diagMin.fY = bounds.fTop;
            diagMax.fY = bounds.fBottom;
        } else {
            diagMin.fY = bounds.fBottom;
            diagMax.fY = bounds.fTop;
        }
        SkScalar test = this->eval(diagMin.fX, diagMin.fY);
        SkScalar sign = test*this->eval(diagMax.fX, diagMin.fY);
        if (sign > 0) {
            // the path is either all on one side of the half-plane or the other
            if (test < 0) {
                return kAllNegative;
            } else {
                return kAllPositive;
            }
        }
        return kMixed;
    }
};

#include "src/core/SkEdgeClipper.h"

static SkPath clip(const SkPath& path, SkPoint p0, SkPoint p1) {
    SkMatrix mx, inv;
    SkVector v = p1 - p0;
    mx.setAll(v.fX, -v.fY, p0.fX,
              v.fY,  v.fX, p0.fY,
                 0,     0,     1);
    SkAssertResult(mx.invert(&inv));

    SkPath rotated;
    path.transform(inv, &rotated);

    SkScalar big = 1e28f;
    SkRect clip = {-big, 0, big, big };

    struct Rec {
        SkPathBuilder   fResult;
        SkPoint         fPrev = {0, 0};
    } rec;

    SkEdgeClipper::ClipPath(rotated.view(), clip, false,
                            [](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
        Rec* rec = (Rec*)ctx;

        bool addLineTo = false;
        SkPoint      pts[4];
        SkPath::Verb verb;
        while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) {
            if (newCtr) {
                rec->fResult.moveTo(pts[0]);
                rec->fPrev = pts[0];
                newCtr = false;
            }

            if (addLineTo || pts[0] != rec->fPrev) {
                rec->fResult.lineTo(pts[0]);
            }

            switch (verb) {
                case SkPath::kLine_Verb:
                    rec->fResult.lineTo(pts[1]);
                    rec->fPrev = pts[1];
                    break;
                case SkPath::kQuad_Verb:
                    rec->fResult.quadTo(pts[1], pts[2]);
                    rec->fPrev = pts[2];
                    break;
                case SkPath::kCubic_Verb:
                    rec->fResult.cubicTo(pts[1], pts[2], pts[3]);
                    rec->fPrev = pts[3];
                    break;
                default: break;
            }
            addLineTo = true;
        }
    }, &rec);

    return rec.fResult.detach().makeTransform(mx);
}

static void draw_halfplane(SkCanvas* canvas, SkPoint p0, SkPoint p1, SkColor c) {
    SkVector v = p1 - p0;
    p0 = p0 - v * 1000;
    p1 = p1 + v * 1000;

    SkPaint paint;
    paint.setColor(c);
    canvas->drawLine(p0, p1, paint);
}

static SkPath make_path() {
    SkRandom rand;
    auto rand_pt = [&rand]() {
        auto x = rand.nextF();
        auto y = rand.nextF();
        return SkPoint{x * 400, y * 400};
    };

    SkPathBuilder path;
    for (int i = 0; i < 4; ++i) {
        SkPoint pts[6];
        for (auto& p : pts) {
            p = rand_pt();
        }
        path.moveTo(pts[0]).quadTo(pts[1], pts[2]).quadTo(pts[3], pts[4]).lineTo(pts[5]);
    }
    return path.detach();
}

class HalfPlaneView : public Sample {
    SkPoint fPts[2];
    SkPath fPath;

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

    void onOnceBeforeDraw() override {
        fPts[0] = {0, 0};
        fPts[1] = {3, 2};
        fPath = make_path();
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkPaint paint;

        paint.setColor({0.5f, 0.5f, 0.5f, 1.0f}, nullptr);
        canvas->drawPath(fPath, paint);

        paint.setColor({0, 0, 0, 1}, nullptr);

        canvas->drawPath(clip(fPath, fPts[0], fPts[1]), paint);

        draw_halfplane(canvas, fPts[0], fPts[1], SK_ColorRED);
    }

    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        return new Click;
    }

    bool onClick(Click* click) override {
        fPts[0] = click->fCurr;
        fPts[1] = fPts[0] + SkPoint{3, 2};
        return true;
    }
};
DEF_SAMPLE( return new HalfPlaneView(); )

static void draw_halfplane(SkCanvas* canvas, const SkHalfPlane& p, SkColor c) {
    SkPoint pts[2];
    p.twoPts(pts);
    draw_halfplane(canvas, pts[0], pts[1], c);
}

static void compute_half_planes(const SkMatrix& mx, SkScalar W, SkScalar H,
                                SkHalfPlane planes[4]) {
    SkScalar a = mx[0], b = mx[1], c = mx[2],
             d = mx[3], e = mx[4], f = mx[5],
             g = mx[6], h = mx[7], i = mx[8];

    planes[0] = { 2*g - 2*a/W,  2*h - 2*b/W,  2*i - 2*c/W };
    planes[1] = { 2*a/W,        2*b/W,        2*c/W };
    planes[2] = { 2*g - 2*d/H,  2*h - 2*e/H,  2*i - 2*f/H };
    planes[3] = { 2*d/H,        2*e/H,        2*f/H };
}

class HalfPlaneView2 : public Sample {
    SkPoint fPts[4];
    SkPath fPath;

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

    void onOnceBeforeDraw() override {
        fPath = make_path();
        SkRect r = fPath.getBounds();
        r.toQuad(fPts);
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkMatrix mx;
        {
            SkRect r = fPath.getBounds();
            SkPoint src[4];
            r.toQuad(src);
            mx.setPolyToPoly(src, fPts, 4);
        }

        SkPaint paint;
        canvas->drawPath(fPath, paint);

        canvas->save();
        canvas->concat(mx);
        paint.setColor(0x40FF0000);
        canvas->drawPath(fPath, paint);
        canvas->restore();

        // draw the frame
        paint.setStrokeWidth(10);
        paint.setColor(SK_ColorGREEN);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPts, paint);

        // draw the half-planes
        SkHalfPlane planes[4];
        compute_half_planes(mx, 400, 400, planes);
        for (auto& p : planes) {
            draw_halfplane(canvas, p, SK_ColorRED);
        }
    }

    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        SkScalar r = 8;
        SkRect rect = SkRect::MakeXYWH(x - r, y - r, 2*r, 2*r);
        for (int i = 0; i < 4; ++i) {
            if (rect.contains(fPts[i].fX, fPts[i].fY)) {
                Click* c = new Click;
                c->fMeta.setS32("index", i);
                return c;
            }
        }
        return nullptr;
    }

    bool onClick(Click* click) override {
        int32_t index;
        SkAssertResult(click->fMeta.findS32("index", &index));
        SkASSERT(index >= 0 && index < 4);
        fPts[index] = click->fCurr;
        return true;
    }
};
DEF_SAMPLE( return new HalfPlaneView2(); )

static SkM44 inv(const SkM44& m) {
    SkM44 inverse;
    SkAssertResult(m.invert(&inverse));
    return inverse;
}

static SkHalfPlane half_plane_w0(const SkMatrix& m) {
    return { m[SkMatrix::kMPersp0], m[SkMatrix::kMPersp1], m[SkMatrix::kMPersp2] - 0.05f };
}

class SampleCameraView : public Sample {
    float   fNear = 0.05f;
    float   fFar = 4;
    float   fAngle = SK_ScalarPI / 4;

    SkV3    fEye { 0, 0, 1.0f/tan(fAngle/2) - 1 };
    SkV3    fCOA { 0, 0, 0 };
    SkV3    fUp  { 0, 1, 0 };

    SkM44  fRot;
    SkV3   fTrans;

    void rotate(float x, float y, float z) {
        SkM44 r;
        if (x) {
            r.setRotateUnit({1, 0, 0}, x);
        } else if (y) {
            r.setRotateUnit({0, 1, 0}, y);
        } else {
            r.setRotateUnit({0, 0, 1}, z);
        }
        fRot = r * fRot;
    }

public:
    SkM44 get44(const SkRect& r) const {
        SkScalar w = r.width();
        SkScalar h = r.height();

        SkM44 camera = Sk3LookAt(fEye, fCOA, fUp),
              perspective = Sk3Perspective(fNear, fFar, fAngle),
              translate = SkM44::Translate(fTrans.x, fTrans.y, fTrans.z),
              viewport = SkM44::Translate(r.centerX(), r.centerY(), 0) *
                         SkM44::Scale(w*0.5f, h*0.5f, 1);

        return viewport * perspective * camera * translate * fRot * inv(viewport);
    }

    bool onChar(SkUnichar uni) override {
        float delta = SK_ScalarPI / 30;
        switch (uni) {
            case '8': this->rotate( delta, 0, 0); return true;
            case '2': this->rotate(-delta, 0, 0); return true;
            case '4': this->rotate(0,  delta, 0); return true;
            case '6': this->rotate(0, -delta, 0); return true;
            case '-': this->rotate(0, 0,  delta); return true;
            case '+': this->rotate(0, 0, -delta); return true;

            case 'i': fTrans.z += 0.1f; SkDebugf("z %g\n", fTrans.z); return true;
            case 'k': fTrans.z -= 0.1f; SkDebugf("z %g\n", fTrans.z); return true;

            case 'n': fNear += 0.1f; SkDebugf("near %g\n", fNear); return true;
            case 'N': fNear -= 0.1f; SkDebugf("near %g\n", fNear); return true;
            case 'f': fFar  += 0.1f; SkDebugf("far  %g\n", fFar); return true;
            case 'F': fFar  -= 0.1f; SkDebugf("far  %g\n", fFar); return true;
            default: break;
        }
        return false;
    }
};

class HalfPlaneView3 : public SampleCameraView {
    SkPath fPath;
    sk_sp<SkShader> fShader;
    bool fShowUnclipped = false;

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

    void onOnceBeforeDraw() override {
        fPath = make_path();
        fShader = GetResourceAsImage("images/mandrill_128.png")
                        ->makeShader(SkMatrix::Scale(3, 3));
    }

    bool onChar(SkUnichar uni) override {
        switch (uni) {
            case 'u': fShowUnclipped = !fShowUnclipped; return true;
            default: break;
        }
        return this->SampleCameraView::onChar(uni);
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkM44 mx = this->get44({0, 0, 400, 400});

        SkPaint paint;
        paint.setColor({0.75, 0.75, 0.75, 1});
        canvas->drawPath(fPath, paint);

        paint.setShader(fShader);

        if (fShowUnclipped) {
            canvas->save();
            canvas->concat(mx);
            paint.setAlphaf(0.33f);
            canvas->drawPath(fPath, paint);
            paint.setAlphaf(1.f);
            canvas->restore();
        }


        SkColor planeColor = SK_ColorBLUE;
        SkPath clippedPath, *path = &fPath;
        if (SkPathPriv::PerspectiveClip(fPath, mx.asM33(), &clippedPath)) {
            path = &clippedPath;
            planeColor = SK_ColorRED;
        }
        canvas->save();
        canvas->concat(mx);
        canvas->drawPath(*path, paint);
        canvas->restore();

        SkHalfPlane hpw = half_plane_w0(mx.asM33());
        draw_halfplane(canvas, hpw, planeColor);
    }
};
DEF_SAMPLE( return new HalfPlaneView3(); )

class HalfPlaneCoons : public SampleCameraView {
    SkPoint fPatch[12];
    SkColor fColors[4] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorBLACK };
    SkPoint fTex[4]    = {{0, 0}, {256, 0}, {256, 256}, {0, 256}};
    sk_sp<SkShader> fShader;

    bool fShowHandles = false;
    bool fShowSkeleton = false;
    bool fShowTex = false;

    SkString name() override { return SkString("halfplane-coons"); }

    void onOnceBeforeDraw() override {
        fPatch[0] = {   0, 0 };
        fPatch[1] = { 100, 0 };
        fPatch[2] = { 200, 0 };
        fPatch[3] = { 300, 0 };
        fPatch[4] = { 300, 100 };
        fPatch[5] = { 300, 200 };
        fPatch[6] = { 300, 300 };
        fPatch[7] = { 200, 300 };
        fPatch[8] = { 100, 300 };
        fPatch[9] = {   0, 300 };
        fPatch[10] = {  0, 200 };
        fPatch[11] = {  0, 100 };

        fShader = GetResourceAsImage("images/mandrill_256.png")->makeShader();
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkPaint paint;

        canvas->save();
        canvas->concat(this->get44({0, 0, 300, 300}));

        const SkPoint* tex = nullptr;
        const SkColor* col = nullptr;
        if (!fShowSkeleton) {
            if (fShowTex) {
                paint.setShader(fShader);
                tex = fTex;
            } else {
                col = fColors;
            }
        }
        canvas->drawPatch(fPatch, col, tex, SkBlendMode::kSrc, paint);
        paint.setShader(nullptr);

        if (fShowHandles) {
            paint.setAntiAlias(true);
            paint.setStrokeCap(SkPaint::kRound_Cap);
            paint.setStrokeWidth(8);
            canvas->drawPoints(SkCanvas::kPoints_PointMode, 12, fPatch, paint);
            paint.setColor(SK_ColorWHITE);
            paint.setStrokeWidth(6);
            canvas->drawPoints(SkCanvas::kPoints_PointMode, 12, fPatch, paint);
        }

        canvas->restore();
    }

    Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        auto dist = [](SkPoint a, SkPoint b) { return (b - a).length(); };

        const float tol = 15;
        for (int i = 0; i < 12; ++i) {
            if (dist({x,y}, fPatch[i]) <= tol) {
                return new Click([this, i](Click* c) {
                    fPatch[i] = c->fCurr;
                    return true;
                });
            }
        }
        return nullptr;
    }

    bool onChar(SkUnichar uni) override {
        switch (uni) {
            case 'h': fShowHandles = !fShowHandles; return true;
            case 'k': fShowSkeleton = !fShowSkeleton; return true;
            case 't': fShowTex = !fShowTex; return true;
            default: break;
        }
        return this->SampleCameraView::onChar(uni);
    }

};
DEF_SAMPLE( return new HalfPlaneCoons(); )
