/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Sample.h"
#include "SkBlendMode.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkFont.h"
#include "SkGeometry.h"
#include "SkImageInfo.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkPathMeasure.h"
#include "SkPoint.h"
#include "SkPointPriv.h"
#include "SkRRect.h"
#include "SkRect.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkStroke.h"
#include "SkSurface.h"
#include "SkTArray.h"
#include "SkTemplates.h"
#include "SkTextUtils.h"
#include "SkTypes.h"
#include "ToolUtils.h"

#include <cfloat>

class SkEvent;

static bool hittest(const SkPoint& target, SkScalar x, SkScalar y) {
    const SkScalar TOL = 7;
    return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL;
}

static int getOnCurvePoints(const SkPath& path, SkPoint storage[]) {
    SkPath::RawIter iter(path);
    SkPoint pts[4];
    SkPath::Verb verb;

    int count = 0;
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kMove_Verb:
            case SkPath::kLine_Verb:
            case SkPath::kQuad_Verb:
            case SkPath::kConic_Verb:
            case SkPath::kCubic_Verb:
                storage[count++] = pts[0];
                break;
            default:
                break;
        }
    }
    return count;
}

static void getContourCounts(const SkPath& path, SkTArray<int>* contourCounts) {
    SkPath::RawIter iter(path);
    SkPoint pts[4];
    SkPath::Verb verb;

    int count = 0;
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kMove_Verb:
            case SkPath::kLine_Verb:
                count += 1;
                break;
            case SkPath::kQuad_Verb:
            case SkPath::kConic_Verb:
                count += 2;
                break;
            case SkPath::kCubic_Verb:
                count += 3;
                break;
            case SkPath::kClose_Verb:
                contourCounts->push_back(count);
                count = 0;
                break;
            default:
                break;
        }
    }
    if (count > 0) {
        contourCounts->push_back(count);
    }
}

static void erase(const sk_sp<SkSurface>& surface) {
    SkCanvas* canvas = surface->getCanvas();
    if (canvas) {
        canvas->clear(SK_ColorTRANSPARENT);
    }
}

struct StrokeTypeButton {
    SkRect fBounds;
    char fLabel;
    bool fEnabled;
};

struct CircleTypeButton : public StrokeTypeButton {
    bool fFill;
};

class QuadStrokerView : public Sample {
    enum {
        SKELETON_COLOR = 0xFF0000FF,
        WIREFRAME_COLOR = 0x80FF0000
    };

