/*
 * 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, 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(); )
