
/*
 * 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 "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkXfermode.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkTime.h"
#include "SkTypeface.h"

class PathClipView : public SampleView {
public:
    SkRect fOval;
    SkPoint fCenter;

    PathClipView() : fOval(SkRect::MakeWH(200, 50)), fCenter(SkPoint::Make(250, 250)) {}

protected:
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "PathClip");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void onDrawContent(SkCanvas* canvas) override {
        const SkRect oval = fOval.makeOffset(fCenter.fX - fOval.centerX(),
                                             fCenter.fY - fOval.centerY());

        SkPaint p;
        p.setAntiAlias(true);

        p.setStyle(SkPaint::kStroke_Style);
        canvas->drawOval(oval, p);

        const SkRect r = SkRect::MakeLTRB(200, 200, 300, 300);
        canvas->clipRect(r);

        p.setStyle(SkPaint::kFill_Style);
        p.setColor(SK_ColorRED);
        canvas->drawRect(r, p);

        p.setColor(0x800000FF);
        canvas->drawOval(oval, p);
    }

    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
        return new Click(this);
    }

    bool onClick(Click* click) override {
        fCenter.set(click->fCurr.fX, click->fCurr.fY);
        this->inval(nullptr);
        return false;
    }

private:
    typedef SampleView INHERITED;
};
DEF_SAMPLE( return new PathClipView; )

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

static int clip_line(const SkRect& bounds, SkPoint p0, SkPoint p1, SkPoint edges[]) {
    SkPoint* edgesStart = edges;

    if (p0.fY == p1.fY) {
        return 0;
    }
    
    if (p0.fY > p1.fY) {
        SkTSwap(p0, p1);
    }
    // now we're monotonic in Y: p0 <= p1
    if (p1.fY <= bounds.top() || p0.fY >= bounds.bottom()) {
        return 0;
    }
    
    double dxdy = (double)(p1.fX - p0.fX) / (p1.fY - p0.fY);
    if (p0.fY < bounds.top()) {
        p0.fX = SkDoubleToScalar(p0.fX + dxdy * (bounds.top() - p0.fY));
        p0.fY = bounds.top();
    }
    if (p1.fY > bounds.bottom()) {
        p1.fX = SkDoubleToScalar(p1.fX + dxdy * (bounds.bottom() - p1.fY));
        p1.fY = bounds.bottom();
    }
    
    // Now p0...p1 is strictly inside bounds vertically, so we just need to clip horizontally
    
    if (p0.fX > p1.fX) {
        SkTSwap(p0, p1);
    }
    // now we're left-to-right: p0 .. p1
    
    if (p1.fX <= bounds.left()) {   // entirely to the left
        p0.fX = p1.fX = bounds.left();
        *edges++ = p0;
        *edges++ = p1;
        return 2;
    }
    if (p0.fX >= bounds.right()) {  // entirely to the right
        p0.fX = p1.fX = bounds.right();
        *edges++ = p0;
        *edges++ = p1;
        return 2;
    }
    
    if (p0.fX < bounds.left()) {
        float y = SkDoubleToScalar(p0.fY + (bounds.left() - p0.fX) / dxdy);
        *edges++ = SkPoint::Make(bounds.left(), p0.fY);
        *edges++ = SkPoint::Make(bounds.left(), y);
        p0.set(bounds.left(), y);
    }
    if (p1.fX > bounds.right()) {
        float y = SkDoubleToScalar(p0.fY + (bounds.right() - p0.fX) / dxdy);
        *edges++ = p0;
        *edges++ = SkPoint::Make(bounds.right(), y);
        *edges++ = SkPoint::Make(bounds.right(), p1.fY);
    } else {
        *edges++ = p0;
        *edges++ = p1;
    }
    return SkToInt(edges - edgesStart);
}

static void draw_clipped_line(SkCanvas* canvas, const SkRect& bounds,
                              SkPoint p0, SkPoint p1, const SkPaint& paint) {
    SkPoint verts[6];
    int count = clip_line(bounds, p0, p1, verts);

    SkPath path;
    path.addPoly(verts, count, false);
    canvas->drawPath(path, paint);
}

// Demonstrate edge-clipping that is used in the scan converter
//
class EdgeClipView : public SampleView {
    enum {
        N = 3
    };
public:
    SkPoint fPoly[N];
    SkRect  fClip;
    SkColor fEdgeColor[N];
    
    EdgeClipView() : fClip(SkRect::MakeLTRB(150, 150, 550, 450)) {
        fPoly[0].set(300, 40);
        fPoly[1].set(550, 250);
        fPoly[2].set(40, 450);

        fEdgeColor[0] = 0xFFFF0000;
        fEdgeColor[1] = 0xFF00FF00;
        fEdgeColor[2] = 0xFF0000FF;
    }
    
protected:
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "EdgeClip");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    static SkScalar snap(SkScalar x) {
        return SkScalarRoundToScalar(x * 0.5f) * 2;
    }
    static SkPoint snap(const SkPoint& pt) {
        return SkPoint::Make(snap(pt.x()), snap(pt.y()));
    }
    static void snap(SkPoint dst[], const SkPoint src[], int count) {
        for (int i = 0; i < count; ++i) {
            dst[i] = snap(src[i]);
        }
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkPath path;
        path.addPoly(fPoly, N, true);

        // Draw the full triangle, stroked and filled
        SkPaint p;
        p.setAntiAlias(true);
        p.setColor(0xFFE0E0E0);
        canvas->drawPath(path, p);
        p.setStyle(SkPaint::kStroke_Style);
        p.setStrokeWidth(2);
        for (int i = 0; i < N; ++i) {
            const int j = (i + 1) % N;
            p.setColor(fEdgeColor[i]);
            p.setAlpha(0x88);
            canvas->drawLine(fPoly[i].x(), fPoly[i].y(), fPoly[j].x(), fPoly[j].y(), p);
        }
        p.setStyle(SkPaint::kFill_Style);

        // Draw the clip itself
        p.setColor(0xFF8888CC);
        canvas->drawRect(fClip, p);

        // Draw the filled triangle through the clip
        p.setColor(0xFF88CC88);
        canvas->save();
        canvas->clipRect(fClip);
        canvas->drawPath(path, p);
        canvas->restore();

        p.setStyle(SkPaint::kStroke_Style);
        p.setStrokeWidth(6);

        // Draw each of the "Edges" that survived the clipping
        // We use a layer, so we can PLUS the different edge-colors, showing where two edges
        // canceled each other out.
        canvas->saveLayer(nullptr, nullptr);
        p.setXfermodeMode(SkXfermode::kPlus_Mode);
        for (int i = 0; i < N; ++i) {
            const int j = (i + 1) % N;
            p.setColor(fEdgeColor[i]);
            draw_clipped_line(canvas, fClip, fPoly[i], fPoly[j], p);
        }
        canvas->restore();
    }

    class MyClick : public Click {
    public:
        MyClick(SkView* view) : Click(view) {}
        virtual void handleMove() = 0;
    };
    
    class VertClick : public MyClick {
        SkPoint* fPt;
    public:
        VertClick(SkView* view, SkPoint* pt) : MyClick(view), fPt(pt) {}
        void handleMove() override { *fPt = snap(fCurr); }
    };
    
    class DragRectClick : public MyClick {
        SkRect* fRect;
    public:
        DragRectClick(SkView* view, SkRect* rect) : MyClick(view), fRect(rect) {}
        void handleMove() override { fRect->offset(fCurr.x() - fPrev.x(), fCurr.y() - fPrev.y()); }
    };
    
    class DragPolyClick : public MyClick {
        SkPoint fSrc[100];
        SkPoint* fPoly;
        int fCount;
    public:
        DragPolyClick(SkView* view, SkPoint poly[], int count)
            : MyClick(view), fPoly(poly), fCount(count)
        {
            SkASSERT((size_t)count <= SK_ARRAY_COUNT(fSrc));
            memcpy(fSrc, poly, count * sizeof(SkPoint));
        }
        void handleMove() override {
            const SkScalar dx = fCurr.x() - fOrig.x();
            const SkScalar dy = fCurr.y() - fOrig.y();
            for (int i = 0; i < fCount; ++i) {
                fPoly[i].set(snap(fSrc[i].x() + dx), snap(fSrc[i].y() + dy));
            }
        }
    };

    class DoNothingClick : public MyClick {
    public:
        DoNothingClick(SkView* view) : MyClick(view) {}
        void handleMove() override {}
    };

    static bool hit_test(const SkPoint& pt, SkScalar x, SkScalar y) {
        const SkScalar rad = 8;
        const SkScalar dx = pt.x() - x;
        const SkScalar dy = pt.y() - y;
        return dx*dx + dy*dy <= rad*rad;
    }

    SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override {
        for (int i = 0; i < N; ++i) {
            if (hit_test(fPoly[i], x, y)) {
                return new VertClick(this, &fPoly[i]);
            }
        }
        
        SkPath path;
        path.addPoly(fPoly, N, true);
        if (path.contains(x, y)) {
            return new DragPolyClick(this, fPoly, N);
        }

        if (fClip.intersects(SkRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1))) {
            return new DragRectClick(this, &fClip);
        }
        return new DoNothingClick(this);
    }
    
    bool onClick(Click* click) override {
        ((MyClick*)click)->handleMove();
        this->inval(nullptr);
        return false;
    }
    
private:
    typedef SampleView INHERITED;
};
DEF_SAMPLE( return new EdgeClipView; )