    enum {
        kCount = 18
    };
    SkPoint fPts[kCount];
    SkRect fWeightControl;
    SkRect fRadiusControl;
    SkRect fErrorControl;
    SkRect fWidthControl;
    SkRect fBounds;
    SkMatrix fMatrix, fInverse;
    sk_sp<SkShader> fShader;
    sk_sp<SkSurface> fMinSurface;
    sk_sp<SkSurface> fMaxSurface;
    StrokeTypeButton fCubicButton;
    StrokeTypeButton fConicButton;
    StrokeTypeButton fQuadButton;
    StrokeTypeButton fArcButton;
    StrokeTypeButton fRRectButton;
    CircleTypeButton fCircleButton;
    StrokeTypeButton fTextButton;
    SkString fText;
    SkScalar fTextSize;
    SkScalar fWeight;
    SkScalar fRadius;
    SkScalar fWidth, fDWidth;
    SkScalar fWidthScale;
    int fW, fH, fZoom;
    bool fAnimate;
    bool fDrawRibs;
    bool fDrawTangents;
    bool fDrawTDivs;
#ifdef SK_DEBUG
    #define kStrokerErrorMin 0.001f
    #define kStrokerErrorMax 5
#endif
    #define kWidthMin 1
    #define kWidthMax 100
public:
    QuadStrokerView() {
        this->setBGColor(SK_ColorLTGRAY);

        fPts[0].set(50, 200);  // cubic
        fPts[1].set(50, 100);
        fPts[2].set(150, 50);
        fPts[3].set(300, 50);

        fPts[4].set(350, 200);  // conic
        fPts[5].set(350, 100);
        fPts[6].set(450, 50);

        fPts[7].set(150, 300);  // quad
        fPts[8].set(150, 200);
        fPts[9].set(250, 150);

        fPts[10].set(250, 200);  // arc
        fPts[11].set(250, 300);
        fPts[12].set(150, 350);

        fPts[13].set(200, 200); // rrect
        fPts[14].set(400, 400);

        fPts[15].set(250, 250);  // oval
        fPts[16].set(450, 450);

        fText = "a";
        fTextSize = 12;
        fWidth = 50;
        fDWidth = 0.25f;
        fWeight = 1;
        fRadius = 150;

        fCubicButton.fLabel = 'C';
        fCubicButton.fEnabled = false;
        fConicButton.fLabel = 'K';
        fConicButton.fEnabled = false;
        fQuadButton.fLabel = 'Q';
        fQuadButton.fEnabled = false;
        fArcButton.fLabel = 'A';
        fArcButton.fEnabled = true;
        fRRectButton.fLabel = 'R';
        fRRectButton.fEnabled = false;
        fCircleButton.fLabel = 'O';
        fCircleButton.fEnabled = true;
        fCircleButton.fFill = true;
        fTextButton.fLabel = 'T';
        fTextButton.fEnabled = false;
        fAnimate = false;
        setAsNeeded();
    }

protected:
    bool onQuery(Sample::Event* evt) override {
        if (Sample::TitleQ(*evt)) {
            Sample::TitleR(evt, "QuadStroker");
            return true;
        }
        SkUnichar uni;
        if (fTextButton.fEnabled && Sample::CharQ(*evt, &uni)) {
            switch (uni) {
                case ' ':
                    fText = "";
                    break;
                case '-':
                    fTextSize = SkTMax(1.0f, fTextSize - 1);
                    break;
                case '+':
                case '=':
                    fTextSize += 1;
                    break;
                default:
                    fText.appendUnichar(uni);
            }
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    void onSizeChange() override {
        fRadiusControl.setXYWH(this->width() - 200, 30, 30, 400);
        fWeightControl.setXYWH(this->width() - 150, 30, 30, 400);
        fErrorControl.setXYWH(this->width() - 100, 30, 30, 400);
        fWidthControl.setXYWH(this->width() -  50, 30, 30, 400);
        int buttonOffset = 450;
        fCubicButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        buttonOffset += 50;
        fConicButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        buttonOffset += 50;
        fQuadButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        buttonOffset += 50;
        fArcButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        buttonOffset += 50;
        fRRectButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        buttonOffset += 50;
        fCircleButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        buttonOffset += 50;
        fTextButton.fBounds.setXYWH(this->width() - 50, SkIntToScalar(buttonOffset), 30, 30);
        this->INHERITED::onSizeChange();
    }

     void copyMinToMax() {
        erase(fMaxSurface);
        SkCanvas* canvas = fMaxSurface->getCanvas();
        canvas->save();
        canvas->concat(fMatrix);
        fMinSurface->draw(canvas, 0, 0, nullptr);
        canvas->restore();

        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kClear);
        for (int iy = 1; iy < fH; ++iy) {
            SkScalar y = SkIntToScalar(iy * fZoom);
            canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
        }
        for (int ix = 1; ix < fW; ++ix) {
            SkScalar x = SkIntToScalar(ix * fZoom);
            canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
        }
    }

   void setWHZ(int width, int height, int zoom) {
        fZoom = zoom;
        fBounds.set(0, 0, SkIntToScalar(width * zoom), SkIntToScalar(height * zoom));
        fMatrix.setScale(SkIntToScalar(zoom), SkIntToScalar(zoom));
        fInverse.setScale(SK_Scalar1 / zoom, SK_Scalar1 / zoom);
        fShader = ToolUtils::create_checkerboard_shader(0xFFCCCCCC, 0xFFFFFFFF, zoom);

        SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
        fMinSurface = SkSurface::MakeRaster(info);
        info = info.makeWH(width * zoom, height * zoom);
        fMaxSurface = SkSurface::MakeRaster(info);
    }

    void draw_points(SkCanvas* canvas, const SkPath& path, SkColor color,
                     bool show_lines) {
        SkPaint paint;
        paint.setColor(color);
        paint.setAlpha(0x80);
        paint.setAntiAlias(true);
        int n = path.countPoints();
        SkAutoSTArray<32, SkPoint> pts(n);
        if (show_lines && fDrawTangents) {
            SkTArray<int> contourCounts;
            getContourCounts(path, &contourCounts);
            SkPoint* ptPtr = pts.get();
            for (int i = 0; i < contourCounts.count(); ++i) {
                int count = contourCounts[i];
                path.getPoints(ptPtr, count);
                canvas->drawPoints(SkCanvas::kPolygon_PointMode, count, ptPtr, paint);
                ptPtr += count;
            }
        } else {
            n = getOnCurvePoints(path, pts.get());
        }
        paint.setStrokeWidth(5);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts.get(), paint);
    }

    void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width,
                   SkColor color) {
        const SkScalar radius = width / 2;

        SkPathMeasure meas(path, false);
        SkScalar total = meas.getLength();

        SkScalar delta = 8;
        SkPaint paint, labelP;
        paint.setColor(color);
        labelP.setColor(color & 0xff5f9f5f);
        SkFont font;
        SkPoint pos, tan;
        int index = 0;
        for (SkScalar dist = 0; dist <= total; dist += delta) {
            if (meas.getPosTan(dist, &pos, &tan)) {
                tan.scale(radius);
                SkPointPriv::RotateCCW(&tan);
                canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(),
                                 pos.x() - tan.x(), pos.y() - tan.y(), paint);
                if (0 == index % 10) {
                    SkString label;
                    label.appendS32(index);
                    SkRect dot = SkRect::MakeXYWH(pos.x() - 2, pos.y() - 2, 4, 4);
                    canvas->drawRect(dot, labelP);
                    canvas->drawString(label,
                        pos.x() - tan.x() * 1.25f, pos.y() - tan.y() * 1.25f, font, labelP);
                }
            }
            ++index;
        }
    }

    void draw_t_divs(SkCanvas* canvas, const SkPath& path, SkScalar width, SkColor color) {
        const SkScalar radius = width / 2;
        SkPaint paint;
        paint.setColor(color);
        SkPathMeasure meas(path, false);
        SkScalar total = meas.getLength();
        SkScalar delta = 8;
        int ribs = 0;
        for (SkScalar dist = 0; dist <= total; dist += delta) {
            ++ribs;
        }
        SkPath::RawIter iter(path);
        SkPoint pts[4];
        if (SkPath::kMove_Verb != iter.next(pts)) {
            SkASSERT(0);
            return;
        }
        SkPath::Verb verb = iter.next(pts);
        SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb);
        SkPoint pos, tan;
        for (int index = 0; index < ribs; ++index) {
            SkScalar t = (SkScalar) index / ribs;
            switch (verb) {
                case SkPath::kLine_Verb:
                    tan = pts[1] - pts[0];
                    pos = pts[0];
                    pos.fX += tan.fX * t;
                    pos.fY += tan.fY * t;
                    break;
                case SkPath::kQuad_Verb:
                    pos = SkEvalQuadAt(pts, t);
                    tan = SkEvalQuadTangentAt(pts, t);
                    break;
                case SkPath::kConic_Verb: {
                    SkConic conic(pts, iter.conicWeight());
                    pos = conic.evalAt(t);
                    tan = conic.evalTangentAt(t);
                    } break;
                case SkPath::kCubic_Verb:
                    SkEvalCubicAt(pts, t, &pos, &tan, nullptr);
                    break;
                default:
                    SkASSERT(0);
                    return;
            }
            tan.setLength(radius);
            SkPointPriv::RotateCCW(&tan);
            canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(),
                                pos.x() - tan.x(), pos.y() - tan.y(), paint);
            if (0 == index % 10) {
                SkString label;
                label.appendS32(index);
                canvas->drawString(label,
                    pos.x() + tan.x() * 1.25f, pos.y() + tan.y() * 1.25f, SkFont(), paint);
            }
        }
    }

    void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width, SkScalar scale,
            bool drawText) {
        if (path.isEmpty()) {
            return;
        }
        SkRect bounds = path.getBounds();
        this->setWHZ(SkScalarCeilToInt(bounds.right()), drawText
                ? SkScalarRoundToInt(scale * 3 / 2) : SkScalarRoundToInt(scale),
                SkScalarRoundToInt(950.0f / scale));
        erase(fMinSurface);
        SkPaint paint;
        paint.setColor(0x1f1f0f0f);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(width * scale * scale);
        paint.setColor(0x3f0f1f3f);
        if (drawText) {
            fMinSurface->getCanvas()->drawPath(path, paint);
            this->copyMinToMax();
            fMaxSurface->draw(canvas, 0, 0, nullptr);
        }
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(1);

        paint.setColor(SKELETON_COLOR);
        SkPath scaled;
        SkMatrix matrix;
        matrix.reset();
        matrix.setScale(950 / scale, 950 / scale);
        if (drawText) {
            path.transform(matrix, &scaled);
        } else {
            scaled = path;
        }
        canvas->drawPath(scaled, paint);
        draw_points(canvas, scaled, SKELETON_COLOR, true);

        if (fDrawRibs) {
            draw_ribs(canvas, scaled, width, 0xFF00FF00);
        }

        if (fDrawTDivs) {
            draw_t_divs(canvas, scaled, width, 0xFF3F3F00);
        }

        SkPath fill;

        SkPaint p;
        p.setStyle(SkPaint::kStroke_Style);
        if (drawText) {
            p.setStrokeWidth(width * scale * scale);
        } else {
            p.setStrokeWidth(width);
        }
        p.getFillPath(path, &fill);
        SkPath scaledFill;
        if (drawText) {
            fill.transform(matrix, &scaledFill);
        } else {
            scaledFill = fill;
        }
        paint.setColor(WIREFRAME_COLOR);
        canvas->drawPath(scaledFill, paint);
        draw_points(canvas, scaledFill, WIREFRAME_COLOR, false);
    }

    void draw_fill(SkCanvas* canvas, const SkRect& rect, SkScalar width) {
        if (rect.isEmpty()) {
            return;
        }
        SkPaint paint;
        paint.setColor(0x1f1f0f0f);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(width);
        SkPath path;
        SkScalar maxSide = SkTMax(rect.width(), rect.height()) / 2;
        SkPoint center = { rect.fLeft + maxSide, rect.fTop + maxSide };
        path.addCircle(center.fX, center.fY, maxSide);
        canvas->drawPath(path, paint);
        paint.setStyle(SkPaint::kFill_Style);
        path.reset();
        path.addCircle(center.fX, center.fY, maxSide - width / 2);
        paint.setColor(0x3f0f1f3f);
        canvas->drawPath(path, paint);
        path.reset();
        path.setFillType(SkPath::kEvenOdd_FillType);
        path.addCircle(center.fX, center.fY, maxSide + width / 2);
        SkRect outside = SkRect::MakeXYWH(center.fX - maxSide - width, center.fY - maxSide - width,
                (maxSide + width) * 2, (maxSide + width) * 2);
        path.addRect(outside);
        canvas->drawPath(path, paint);
    }

    void draw_button(SkCanvas* canvas, const StrokeTypeButton& button) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000);
        canvas->drawRect(button.fBounds, paint);
        paint.setColor(button.fEnabled ? 0xFF3F0000 : 0x6F3F0000);
        paint.setStyle(SkPaint::kFill_Style);
        SkFont font;
        font.setSize(25.0f);
        SkTextUtils::Draw(canvas, &button.fLabel, 1, kUTF8_SkTextEncoding,
                button.fBounds.centerX(), button.fBounds.fBottom - 5,
                font, paint, SkTextUtils::kCenter_Align);
    }

    void draw_control(SkCanvas* canvas, const SkRect& bounds, SkScalar value,
            SkScalar min, SkScalar max, const char* name) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        canvas->drawRect(bounds, paint);
        SkScalar scale = max - min;
        SkScalar yPos = bounds.fTop + (value - min) * bounds.height() / scale;
        paint.setColor(0xFFFF0000);
        canvas->drawLine(bounds.fLeft - 5, yPos, bounds.fRight + 5, yPos, paint);
        SkString label;
        label.printf("%0.3g", value);
        paint.setColor(0xFF000000);
        paint.setStyle(SkPaint::kFill_Style);
        SkFont font(nullptr, 11.0f);
        canvas->drawString(label, bounds.fLeft + 5, yPos - 5, font, paint);
        font.setSize(13.0f);
        canvas->drawString(name, bounds.fLeft, bounds.bottom() + 11, font, paint);
    }

    void setForGeometry() {
        fDrawRibs = true;
        fDrawTangents = true;
        fDrawTDivs = false;
        fWidthScale = 1;
    }

    void setForText() {
        fDrawRibs = fDrawTangents = fDrawTDivs = false;
        fWidthScale = 0.002f;
    }

    void setForSingles() {
        setForGeometry();
        fDrawTDivs = true;
    }

    void setAsNeeded() {
        if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabled) {
            setForSingles();
        } else if (fRRectButton.fEnabled || fCircleButton.fEnabled || fArcButton.fEnabled) {
            setForGeometry();
        } else {
            setForText();
        }
    }

    bool arcCenter(SkPoint* center) {
        SkPath path;
        path.moveTo(fPts[10]);
        path.arcTo(fPts[11], fPts[12], fRadius);
        SkPath::Iter iter(path, false);
        SkPoint pts[4];
        iter.next(pts);
        if (SkPath::kLine_Verb == iter.next(pts)) {
            iter.next(pts);
        }
        SkVector before = pts[0] - pts[1];
        SkVector after = pts[1] - pts[2];
        before.setLength(fRadius);
        after.setLength(fRadius);
        SkVector beforeCCW, afterCCW;
        SkPointPriv::RotateCCW(before, &beforeCCW);
        SkPointPriv::RotateCCW(after, &afterCCW);
        beforeCCW += pts[0];
        afterCCW += pts[2];
        *center = beforeCCW;
        if (SkScalarNearlyEqual(beforeCCW.fX, afterCCW.fX)
                && SkScalarNearlyEqual(beforeCCW.fY, afterCCW.fY)) {
            return true;
        }
        SkVector beforeCW, afterCW;
        SkPointPriv::RotateCW(before, &beforeCW);
        SkPointPriv::RotateCW(after, &afterCW);
        beforeCW += pts[0];
        afterCW += pts[2];
        *center = beforeCW;
        return SkScalarNearlyEqual(beforeCW.fX, afterCW.fX)
                && SkScalarNearlyEqual(beforeCCW.fY, afterCW.fY);
    }

    void onDrawContent(SkCanvas* canvas) override {
        SkPath path;
        SkScalar width = fWidth;

        if (fCubicButton.fEnabled) {
            path.moveTo(fPts[0]);
            path.cubicTo(fPts[1], fPts[2], fPts[3]);
            setForSingles();
            draw_stroke(canvas, path, width, 950, false);
        }

        if (fConicButton.fEnabled) {
            path.reset();
            path.moveTo(fPts[4]);
            path.conicTo(fPts[5], fPts[6], fWeight);
            setForSingles();
            draw_stroke(canvas, path, width, 950, false);
        }

        if (fQuadButton.fEnabled) {
            path.reset();
            path.moveTo(fPts[7]);
            path.quadTo(fPts[8], fPts[9]);
            setForSingles();
            draw_stroke(canvas, path, width, 950, false);
        }

        if (fArcButton.fEnabled) {
            path.reset();
            path.moveTo(fPts[10]);
            path.arcTo(fPts[11], fPts[12], fRadius);
            setForGeometry();
            draw_stroke(canvas, path, width, 950, false);
            SkPath pathPts;
            pathPts.moveTo(fPts[10]);
            pathPts.lineTo(fPts[11]);
            pathPts.lineTo(fPts[12]);
            draw_points(canvas, pathPts, SK_ColorDKGRAY, true);
        }

        if (fRRectButton.fEnabled) {
            SkScalar rad = 32;
            SkRect r;
            r.set(&fPts[13], 2);
            path.reset();
            SkRRect rr;
            rr.setRectXY(r, rad, rad);
            path.addRRect(rr);
            setForGeometry();
            draw_stroke(canvas, path, width, 950, false);

            path.reset();
            SkRRect rr2;
            rr.inset(width/2, width/2, &rr2);
            path.addRRect(rr2, SkPath::kCCW_Direction);
            rr.inset(-width/2, -width/2, &rr2);
            path.addRRect(rr2, SkPath::kCW_Direction);
            SkPaint paint;
            paint.setAntiAlias(true);
            paint.setColor(0x40FF8844);
            canvas->drawPath(path, paint);
        }

        if (fCircleButton.fEnabled) {
            path.reset();
            SkRect r;
            r.set(&fPts[15], 2);
            path.addOval(r);
            setForGeometry();
            if (fCircleButton.fFill) {
                if (fArcButton.fEnabled) {
                    SkPoint center;
                    if (arcCenter(&center)) {
                        r.set(center.fX - fRadius, center.fY - fRadius, center.fX + fRadius,
                                center.fY + fRadius);
                    }
                }
                draw_fill(canvas, r, width);
            } else {
                draw_stroke(canvas, path, width, 950, false);
            }
        }

        if (fTextButton.fEnabled) {
            path.reset();
            SkFont font;
            font.setSize(fTextSize);
            SkTextUtils::GetPath(fText.c_str(), fText.size(), kUTF8_SkTextEncoding,
                                 0, fTextSize, font, &path);
            setForText();
            draw_stroke(canvas, path, width * fWidthScale / fTextSize, fTextSize, true);
        }

        if (fAnimate) {
            fWidth += fDWidth;
            if (fDWidth > 0 && fWidth > kWidthMax) {
                fDWidth = -fDWidth;
            } else if (fDWidth < 0 && fWidth < kWidthMin) {
                fDWidth = -fDWidth;
            }
        }
        setAsNeeded();
        if (fConicButton.fEnabled) {
            draw_control(canvas, fWeightControl, fWeight, 0, 5, "weight");
        }
        if (fArcButton.fEnabled) {
            draw_control(canvas, fRadiusControl, fRadius, 0, 500, "radius");
        }
#ifdef SK_DEBUG
        draw_control(canvas, fErrorControl, gDebugStrokerError, kStrokerErrorMin, kStrokerErrorMax,
                "error");
#endif
        draw_control(canvas, fWidthControl, fWidth * fWidthScale, kWidthMin * fWidthScale,
                kWidthMax * fWidthScale, "width");
        draw_button(canvas, fQuadButton);
        draw_button(canvas, fCubicButton);
        draw_button(canvas, fConicButton);
        draw_button(canvas, fArcButton);
        draw_button(canvas, fRRectButton);
        draw_button(canvas, fCircleButton);
        draw_button(canvas, fTextButton);
    }

    class MyClick : public Click {
    public:
        int fIndex;
        MyClick(Sample* target, int index) : Click(target), fIndex(index) {}
    };

    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                              unsigned modi) override {
        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) {
            if (hittest(fPts[i], x, y)) {
                return new MyClick(this, (int)i);
            }
        }
        const SkRect& rectPt = SkRect::MakeXYWH(x, y, 1, 1);
        if (fWeightControl.contains(rectPt)) {
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 1);
        }
        if (fRadiusControl.contains(rectPt)) {
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 2);
        }
#ifdef SK_DEBUG
        if (fErrorControl.contains(rectPt)) {
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 3);
        }
#endif
        if (fWidthControl.contains(rectPt)) {
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 4);
        }
        if (fCubicButton.fBounds.contains(rectPt)) {
            fCubicButton.fEnabled ^= true;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 5);
        }
        if (fConicButton.fBounds.contains(rectPt)) {
            fConicButton.fEnabled ^= true;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 6);
        }
        if (fQuadButton.fBounds.contains(rectPt)) {
            fQuadButton.fEnabled ^= true;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 7);
        }
        if (fArcButton.fBounds.contains(rectPt)) {
            fArcButton.fEnabled ^= true;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 8);
        }
        if (fRRectButton.fBounds.contains(rectPt)) {
            fRRectButton.fEnabled ^= true;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 9);
        }
        if (fCircleButton.fBounds.contains(rectPt)) {
            bool wasEnabled = fCircleButton.fEnabled;
            fCircleButton.fEnabled = !fCircleButton.fFill;
            fCircleButton.fFill = wasEnabled && !fCircleButton.fFill;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 10);
        }
        if (fTextButton.fBounds.contains(rectPt)) {
            fTextButton.fEnabled ^= true;
            return new MyClick(this, (int) SK_ARRAY_COUNT(fPts) + 11);
        }
        return this->INHERITED::onFindClickHandler(x, y, modi);
    }

    static SkScalar MapScreenYtoValue(int y, const SkRect& control, SkScalar min,
            SkScalar max) {
        return (SkIntToScalar(y) - control.fTop) / control.height() * (max - min) + min;
    }

    bool onClick(Click* click) override {
        int index = ((MyClick*)click)->fIndex;
        if (index < (int) SK_ARRAY_COUNT(fPts)) {
            fPts[index].offset(SkIntToScalar(click->fICurr.fX - click->fIPrev.fX),
                               SkIntToScalar(click->fICurr.fY - click->fIPrev.fY));
        } else if (index == (int) SK_ARRAY_COUNT(fPts) + 1) {
            fWeight = MapScreenYtoValue(click->fICurr.fY, fWeightControl, 0, 5);
        } else if (index == (int) SK_ARRAY_COUNT(fPts) + 2) {
            fRadius = MapScreenYtoValue(click->fICurr.fY, fRadiusControl, 0, 500);
        }
#ifdef SK_DEBUG
        else if (index == (int) SK_ARRAY_COUNT(fPts) + 3) {
            gDebugStrokerError = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY,
                    fErrorControl, kStrokerErrorMin, kStrokerErrorMax));
            gDebugStrokerErrorSet = true;
        }
#endif
        else if (index == (int) SK_ARRAY_COUNT(fPts) + 4) {
            fWidth = SkTMax(FLT_EPSILON, MapScreenYtoValue(click->fICurr.fY, fWidthControl,
                    kWidthMin, kWidthMax));
            fAnimate = fWidth <= kWidthMin;
        }
        return true;
    }

private:
    typedef Sample INHERITED;
};

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

DEF_SAMPLE( return new QuadStrokerView(); )
